Thursday, May 31, 2007

本日のテトリス

37540 点なり...。

あおじる

ファンケルのオンラインショップで、青汁(粉末スティック型)を注文した。

本日のテトリス

57360 点なり。

Wednesday, May 30, 2007

tips : rsync

今月、現場において Python で作成したスクリプトを導入した。Subversion のデータをバックアップするためだ。commit が発生するたびに、ローカルホストとリモートホストのデータを同期させる。現在 Subversion を稼働させているハードウェアが古くなってきているため、そのうち HDD が故障してしまうかもしれない。そのため、データをリモートホストにも保存することにした。最初、FTP を使用してファイルを転送するしくみで導入した。スクリプトは正常に動作したため、バックアップを取得していなかったころと比較して、安心できるようになった。ただし問題がひとつ。commit が発生するたびに FTP でファイルを転送するため、リモートホストにおいてファイルが増えていくのだ。リモートホストの HDD の容量は、約 130 GB で、リポジトリのファイルは大きくて 0.150 GB ほど。commit が頻繁に発生するわけでないため、さほど問題でなかった。ただ、気持ち悪かった。

最初に考えた対策、それは、覚えたいと思っていた Ruby でスクリプトを書き、リモートホストに設置して、一定の間隔で古いファイルを削除することだった。ただ、面倒だったため挫折...。かわりに rcync を使用してデータをミラーすることにした。

簡単に説明すると、以下のコマンドを書いたスクリプトを作成し、スクリプトへの path を post-commit ファイルに記述すればよい。自分は shell でなく Python で書いたが。

/* 参考 */
post-commit ファイルは、リポジトリのディレクトリに存在する hooks ディレクトリに保存されている。ただし、ファイル名が post-commit.tmpl であるため、リネームして実行権限を付与(chmod +x)しておく。すると、commit が発生するたびに pos-commit ファイルが kick される(post-commit ファイル自体は shell で記述されている)のだ。


(スクリプトの内容ここから)
#!/bin/sh
rsync -az -e ssh --delete ~ftp/pub/samba nimbus:"~ftp/pub/tridge"
(スクリプトの内容ここまで)


ちなみに、この 1 行は、rsync の man ページに記載されているそのまま。

これだけで、ローカルホストとリモートホストのファイルを同期できるのだ!しかも高速!別のスクリプトを書いて古いファイルを削除したりせずに済ませられる。--delete オプションを指定しているため、ローカルホストで削除されたファイル or ディレクトリは、リモートホストにおいても削除されるのだ!すばらしい。

ただし、上記 1 行を書いてスクリプトを実行すると、ssh を使用してリモートホストへ接続するため、パスワードを入力しなければならない。そのため、以下のように修正する。


(スクリプトの内容ここから)
#!/bin/sh
rsync -az -e "ssh -i /home/you/.ssh/id_rsa" --delete ~ftp/pub/samba nimbus:"~ftp/pub/tridge"
(スクリプトの内容ここまで)


ssh コマンドに -i オプションを指定して、-i オプションの引数に秘密鍵を指定する。以下に示すとおり、empty なパスフレーズを指定すれば、ssh の認証プロンプトを表示させず接続できる。


public-key と private-kye を作成する手順は、以下のとおり。

localhost$ ssh-keygen -t rsa
##### empty なパスフレーズを指定する #####
localhost$ scp ~/.ssh/id_rsa.pub remotehost:id_rsa.pub
localhost$ ssh remotehost

remotehost$ su -
remotehost# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bk
remotehost# vi /etc/ssh/sshd_config
# SSH version 1
RSAAuthentication yes

# SSH version 2
PubkeyAuthentication yes

AuthorizedKeysFile .ssh/authorized_keys
:wq
remotehost# /etc/init.d/ssh restart
remotehost# exit
remotehost$ mkdir ~/.ssh
remotehost$ chmod 700 ~/.ssh
remotehost$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
remotehost$ chmod 600 ~/.ssh/authorized_keys
remotehost$ exit


超便利です。

Tuesday, May 29, 2007

テトリス

最近テトリスにハマっている。毎日、練習を欠かさない。現在、86460 点が最高得点。このテトリスは、Ubuntu Linux の Gnome デスクトップにデフォルトで付属しているのゲームのひとつ。

Saturday, May 26, 2007

IDE

Python に対応している IDE を探している。Eclipse は重いしなぁ...。

PythonEditors

Thursday, May 24, 2007

日本語

Ubuntu Linux 7.04 において OperaBrowser を参考に Opera をインストールしてみた。が、日本語を入力できない。不便。localize しなくても不便じゃないが、母国語を入力できない、となると厳しいな。

Wednesday, May 23, 2007

Dell

Dell の Web サイトがリニューアルしたらしく、Internet Explorer と Netscape Navigator じゃないと購入できない、という?な制限が解除されたようだ。やはり Dell の製品は安いな。20 インチあたりの LCD を購入したい。だいたい 3 万円くらいだ。10 万円なら、LCD に加え、本体と Windows をプラスできる。なやましい。Windows を使用しないと思うが...。

Sunday, May 20, 2007

Python : Tkinter で GUI プログラミング, part.004

前回の内容を少し編集して、発生するイベントの結果を Listbox に書き込んでみる。method の結果を GUI 上に書き出せるので便利かも。

#!/usr/bin/python

from Tkinter import *
import os

class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid()
self.createWidget()

def createWidget(self):
self.quitButton = Button(self, text='Quit', command=self.quit)
self.quitButton.grid()

self.showLog = Button(self, text='ClickMe')
self.showLog.grid()
self.showLog.bind('', self.load_data)

self.listbox = Listbox(self, selectmode=SINGLE, height=30, width=30)
self.listbox.grid(columnspan=2, sticky=E+W+N+S)

def load_data(self, event=None):
self.listbox.delete(0, END)
self.items = []
for filename in os.listdir('.'):
item = filename
self.items.append(item)
self.listbox.insert('end', repr(item))


app = Application()
app.master.title('foobar')
app.mainloop()

Friday, May 18, 2007

Python : Tkinter で GUI プログラミング, part.003

Python による GUI プログラミングの続き。

イベントハンドラを使用してみる。ボタンがクリックされたとき任意のイベントを発生させるサンプル。

#!/usr/bin/python

from Tkinter import *

class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid()
self.createWidget()

def createWidget(self):
self.quitButton = Button(self, text='Quit', command=self.quit)
self.quitButton.grid()

self.sayHello = Button(self, text='ClickMe')
self.sayHello.grid()
self.sayHello.bind('', self.sayhello)

def sayhello(self, event=None):
print 'Hello!'

app = Application()
app.master.title('foobar')
app.mainloop()


--
24. Events: responding to stimuli

Tuesday, May 15, 2007

Python : Tkinter で GUI プログラミング, part.002

ウィンドウにボタンを作成してみるサンプル。

#!/usr/bin/python

from Tkinter import *

class App:

def __init__(self, master):

frame = Frame(master)
frame.pack()

self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.button.pack(side=LEFT)

self.hi_there = Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side=LEFT)

def say_hi(self):
print "hi there, everyone!"

root = Tk()
app = App(root)
root.mainloop()


--
Hello, Again

Monday, May 14, 2007

tips : lsof

自分のマシンに *誰かが接続している* かもしれない、それを確認する方法をひとつ。以下の例において、IP アドレスは自分のマシンに設定されている IP アドレスとする。

試験するため自分の IP アドレスに ssh で接続しておく。

$ ssh 192.168.100.21

lsof コマンドを、IP アドレスのレンジを指定して実行できる。

$ lsof -i @192.168.100.21:1-1024
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
ssh 6940 satoshi 3u IPv4 24658 TCP apple.local:54965->diablo.local:ssh (ESTABLISHED)
$

Python : Tkinter で GUI プログラミング, part.001

Python で GUI プログラミングする過程を不定期にメモ!?してみる。


$ python
>>> from Tkinter import *
>>> root = Tk()
>>> w = Label(root, text='Hello, World')
>>> w.pack()
>>> root.mainloop()


### 自分のモジュールのネームスペースに Tkinter からすべてをインポートする。
>>> from Tkinter import *

### Tkinter をイニシャライズするため、Tk root widget を生成する。
>>> root = Tk()

### Label widget 生成する。
>>> w = Label(root, text='Hello, World')
>>> w.pack()

### Tkinter イベントループへ突入する。
>>> root.mainloop()



終了。

Sunday, May 13, 2007

Python : string substitution

Python で置換してみるサンプル。普通なら、ファイルを読み込んで実行することになるだろう。

$ python
>>> import re
>>> mystr = '2007-05-13 ERROR : -----'
>>> re.sub(r'2007-[01][0-9]-[0-3][0-9] (.+)$', r'\1', mystr)
'ERROR : -----'
>>>


典型的なファイルの読み込みは、以下のとおり。

>>> read_file = '/etc/passwd'
>>> file = open(read_file, 'r')
>>> for i in file: print i,
...
root:x:0:0:root:/root:/bin/bash
...(以下つづく)...

Python : SimpleXMLRPCServer

Python で、リモートホストのメソッドを実行してみるサンプル。参考にした情報は、www.python.org の Python Library Reference に記載されている。

18.25 SimpleXMLRPCServer -- Basic XML-RPC server

サンプルコードは、公式ドキュメントのコメントを削除した内容そのまま。


### Server Program

#!/usr/bin/python

from SimpleXMLRPCServer import SimpleXMLRPCServer

server = SimpleXMLRPCServer(("localhost", 8000))
server.register_introspection_functions()

server.register_function(pow)

def adder_function(x,y):
return x + y
server.register_function(adder_function, 'add')

class MyFuncs:
def div(self, x, y):
return x // y

server.register_instance(MyFuncs())

server.serve_forever()



### Client Program

import xmlrpclib

s = xmlrpclib.Server('http://localhost:8000')
print s.pow(2,3) # Returns 2**3 = 8
print s.add(2,3) # Returns 5
print s.div(5,2) # Returns 5//2 = 2

# Print list of available methods
print s.system.listMethods()


### 実行

ふたつのターミナルを実行させ、server.py と client.py を実行する。server.py から実行しておく。

$ ./server.py

別のターミナルで。

$ ./client.py
8
5
2
['add', 'div', 'pow', 'system.listMethods', 'system.methodHelp', 'system.methodSignature']
$


リモートホストに Python がインストールされてあり、プログラムを常駐させておかなければならないが、簡単にリモートホストのメソッドを実行できることを便利と感じた。

かなり Python 熱いっす!ついに会社で Python のスクリプトを導入してしまった、shell で書けばいいものを。自分以外の人間が保守できないから、早めに布教活動せねば。新しい言語に興味をもってくれそうな人がいない...。気分転換に Python で GUI プログラムを作成してみるか、と考えてみた土曜日。つまり今日。Tkinter モジュールでコリコリ書いてみたが...、いまいち理解できない。また挫折。

Wednesday, May 09, 2007

連休その後

まだ連休の雰囲気から脱出できていない人が存在するせいか、職場は比較的またーりしている...。

過ぎ去ったゴールデンウィークは(自分が社会人になってから)最長の連休だったに違いない。プロジェクトが暗礁に乗り上げたおかげで、5 月の 1, 2 日は休みだった。つまり 9 連休だったわけだ。ただ、先月 30 日の深夜から症状が出た風邪のため、ほとんど寝てばかりだった。とても外出できるような体調でなかったのだ。加えて、まだセキだけ続いている状態。常にセキこんでいる状態で、結構しんどい。寝ていてもセキこみ苦しいため何度も目覚めてしまう。そのため、十分な睡眠時間を確保できていない。気管支炎だろうか...。また病院へ行こう。連休中、集中的に Java を勉強するはずだったが...、連休の後半から、なぜか Python を勉強しなおしている...。

Sunday, May 06, 2007

How to connect to a MySQL database in Python

Python から MySQL へ接続してみる

----------(ここから)----------
>>>
>>> import MySQLdb
>>> con = MySQLdb.Connect(host='localhost', db='db01', user='root', passwd='')
>>> cursor = con.cursor()
>>> sqlString = 'SELECT * FROM user;'
>>> cursor.execute(sqlString)
2L
>>> results = cursor.fetchall()
>>> print results
((1L, 'satoshi', 'abe'), (2L, 'SATOSHI', 'ABE'))
>>> con.close()
>>>
----------(ここまで)----------

Friday, May 04, 2007

Python : ftp クライアント

Python で書いた ftp クライアントのサンプル

----------(ここから)----------
#!/usr/bin/python

from ftplib import FTP
import sys, getpass, os.path

host, username, localfile, remotepath = sys.argv[1:]
password = getpass.getpass("Enter password for %s on %s: " %(username, host))

f = FTP(host)
f.login(username, password)

f.cwd(remotepath)

fd = open(localfile, 'rb')
f.storbinary('STOR %s' %os.path.basename(localfile), fd)

fd.close()
f.quit()
----------(ここまで)----------


実行例

$ ./ftp_client.py localhost user_name ~/upload.file tmp