顯示具有 python 標籤的文章。 顯示所有文章
顯示具有 python 標籤的文章。 顯示所有文章

2012年1月25日 星期三

monitor filesystem events by python

似乎各大 os 都不同, 沒有統一的方法。
ref 1 是使用 pyinotify 在 linux 下的範例。
ref:
  1. http://david-latham.blogspot.com/2008/06/python-inotify-pyinotify-how-to-watch.html
  2. http://pyinotify.sourceforge.net/
  3. http://www.stepthreeprofit.com/2008/06/cross-platform-monitoring-of-filesystem.html

file_monitor.py
 1 #!/usr/bin/python
 2 import os
 3 import pyinotify
 4 import sys
 5
 6 #ref: http://david-latham.blogspot.com/2008/06/python-inotify-pyinotify-how-to-watch.html
 7
 8 wm = pyinotify.WatchManager()
 9 mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_MODIFY | 
            pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO
10
11 class PTmp(pyinotify.ProcessEvent):
12     # move file to /mnt
13     def process_IN_MOVED_TO(self, event):
14         print "move to: %s " % os.path.join(event.path, event.name)
15     def process_IN_MOVED_FROM(self, event):
16         print "move from: %s " % os.path.join(event.path, event.name)
17     def process_IN_CREATE(self, event):
18         print "Create: %s " % os.path.join(event.path, event.name)
19
20 #    def process_IN_DELETE(self, event):
21 #        print "Delete: %s " % os.path.join(event.path, event.name)
22     def process_IN_MODIFY(self, event):
23         print "Modify: %s " % os.path.join(event.path, event.name)
24
25
26 notifier = pyinotify.Notifier(wm, PTmp())
27
28 m_dir='/mnt/'
29 wdd = wm.add_watch(m_dir, mask, rec=True)
30 print "monitor:", m_dir
31
32 while True:
33     try:
34         notifier.process_events()
35         if notifier.check_events():
36             notifier.read_events()
37     except KeyboardInterrupt:
38         notifier.stop()
39         break

2012年1月18日 星期三

python url encone

/ 不會被編碼的問題:

>>> import urllib
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', '')
'%2Ftest'
>>> urllib.quote('\n', '')
'%0A'
>>> urllib.quote('\r', '')
'%0D'

ref:
http://stackoverflow.com/questions/1695183/how-to-percent-encode-url-parameters-in-python

2012年1月9日 星期一

python data time

在 python 獲得 timestamp

import datetime
today = datetime.date.today()
current = datetime.datetime.now()

print current.strftime('%Y%m%d-%H%M%S')

20120109-140126

strftime: http://docs.python.org/library/datetime.html#strftime-strptime-behavior
ref: http://pythonly.blogspot.com/2008/12/python.html

2011年12月31日 星期六

擷取網站檔案

http_c0.py
  1 #!/usr/bin/env python
2 #encoding=utf-8
3 # -*- coding: utf-8 -*-
4 #ref: http://www.cnblogs.com/chenzehe/archive/2010/08/30/1812995.html
5
6 import httplib
7 import commands
8 import shutil
9 import re
10 import os
11
12 def get_fn(fp):
13 a=fp.rfind('/')
14 a+=1
15 return fp[a:]
16
17 def get_href(page_html):
18 #return get_page('href.*"', page_html)
19 return get_page('[0-9_]*.shtml', page_html)
20
21 def get_page(page_pattern, page_html):
22 s=''
23 if (re.search(page_pattern, page_html)):
24 m=re.search(page_pattern, page_html)
25 #print "found:", m.group()
26 s = m.group()
27 else:
28 pass#print "not found"
29 return s
30
31 def get_next_page(page_html):
32 return get_page('<a href=.*>下一页</a>', page_html)
33 def get_previous_page(page_html):
34 return get_page('<a href=.*>上一页</a>', page_html)
35 def get_file_url(page_html):
36 return get_page('http://.*.jpg', page_html)
37
38 #http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
39
40 #url = 'www.webxml.com.cn'
41 url = 'www.google.com'
42 #url = 'pic.076.com/ComicList/201008/2911_68.shtml'
43 url='files.076.com'
44 url = 'pic.076.com'
45
46 conn = httplib.HTTPConnection(host=url)
47
48 h={'User-agent': 'python-httplib'}
49
50 req_path = '/'
51 #req_path = '/WebServices/WeatherWebService.asmx?wsdl'
52 #conn.request("GET", "/", headers=h)
53 #conn.request("GET", req_path, headers=h)


54 #path='2911_69.shtml'
55 path='/201008/20100830145757244358.jpg'
56 path='/ComicList/201008/'
57 p='2818.shtml'
58 #p='2818_32.shtml'
59
60
61 #conn.request("GET", path+p, headers=h)
62 #r1 = conn.getresponse()
63 #print r1.status, r1.reason
64 #print "msg:", r1.msg
65 #print "version:", r1.version
66 #print "headers:", r1.getheaders()
67 #data1 = r1.read()
68 #print type(data1)
69 #print "len:", len(data1)
70 #print data1
71
72 #f=open('c.jpg', 'w')
73 #f.write(data1)
74 #f.close()
75
76 #print get_file_url(data1)
77 #ppage=get_previous_page(data1)
78 #print ppage
79 #ppage_page=get_href(ppage)
80 #print ppage_page
81
82 move_dir = os.path.join(os.getcwd(), 'jpg/')
83
84 try:
85 os.mkdir(move_dir)
86 except Exception as err:
87 if err.errno != 17: # the directory already exists
88 print("warn", err)
89 else:
90 print("ERROR", err)
91
92 fc=0
93 while(1):
94
95 print 'req path:', path+p
96 conn.request("GET", path+p, headers=h)
97 r1 = conn.getresponse()
98 data1 = r1.read()
99
100 furl = get_file_url(data1)
101
102 fn=get_fn(furl)
103 print 'get file:', furl
104 print 'fn:', fn
105
106 # os.spawnl(os.P_NOWAIT, cmd)
107
108 cmd = "/usr/bin/wget " + furl
109 ( stat, output ) = commands.getstatusoutput(cmd)
110 if stat!=0:
111 print output
112 print "move", os.path.join(os.getcwd(), fn), "to", os.path.join(os.getcwd(), 'jpg/')+str(fc) + '.jpg'
113 shutil.move(os.path.join(os.getcwd(), fn), move_dir + str(fc) + '.jpg')
114 fc+=1
115
116 npage=get_next_page(data1)
117 print npage
118 # if npage.find('_101')!=-1:
119 # break
120 npage_page=get_href(npage)
121 print npage_page
122 p=npage_page
123 if fc > 100 :
124 break
125
126 #print data1


這是一個練習程式, 把漫畫網站的圖檔抓下來, 這樣就不用辛苦的一一點選上一頁/下一頁, 不過這程式有好幾個缺點。
  • 需要使用 wget
  • 只能針對特定網站, 可能需要改寫其他規則才能用在其他網站上。
  • 依序把所有檔案抓下來, 前一個圖檔抓完, 才能抓下一個。
  • 停止條件很粗糙。
  • 若是網站圖檔 url 使用 javascript 產生, 那就無法處理了, 這需要一個 javascript interpreter, 這工程可能有點麻煩。
不過已經比慢慢等著圖檔傳輸, 按著上一頁/下一頁好很多了。

這裡有更多技巧:
http://www.pythonclub.org/python-network-application/observer-spider

2011年12月15日 星期四

python http web server

http_s1.py
 1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #encoding=utf-8
4 # python 2
5
6 import sys
7 import BaseHTTPServer
8 from SimpleHTTPServer import SimpleHTTPRequestHandler
9 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
10 import string,cgi,time
11
12 class MyHandler(BaseHTTPRequestHandler):
13 def do_GET(self):
14
try:
15 #if self.pathc.endswith(".html")
16 self.send_response(200)
17 #self.send_header('Content-type', 'text/plain')
18 #self.send_header('Content-type', 'text/html; charset=utf-8')
19 self.send_header('Content-type', 'text/xml; charset=utf-8')
20 f = open('/test.html')
21 self.end_headers()
22 self.wfile.write(f.read())
23 f.close()
24 return
25 except IOError:
26 self.send_error(404, 'File Not Found')
27 def do_POST(self):
28
# global rootnode
29 try:
30 ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
31 if ctype == 'multipart/form-data':
32 query=cgi.parse_multipart(self.rfile, pdict)
33 self.send_reponse(301)
34 self.end_headers()
35 upfilecontent = query.get('upfile')
36 print "filecontent", upfilecontent[0]
37 self.wfile.write("<HTML>POST OK.<BR><BR>")
38 self.wfile.write(upfilecontent[0]);
39 except:
40 pass
41
42 HandlerClass = SimpleHTTPRequestHandler
43 ServerClass = BaseHTTPServer.HTTPServer
44 Protocol = "HTTP/1.1"
45
46 if sys.argv[1:]:
47 port = int(sys.argv[1])
48 else:
49 port = 8000
50 server_address = ('127.0.0.1', port)
51
52 HandlerClass.protocol_version = Protocol
53 #httpd = ServerClass(server_address, HandlerClass)
54 #httpd = ServerClass(server_address, MyHandler)
55 httpd = HTTPServer(server_address, MyHandler)
56
57 sa = httpd.socket.getsockname()
58 print "Serving HTTP on", sa[0], "port", sa[1], "..."
59 httpd.serve_forever()


ref: http://fragments.turtlemeat.com/pythonwebserver.php

對於 script language 我似乎搞錯了, 我還停留在 dos 的批次檔和 bash 的能力。只能處理簡單的文字處理功能, 近來接觸 python 後, 原來 script language 可以完成強大的程式, 而且比起 C/C++ 來說, 簡單不少。身為 C/C++、組合語言基本教義派的我, 也不禁開始懷疑幹嘛那麼辛苦用 C/C++ 來打造程式。除了說服自己在速度上的差異, 好像沒什麼可以在說服自己使用 C/C++, 不過速度在自己身邊的應用, 好像也沒有到無法接受的地步。除了練習的 OS 程式外, 用 script language 好像都可以完成。

當然 script language 也有些問題, 例如版本的取捨, 目前為止 python 已經來到第三版, 但還是有很多使用者停留在 2, 就算我才剛學, 也是以 python 2 為主。而 python 2.6 和 2.7 的差異, 也多少困擾開發者, 尤其是在使用標準程式庫之外的 library, 還要確認這個 library 是在那個 python 上才能執行。ex: a lib 要 python 2.7, b lib 只能在 python 2.5 以下執行。以 C++ 來舉個反例: qt3, qt4 在一般的 c++ compiler 都應該可以 compile。

簡單有個很重要的好處, 以 http web server 來說, 很快可以實作一個出來, 把重點擺在 http 來回的 protocol 上, 不用管程式本身的細節, 練功嘛!能動就好了, 不用考慮太多細節, 可以著重在 http 這個重點。

看看 qt 的 web server 版本: http://doc.qt.nokia.com/solutions/4/qtservice/qtservice-example-server.html 雖然簡化不少, 但還是複雜多了。而且只看程式碼本身, python 很容易就可以猜出來每一行在幹嘛, 不用太多的說明。

總之在 c/c++ 之外, 學個 script language 好像還不賴。

2011年12月7日 星期三

web service and python

web service 有三種:
  1. soap/wsdl (python 有好幾個 library 可處理, 這裡使用 pysimplesoap)
  2. xmlrpc (python xmlrpc 可處理)
  3. 忘了

pysimplesoap 使用起來蠻容易的 (server/client), 不過可能不是所有 data type 都能支援, 需要自己動手修改。soapui 是以 java 完成的 soap 測試工具, 用來測試 soap 還蠻好用的。

關於 soap 有一本中文書籍可以參考:
From wish list books


ref:
http://andypony.mis.stut.edu.tw/present/tech_rep1.htm
http://code.google.com/p/pysimplesoap/
http://sun.cis.scu.edu.tw/~nms9115/articles/delphi/WebServices/WebServices1.htm

2011年11月30日 星期三

使用瀏覽器連到 http://www.google.com 發生什麼事情 (python http client test by httplib)

在 chrome 上打 http://www.google.com
很神奇吧!

hc.py
1 #!/usr/bin/env python
2
3 import httplib
4
5 conn = httplib.HTTPConnection(host="www.google.com")
6
7 conn.request("GET", "/")
8 r1 = conn.getresponse()
9 print r1.status, r1.reason
10 print "msg:", r1.msg
11 print "version:", r1.version
12 print "headers:", r1.getheaders()
13 data1 = r1.read()
14 print data1
15
16 data1 = r1.read()
17 print data1

r.txt 是 hc.py 得到的結果。從 r.txt line 2 得到 server 傳回的 header: Location: http://www.google.com.tw/
14.30 Location 的說明可以得知, 這是要做 redirect 到 www.google.com.tw, 所以 chrome 就會在連到 www.google.com.tw。從 wireshark 抓封包可以看到這樣的流程。

r.txt
1 302 Found
2 msg: Location: http://www.google.com.tw/
3 Cache-Control: private
4 Content-Type: text/html; charset=UTF-8
5 Set-Cookie: PREF=ID=8a924e1dbd9c2f9e:FF=0:TM=1322661327:LM=1322661327:S=YKAvttVjJWz8Xb2z; expires=Fri, 29-Nov-2013 13:55:27 GMT; path=/; domain=.google.com
6 Date: Wed, 30 Nov 2011 13:55:27 GMT
7 Server: gws
8 Content-Length: 222
9 X-XSS-Protection: 1; mode=block
10 X-Frame-Options: SAMEORIGIN
11
12 version: 11
13 headers: [('content-length', '222'), ('x-xss-protection', '1; mode=block'), ('set-cookie', 'PREF=ID=8a924e1dbd9c2f9e:FF=0:TM=1322661327:LM=1322661327:S=YKAvttVjJWz8Xb2z; expires=Fri, 29-Nov-2013 13:55:27 GMT; path=/; domain=.google.com'), ('server', 'gws'), ('location', 'http://www.google.com.tw/'), ('cache-control', 'private'), ('date', 'Wed, 30 Nov 2011 13:55:27 GMT'), ('x-frame-options', 'SAMEORIGIN'), ('content-type', 'text/html; charset=UTF-8')]
14 <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
15 <TITLE>302 Moved</TITLE></HEAD><BODY>
16 <H1>302 Moved</H1>
17 The document has moved
18 <A HREF="http://www.google.com.tw/">here</A>.
19 </BODY></HTML>

ref: http://www.cnblogs.com/chenzehe/archive/2010/08/30/1812995.html

2011年11月25日 星期五

python send mail (smtp) by gmail server

send_mail.py
1 #!/usr/bin/env python
2 # ref: http://docs.python.org/library/email-examples.html
3 # Import smtplib for the actual sending function
4 import smtplib
5
6 # Import the email modules we'll need
7 from email.mime.text import MIMEText
8
9 # Open a plain text file for reading. For this example, assume that
10 # the text file contains only ASCII characters.
11 #fp = open(textfile, 'rb')
12 # Create a text/plain message
13 #msg = MIMEText(fp.read())
14 #fp.close()
15 msg = MIMEText("python mail test")
16
17 me = 'my@gmail.com'
18
19 you = 'you@gmail.com'
20
21 # me == the sender's email address
22 # you == the recipient's email address
23 #msg['Subject'] = 'The contents of %s' % textfile
24 msg['Subject'] = 'The contents of 111'
25 msg['From'] = me
26 msg['To'] = you
27
28 print 'send...'
29
30 # Send the message via our own SMTP server, but don't include the
31 # envelope header.
32 #s = smtplib.SMTP('localhost')
33 s = smtplib.SMTP_SSL('smtp.gmail.com', 465) #port 465 or 587
34 s.login('me@gmail.com','my_passwd')
35 s.sendmail(me, [you], msg.as_string())
36 s.quit()
37 print 'end send'

in my test, I cannot use port 587.
ref:
http://docs.python.org/library/smtplib.html

2011年11月19日 星期六

delete durable queue (rabbitmq)

以下的 code 可以刪除 queue (include durable queue)

delete_q.py
1 #!/usr/bin/env python
2 # python 2
3 # pika 0.5.2
4 # delete queue (include durable queue)
5 import pika
6 import pickle
7
8 connection = pika.AsyncoreConnection(pika.ConnectionParameters(host='localhost', credentials=pika.PlainCredentials('guest', 'guest')))
9
10 channel = connection.channel()
11 channel.queue_delete(queue='queue-name')
12 channel.close()
13 connection.close()

ref:
http://blog.boxedice.com/2010/10/21/clearing-purging-rabbitmq-queues/

2011年11月9日 星期三

install RabbitMQ in ubuntu

ubuntu 11.10:

apt-get install rabbitmq-plugins-common
pip install pika==0.9.5

ubuntu 10.04:

apt-get install rabbitmq-server
sudo apt-get install python-pip
pip install pika==0.5.2

pip 安裝的 pika 會安裝在 /usr/local/lib/python2.6 路徑下。

apt server:

python3 install pip in ubuntu

curl -O http://python-distribute.org/distribute_setup.pyl
python3.2 distribute_setup.py
easy_install-3.2 pip

python distribute_setup.py # for python2