2015年9月1日火曜日

FlaskとPython3からGmailでメール送信(OAuth 2.0対応)

Webアプリ経由でGmailからメールを送ることにしたが、せっかくなのOAuth 2.0に対応させることにした。

ベースのソースコード下記にあるので、2つを組み合わせてそれを動かす。

1.の方はFlaskでOAuth2.0認証して、Google Driveのファイルを取得しているので、認証後に2.のGmailから送信するように組み合わせる。
2つ合体はサクッと。。。
まぁ。動きません。

ここからは試行錯誤なので、結論を書くと、
  • Payloadの"raw"はurlsafe_b64decodeを使いましょう。
  • Python3で使う場合は、ちゃんとStrからByteに変換してからBase64変換をかけましょう。
いじょ。

適当な入力フォームから送ると、

こんな結果が帰ってきます。



ソースはこんな感じ。
※GoogleDevelopersConsoleからAPI認証用Jsonファイルをダウンロードして、作業ディレクトリに"client_secrets.json"として保存してください。
※送信元のメールアドレスは、API認証用Jsonファイルと同じカウントでないとNG。
※ソースはBitbucketにおいてありますので、自己責任で使ってください。


ここからが試行錯誤した結果。
Pythonのバージョンなのか、日本語なのか、GmailのBase64フォーマットの変換でエラー。。。

  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/base64.py", line 62, in b64encode
    encoded = binascii.b2a_base64(s)[:-1]
TypeError: 'str' does not support the buffer interface
まぁ。GoogleのサンプルがPython2系向けで、3系からByteとStrの扱いが変わったので、再度サクッと。。。

直したとこだけ。
return {'raw': base64.b64encode(message.as_string())}

return {'raw': base64.b64encode(bytes(message.as_string(), 'UTF-8')).decode()}
これで、ASCIIは送れるようになったので。

キャプチャか何か。同じ同じ

日本語を送ろうとすると。。。。こんな感じで、エラーが。
Invalid value for ByteString: Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1dGY・・(略)・・・

GoogleAPIを使うためにググる。
stackoverflowの
によると、"urlsafe_b64encode"を使えよとのこと。
PHPの話みたいなので、Pythonだとこれかな。

base64.urlsafe_b64encode (s)バイト文字列 s を URL-safe アルファベットを利用してエンコードします。標準 base64 アルファベットに比べて、+ の替わりに - を、/ の替わりに _ を利用します。結果は = を含みます。
直すと、無事に日本語が送れました。
なかなか、”URL Safe” Base64に気づかず、結構はまったのでメモ。

2015年5月19日火曜日

さくらVPSのCentos7が起動しなくなった。。。

さくらVPSのCentos7が、YUMでカーネルアップデート後にカーネルパニックでブートローダーから読めなくなった。
実は、OSがカーネルパニックで起動しなくなったのは2回目なので、、、、今回は作業メモを残すことにした。3回目に備えて。。。

完全に作業メモなので、気が向いたら綺麗に書くかも。。。

①CentOSのISOからレスキューモードで起動させる。
 さくらVPSのコントロールパネル
  →OSインストール
  →カスタムOSインストール
  →CentOS7を選択
   →内容を確認するを押す
  →インストールを実行するを押す
    ※バックアップを取ってから作業してね 的なメッセージがでるが無視。。。
  →準備ができるとVNCコンソールを開くボタンが表示される。

 ここからVNCコンソールの作業
 トラブルシューティングを選択
 →レスキューを選択
 →ISOからOSが起動する。
  →既存のHDDをマウントするか聞かれるので、Continueを選択
  →何度かOKを押す
 →シェルが表示される。
 →chroot /mnt/systemimage
 
②1つ前のカーネルで起動させる。
下記のサイトを参考に実施。
http://ayufishing.blog.fc2.com/blog-entry-12.html
※このサーバのCentOS7は、6からのアップデートなのでGRUBで起動する。

vi /etc/grub.conf

default=0

default=1

③再起動させる
exit
→reboot

④再起動後、特に問題が無ければYUMでアップデートされる前のカーネルで起動する。
 が、今回はサービス起動中に固まってしまって起動できず。。。

⑤シングルユーザで起動
下記のサイトを参考に実施
http://infrakeise.blog92.fc2.com/blog-entry-151.html

GRUBの画面で、何かキーを押す
→起動選択画面で、1つ前のカーネルにカーソルを動かし、「e」を押す
 →kernel始まる行にカーソルを動かし「e」を押す
 →最後尾にスペースを入れて「single」と入力し、エンターを押す。
 →1つ前の画面に戻るので、「b」を押す。
→HDDからCentOSがシングルユーザモードで起動する。
 →途中でRootパスワードを入れるように言われるので、入力するとRootでログインができる。

⑥シングルユーザモードでSSHを起動して、外部にデータを救出
シングルユーザモード(ランレベル1)では、NetworkとSSHが起動していないので手動起動。
下記のサイトで、シングルユーザでもSSHが起動できると書いてあったので、試したら本当に起動した。
http://qiita.com/hilotech/items/4d830347085ca27e3ba1

下記のコマンドで、NetworkサービスとSSHDを起動させる。
 systemctl start network
 systemctl start sshd
→もし、SSHでRootログインを禁止している場合は、
vi /etc/ssh/sshd_conf
root〜 yesにする
 →あとは、通常のSSHの接続と同じで使えるので、SFTPでファイルを外部に送ってやればOK.








2015年3月22日日曜日

JenkinsでtoxとPytestを使ってCI

JenkinsでToxとPytestを使って、テストを実行するまでの設定。

まず、Jenknsがインストールされているサーバに下記をインストールします。
本当は、Virtualenvを使うのが良いのですが、Jenkinsの設定が面倒なので、そのまま入れます。。。。(あんまり良くないよね。。。。。)

1. Tox.iniを準備
試験したいプロジェクトにTox.iniファイルを作成します。
今回は、Python2.7と3.4で、PytestとPEP8確認とカバレッジを実行します。(ちなみに、試験で使うPythonはインストールされてないとダメです。なので、Python2,7と3.4はJenkinsサーバにインストール済みです。)

プロジェクトのdirectory構成はこんな感じ。
├── LICENSE
├── application
│   ├── Calculation.py
│   ├── __init__.py
├── setup.py
├── test
│   ├── test_Calculation.py
└── tox.ini


Tox.ini
[tox]
envlist = py27, py34

[pytest]
pep8maxlinelength = 120

[testenv:py27]
basepython = /usr/local/python27/bin/python2.7

[testenv:py34]
basepython = /usr/local/python34/bin/python3.4

[testenv]
deps =
  pytest
  pytest-cov
  pytest-pep8
  blinker
  Flask
  itsdangerous
  Jinja2
  MarkupSafe
  raven
  requests
  six
  Werkzeug

commands =
  py.test \
    --pep8 \
    --cov application \
    --cov-report xml \
    --junitxml=junit-{envname}.xml \
    test

2. setup.pyを準備
Toxにはsetup.pyが必ず必要らしいので、簡易的な物を作成します。



# -*- coding:utf-8 -*- 
from distutils.core import setup
setup(name='application name', 
  version='0.0.1',
  description='application description',
  author='auth user name',
  author_email='email@localhost.localhost', )
3. JenkinsサーバにToxをインストール
$ sudo pip install tox
ずらずらと・・・
$ sudo -u jenkins python -c "import tox; print tox.__version__"
今回は「1.9.0」がインストールされた様です。

4. jenkinsに「shiningpanda」「Cobertura Plugin」プラグインをインストール
・「shiningpanda」は、JenkinsでPythonを実行するためのプラグインです。
・「Cobertura Plugin」はカバレッジ集計用のプラグインです。

「Jenkinsの管理」→「プラグインマネージャ」→「利用可能」タブに進んで、「ShiningPanda Plugin」「Cobertura Plugin」にチェックを入れてインストールします。

5. JenkinsにPythonの設定
今回は、Python2.7とPython3.4を設定します。

「Jenkinsの管理」→「システムの設定」のなかに「Python」という項目があると思います。
「Python追加」から必要な分だけPythonの設定を入れて、保存。

各項目の設定 
 ・Name: Jenkinsで識別するための名前(何でもよさそう)
 ・Home or executable: Pythonの実行パス。「which python」等で確認して設定。


6. Jobの作成
「新規ジョブ作成」から「マルチ構成プロジェクトのビルド」を選択して、OK。
プロジェクト名はお好きな物を。


7. Jobの設定
6. で新規にジョブを作成した場合は、設定画面に遷移しているはずなので。(遷移していない人は、プロジェクト名を選択して、「設定」を押してください。)

設定画面の下の方にある項目を設定してきます。それ以外の項目は、GithubにコミットしたタイミングでJobを走らせたい場合は設定してください(ここでは割愛)。

次の3カ所を設定して、保存する。
・マトリックスの設定
 「軸の追加」→「Tox」を選択して、「py27」にチェック。「py34」にもチェックしたいが項目がない。。。

   仕方が無いので、「高度な設定」→「py34」と入力。

・ビルド
 「ビルド手順の追加」→「Tox Bulider」を選択し、「Configuration file」に「tox.ini」(デフォルトだった)になっていることを確認。

・ビルド後の処理
 「ビルド後の処理の追加」から次の2つを選択して設定する。

 ①「Cobertura カバレッジ・レポートの集計」
    Cobertura XMLレポート パターン: **/coverage.xml
    ※Pytestのカバレッジレポートは、「coverage.xml」で出力されるので。
 ②「JUnitテスト結果の集計」
    テスト結果XML: **/junit-*.xml
    ※tox.iniで設定したファイル名を指定。

 設定するとこんな感じになる。

8. あとは「ビルド実行」を押すだけ。

参考
http://d.hatena.ne.jp/kuma8/20121124/1353723982
http://tox.readthedocs.org/en/latest/example/jenkins.html
http://shiningpanda.com/tox-on-jenkins-with-shiningpanda-plugin.html


2015年3月21日土曜日

CentOS 7にPython3.4をインストール

2012年にCentOS 6.2 に Python 2.7.2をインストールしてから、気づけばOSもPythonも新しいバージョンに移行してました。

CentOS 7に更新したので、Python3.4をソースからインストールします。
元のPython2.x系は、CentOSで使っている(yumがPythonで書かれていたような、、、)ものはそのままにして、別に3.xを入れます。

1.インストールに必要なものをインストール
$sudo yum install zlib zlib-devel tk-devel tcl-devel sqlite-devel ncurses-devel gdbm-devel readline-devel bzip2-devel openssl-devel

2.Pythonをダウンロードして解凍する
$ wget https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz
$ tar zxvf Python-3.4.3.tgz
3.インストール
今回は、「/usr/local/python34」配下にインストールします。
$ cd Python-3.4.3
$ ./configure --with-threads --enable-shared --prefix=/usr/local/python34
$ make
$ sudo make install

4.パス設定
$ vi ~/.bash_profile
下記を追加する。
export PATH=/usr/local/python34/bin:$PATH

5.エラー対策(x86_64の場合)
ここで,実行すると
python3: error while loading shared libraries: libpython3.4m.so.1.0: cannot open shared object file: No such file or directory
とエラーで動かない.コンパイルはされているので,シンボリックを貼る
$ sudo ln -s /usr/local/python34/lib/libpython3.4m.so.1.0 /lib64/

6.確認
$ python3 --version
Python 3.4.3と表示されれば成功

2014年5月25日日曜日

VMWare ESXiで使っていたHDDをArch Linuxでマウント

ESXiの中身をfuseを使ってマウントして引き上げる。

参考
http://mapi.tumblr.com/post/2909365768

ツールのインストール
1.非Rootユーザで実施
[test@localhost ~]# wget https://aur.archlinux.org/packages/vm/vmfs-tools/vmfs-tools.tar.gz

2.解凍
[test@localhost ~]# tar zxvf vmfs-tools.tar.gz

3.依存関係を解決しながらコンパイル

[test@localhost ~]# makepkg -s

4.インストール
[test@localhost ~]# sudo pacman -U vmfs-tools-0.2.5-1-x86_64.pkg.tar.xz

マウント
[test@localhost ~]# sudo vmfs-fuse /dev/sda1 /mnt

アンマウント
公式サイトのどこにもアンマウント方が書いてないし、とりあえず普通にアンマウントしたらできた。。。ちなみに「sudo fusermount /mnt」はダメでした。。
[test@localhost ~]# sudo umount /mnt

あとは、コピーするなり、変換するなり、お好きなように。

2014年4月23日水曜日

Arch Linuxをインストールする

CentOSとかUbuntuとか比較的インストールサイズが大きい、全部入りに飽きたので、Arch Linux
を使ってみることにしました。コンソールからすべて作業する手順が多いですが、コンソールではコピペができないのでSSHでインストールするようにします。
例によって参照先は下記の通りです。
https://wiki.archlinux.org/index.php/Install_from_SSH_(%E6%97%A5%E6%9C%AC%E8%AA%9E)
http://opamp.hatenablog.jp/entry/20110704/1309798049
http://blog.volment.com/?p=47
https://wiki.archlinux.org/index.php/Network_Configuration_(%E6%97%A5%E6%9C%AC%E8%AA%9E)

# 2014/05/25 パーティション作成とGRUBの設定を修正。USBメモリにインストールしている場合の手順追加。

NIC読み込みの確認
root@archiso ~ # lspci -v | grep -A 2 Ethernet
レスポンス貼り付け

NIC名の確認
root@archiso ~ # ls -l /sys/class/net
レスポンス貼り付け

NICの有効化

root@archiso ~ # ip link set eno16777736 up
root@archiso ~ # ip addr

動的 IP アドレス

IPアドレスが取得できない場合は、下記のコマンドでDHCPを有効にしてIPアドレスを取得する。
root@archiso ~ # dhcpd eno16777736

SSHの有効化
root@archiso ~ # systemctl start sshd

インストールCDのRootユーザのパスワードを設定する。
とりあえず、root等で良い。
root@archiso ~ # passwd


Install
ここからは、SSHでremote接続して作業します。
gdisk /dev/sda

パーティションを切る
  • /dev/sda1 /boot 400MB
  • /dev/sda2 swap 5GB
  • /dev/sda3 / 残り
※MBRの場合は、一番先頭に「ef02(BIOS boot partition)」を作成する必要があります。

※他のOSをインストールしてあるディスクを使い回すときは、パーティション情報等をすべて削除した方がイイかも。

root@archiso ~ # csgdisk --zap-all /dev/sda

パーティションのフォーマット
root@archiso ~ # mkfs.ext4 /dev/sda1
root@archiso ~ # mkfs.ext4 /dev/sda3

インストール先のディバイスをマウント
root@archiso ~ # mount /dev/sda3 /mnt
root@archiso ~ # mkdir /mnt/boot
32 root@archiso ~ # mount /dev/sda1 /mnt/boot                                                              
root@archiso ~ # df
Filesystem                  1K-blocks   Used Available Use% Mounted on
/dev/mapper/arch_root-image   1438256 681656    740216  48% /
dev                           1012560      0   1012560   0% /dev
run                           1023452  30736    992716   4% /run
/dev/sr0                       546816 546816         0 100% /run/archiso/bootmnt
cowspace                      1535180   1132   1534048   1% /run/archiso/cowspace
/dev/loop0                     234880 234880         0 100% /run/archiso/sfs/root-image
tmpfs                         1023452      0   1023452   0% /dev/shm
tmpfs                         1023452      0   1023452   0% /sys/fs/cgroup
tmpfs                         1023452      0   1023452   0% /tmp
tmpfs                         1023452    912   1022540   1% /etc/pacman.d/gnupg
tmpfs                          204692      0    204692   0% /run/user/0
/dev/sda3                    12180228  30548  11507916   1% /mnt
/dev/sda1                      271811   2062    251197   1% /mnt/boot
root@archiso ~ #

ミラーリポジトリの優先度を上げる
$ vim /etc/pacman.d/mirrorlist
# jpか何かでgrepして日本にミラーを一番上の行にもってくる
# Server = http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch

システムのインストール
1 root@archiso ~ # pacstrap /mnt base base-devel zsh vim openssl

インストール先にGRUBをインストール
1 root@archiso ~ # pacstrap /mnt grub-bios


fstabの生成
1 root@archiso ~ # genfstab -p /mnt >> /mnt/etc/fstab
1 root@archiso ~ # vim /mnt/etc/fstab
以下を追加する。
/dev/sda2 swap swap defaults 0 0

インストール先の設定
chrootでルートディレクトリを変更して、設定先に移行します。
1 root@archiso ~ # arch-chroot /mnt

rootユーザのパスワード設定
sh-4.3# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
sh-4.3#

タイムゾーンの設定
sh-4.3# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

ロケールの設定
sh-4.3# vim /etc/locale.gen
sh-4.3# grep -ve "#" /etc/locale.gen
en_US.UTF-8 UTF-8
ja_JP.EUC-JP EUC-JP
ja_JP.UTF-8 UTF-8
sh-4.3# locale-gen
Generating locales...
  en_US.UTF-8... done
  ja_JP.EUC-JP... done
  ja_JP.UTF-8... done
Generation complete.
sh-4.3#

GRUBの設定
sh-4.3# grub-install --target=i386-pc --recheck /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.
sh-4.3#
sh-4.3# grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-linux
Found initramfs image: /boot/initramfs-linux.img
Found fallback initramfs image: /boot/initramfs-linux-fallback.img
Found linux image: /boot/vmlinuz-linux
Found initrd image: /boot/initramfs-linux.img
done
sh-4.3#

インストール先から抜ける
sh-4.3# exit
exit
root@archiso ~ #

インストール先のディバイスをアンマウント
root@archiso ~ # umount /mnt/{boot,}
root@archiso ~ #

再起動して、インストール先ディバイスから起動
root@archiso ~ # reboot

NICの設定
# ls -l /sys/class/net
# ip link set ens33 up
# ip addr
・一時的にDHCPを有効にする場合
# dhcpd ens33
・恒久的にDHCPを有効にする場合
# systemctl start dhcpcd@ens33
# systemctl enable dhcpcd@ens33


SSHの有効化
# pacman -S openssh
# systemctl start sshd
# systemctl enable sshd

SWAPの設定
[root@localhost ~]# mkswap /dev/sda2
Setting up swapspace version 1, size = 2931856 KiB
no label, UUID=48a2821e-87d6-40ee-abda-506fc785515d
[root@localhost ~]# swapon /dev/sda2

ifconfigとWgetを使うために入れ
sudo pacman -S net-tools wget

user追加
[root@localhost ~]# useradd testUser
[root@localhost ~]# mkdir /home/testUser
[root@localhost ~]# chown -R testUser:testUser /home/testUser

Initial ramdisk 環境の作成
USBメモリやLVM、RAIDでインストールした場合は必ず実施する。
[root@localhost ~]# mkinitcpio -p linux
詳細はInitial ramdisk 環境の作成


2013年10月13日日曜日

FlaskとHighcharts 3.0でグラフを描く

FaskからJSON形式でブラウザに送り、Highcharts 3.0でグラフとして表示するサンプルです。
作業メモなので、気が向いたら補足説明を入れるかも。。

例によって参考は下記です。

highcharts 「Preprocesssing data from a file」

フォルダ構成とその中身は下記の通りです。

HTML
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script src="http://code..com/highcharts.js"></script>
    <script>
     $(document).ready(function() {

    var options = {
        chart: {
            renderTo: 'container',
            type: 'spline'
        },
        series: [{}]
    };

    $.getJSON('/data.json', function(data) {
        options.series[0] = data;
        var chart = new Highcharts.Chart(options);
    });

});
    </script>
</head>
<body>
<h1>{{ title }}</h1>
<div id="container" style="width:100%; height:400px;"></div>
</body>
</html>


Pythonファイル
# -*- coding: utf-8 -*-

from flask import Flask, jsonify
import random
from flask.templating import render_template

app = Flask(__name__)


@app.route('/data.json')
def data():
    list = []
    for i in range(1000):
        list.append([i, random.randint(0, 500)])
    return jsonify(data=list)

@app.route('/')
def index():
    return render_template("graph.html", title=u"グラフテスト")

if __name__ == '__main__':
    app.run(debug=True)