2010年8月31日

如何設定 Becky email client 的 SMTP 驗證

前陣子遇到一個問題,當以 SMTP 寄信的時候,若沒有設定驗證,有時候會發生信件無法寄出的狀況,因此建議還是要手動設定 SMTP 驗證。

不同的 email client 有不同的設定畫面,而 Becky 的 SMTP 驗證設定步驟如下。

步驟一:進入Becky後,在信箱上點選右鍵,選擇「內容」



步驟二:切換到「雜項」頁籤,勾選「SMTP驗證」,並在下方的「用戶名稱」及「密碼」欄位中輸入mPro的帳號以及密碼。最後按確定即可。

2010年8月25日

[Outlook 2007] 如何將 Exchange Server 上的信件收到本機資料夾

以下簡單紀錄之前寫的操作步驟。

步驟一:從控制台進入「郵件」設定


步驟二:選擇目前 Exchange 帳戶所在的設定檔
(若要新增設定檔,請參考:新增 Outlook 電子郵件設定檔),之後點選「內容(R)」按鈕



步驟三: 點選「資料檔」按鈕


步驟四:在「帳戶設定」頁面中,點選「新增(A)...」按鈕



步驟五:在「新的Outlook資料檔」畫面中,使用預設值:Office Outlook 個人資料夾檔案 (.pst)


步驟六:選擇新增的 .pst 檔的儲存位置,並設定檔案名稱



步驟七:在「建立Microsoft個人資料夾」畫面中,設定此資料檔的名稱,此名稱會顯示在Outlook中。



步驟八:在「帳戶設定」畫面中,點選剛剛新增的資料檔,而後再點選上方的「設成預設值(D)」按鈕。



步驟九:此時由跳出的對話視窗中可看出,爾後電子郵件會被收到本機的資料夾,Exchange伺服器上的資料會被清空。



步驟十:啟動 Outlook 2007,此時選擇剛剛修改過的「mPro」設定檔



步驟十一:測試收信,可看到新的信件會被收到剛剛在本機上新增的個人資料夾



步驟十二:在「個人資料夾」上按右鍵,選擇「”個人資料夾”的內容」,可看出此資料夾(.pst)檔是存在本機上。
此外可登入 Exchange Server 確認是否伺服器上面的信件已經清空。





2010年8月18日

如何批次將Yahoo!信箱中的聯絡人轉到Outlook

前陣子被客戶問到「如何批次將 Yahoo! 信箱中的聯絡人轉到 Outlook」,趁機把完整的步驟記錄下來,要特別注意的是步驟?和步驟?,其他的操作倒也不複雜。


步驟一:清除目前 iPhone 中的 Exchange 聯絡人資訊
(取消 iPhone 上 Exchange 帳號的聯絡人同步)
  1. 在 iPhone 上的「設定」點選「電子郵件/聯絡資訊/行事曆」














  2. 選擇 Exchange 信箱 (e.g., xxx@emome.net),取消同步「聯絡資訊」(點選「聯絡資訊」右邊的按鈕,讓按鈕變成白色,顯示「O」。
  3. 在跳出的對話視窗中選擇「從 iPhone 刪除」。














步驟二:將 Yahoo! 信箱中的聯絡人同步到 iPhone 中
  1. 開啟 iTunes,點選裝置中的「xxx 的 iPhone」。
  2. 切換到「資訊」頁籤,勾選「同步聯絡資訊,與 Yahoo! Address Book」,之後執行 iPhone 同步。
  3. 同步完成後 Yahoo! 信箱中的聯絡人就可成功同步到 iPhone 中(存放於「來自我的PC」群組)。(詳細說明請參考:如何將 Yahoo! 奇摩通訊錄與 iPhone 同步)














步驟三:將 iPhone 中的 Yahoo! 聯絡人資料同步到 Outlook 帳號中
  1. 確認目前 Outlook 的聯絡人是空的。
  2. 將「同步聯絡資訊」改成與「Outlook」,之後執行 iPhone 同步,此時要注意選擇「合併」,以免將 iPhone 中的 Yahoo! 聯絡人資訊清除。
  3. 完成後 iPhone 中的 Yahoo! 聯絡人就同步到 Outlook 中了。














  4. 接下來稍等幾分鐘,讓 Outlook 將聯絡人資訊同步到 Exchange Server 上。
步驟四:取消 iTunes 中的「同步聯絡資訊」

為了避免爾後同步時在 iPhone 上產生兩份相同的 Exchange 聯絡人資訊,先取消勾選「同步聯絡資訊」,再執行一次 iPhone 同步。此時原本位於「來自我的 PC」群組的聯絡人會被轉移到「我的 iPhone」群組中。



步驟五:把 Exchange Server 上的聯絡人資訊同步到 iPhone 中

  1. 在 iPhone 的「設定」->「電子郵件/聯絡資訊/行事曆」中,選擇 Exchange 信箱(e.g., xxx@emome.net)














  2. 設定同步「聯絡資訊」(點選「聯絡資訊」右邊的按鈕,讓按鈕變成藍色,顯示「|」。
  3. 在跳出的對話視窗中選擇「刪除」,如此會把「我的 iPhone」群組中的聯絡人資訊刪除,僅保留從 Exchange Server 同步下來的資訊 (位於「xxx@emome.net (Exchange)」群組中),以免產生兩份相同的聯絡人資料。














  4. 接下來稍等幾分鐘,讓 iPhone 把 Exchange Server 上的聯絡人資訊同步到手機上即可。若 iPhone 沒有立刻執行同步,請點選主畫面下方的「Mail」應用程式,開啟後就會自動執行同步。
將 Yahoo! 信箱聯絡人匯出成符合 Outlook 格式的 .csv 檔後匯入 Outlook

步驟一:登入 Yahoo! 信箱後,切換到「通訊錄」畫面



步驟二:點選畫面右邊的「工具」->「匯出」



步驟三:點選 Microsoft Outlook 右邊的「立即匯出」按鈕,將 Yahoo! 信箱中所有的聯絡人資料匯出為符合 Outlook 聯絡人資料的 .csv 檔



步驟四:首先要輸入 Yahoo! 自動產生的認證碼



步驟五:認證碼輸入正確後,會自動開始下載 .csv 檔,預設檔名為「yahoo_ab.csv」,請記住將檔案存到哪個位置



以下匯入 Outlook 的步驟可參考:如何批次將 Yahoo! 信箱中的行事曆匯入到 Outlook,有差異的地方包括以下兩點:
  1. 選擇目的資料夾時,要選擇「聯絡人」
  2. 設定自訂欄位時,要根據聯絡人的各欄位設定對應關係

步驟六:開啟Outlook,選擇「檔案」-->「匯入及匯出」



步驟七:在「匯入及匯出精靈」中,使用預設值:從其他程式或檔案匯入,之後按「下一步」


步驟八:在「匯入檔案」精靈中,向下捲動到最下面,選擇「逗點分隔值 (Windows)」後,按「下一步」


步驟九:在「匯入檔案」精靈中,點選「瀏覽(R)...」按鈕,選擇剛剛存好的 yahoo_ab.csv 檔案,按「下一步」


步驟十:在選取目的資料夾視窗中,選擇「聯絡人」


步驟十一:需勾選「匯入”yahoo_ab.csv”至資料夾:聯絡人」左邊的方塊,而後點選右邊的「對應自訂欄位」按鈕,以設定欄位的對應。


步驟十二:以拖拉的方式,將左邊的英文名稱拖曳到右邊的中文名稱。基本上英文和中文的欄位順序是一致的,只要按照順序拖拉一次即可。




重要:若沒有設定好欄位對應,匯入Outlook後資料會是一片空白:




步驟十三:自訂欄位設定完畢後,點選「完成」按鈕,就會開始匯入。


2010年8月16日

兩種更好的 AWStats 報表呈現方式 - BetterAWStats & JAWStats

前陣子在 AWStats 上啟用了內建的日報表 (daily report) 功能,接下來繼續 survey 週報表 (weekly report),無意間找到另外兩個讓 AWStats 的報表呈現全新風貌的套件:BetterAWStatsJAWStats (這兩個套件的 link 可以參考 Wikipedia - AWStatsExternal links,看來也沒有其他提供不同 AWStats Report 格式的 project 了)。

安裝這兩個套件以後,除了可以更輕鬆的閱讀 AWStats 報表以外,這兩個套件也各自提供了一些官方 AWStats 報表無法提供的功能。另一個好處是這兩個套件的作法都是讀取 AWStats 的統計資料後,再以不同的方式呈現報表,因此不會對系統造成額外的負擔。

BetterAWStats

基本資料
  • 官網
  • Online Demo
  • Help Forum
  • 安裝 & config.php 修改方式請參考 betterawstats-1.0.zip 解壓縮後的 \betterawstats\docs\install.txt,蠻簡單的
最大的優點:可檢視跨年度的統計資料 (稱為 Monthly history)



AWStats 官方的報表只能看到「某年度所有月份」的統計資料:


因此若有「檢視跨年度資料」的需求,就適合用 BetterAWStats 來呈現。

安裝欲到的問題 & 解法
使用上的問題
  • 繪製網頁的速度挺慢的,也很吃 server 的 memory。我管理的 site 中資料比較大的,甚至會超出 php.ini 中設定的 memory_limit (64 MB) (已經從預設的 16 MB 放大4倍了)。
  • All(daily) 和 All(monthly) 的表格呈現方式不容易閱讀 (橫向無限延伸)。

JAWStats

基本資料
最大的優點:繪製網頁的速度快,介面看起來很新穎 (Table 欄位都支援排序),用起來心情比較好

Visitors each Month (月份可跨年)

Visitors each Year (可檢視各年度總計)

Calendar of Visitors this Month (可提供週流量/點擊數統計 的功能!! 看右手邊那兩欄就是了)
把流量、點擊數等等放到月曆裡面,很棒的介面。


安裝欲到的問題 & 解法
  • 由於 JAWStats 已經好久沒更新了,因此有人把這個 project fork 出一個叫做 MAWStats 的 project,目標提供更多的報表檢視方式,但是我一直裝不起來,MAWStats 始終無法讀取 AWStats 的統計資料。
使用上的問題
  • JAWStats 是根據 AWStats 的月報表格式來設計,不支援日報表 (daily report),不過這點影響不算大,日報表用 AWStats 內建的報表格式即可。
  • 如同作者所說 (Any disadvantages?),壞處是 mouse click 比以前多,因為每一個分頁都只有顯示以前完整報表的一部分資料。但我覺得這也沒太大問題,反應速度快比較重要。
小結

就這兩個套件來說,安裝 & 設定 & 使用都很簡單,但是 JAWStats 的介面更新穎好用,且反應速度比 BetterAWStats 快很多,功能也更強,因此最後還是推薦 JAWStats 啦!可惜這套件已經超久沒更新了 ... 希望未來更新版的 AWStats 的資料格式都可以維持 backward compatibility,不然就麻煩啦!

(因為 OS、Search Engine、Browser 的版本不斷推陳出新,因此 AWStats 主程式也常常需要跟著升級,不然就無法辨識最新版的軟體了。)

參考資料:

2010年8月13日

SIKULI 初體驗 -2:進階技巧 & 其他感想

上週日分享了一篇:SIKULI 初體驗 - 利用 SIKULI 每日自動將 50 個 AWStats Report 另存為 mht 檔,這週又花了些時間持續改進。

雖然經過幾次測試,感覺已經沒甚麼問題了,但最後想到這樣的東西要交接其實蠻困難的,因此最後捨棄了這個完整版,另外花了 10 分鐘改出一個精簡版,只有自動去抓 4 個很複雜的綜合報表下來另存,並且用 FileZilla 上傳到 Server 而已。

經過幾天的實作,又更深入的瞭解到 SIKULI 的好處 & 應用上的限制,以下是簡單的紀錄。

進階技巧

SIKULI command line tool

SIKULI 是可以接受 command line 參數的,我遇到的狀況是 SIKULI 執行有時候會失敗,而我要抓的 mht 檔可以分為幾個群組,因此後來我把每個群組包成一個 function,新增一些 command line 參數來對應這些 function,如此就可透過 command line 參數來控制要重跑哪一個 function 了。

SIKULI command line tool 的相關說明可從官網點選 download 之後,在左下的 Others 中點選 Command Line Tool 連結,如下圖:


傳遞 command line 參數給 SIKULI 的範例 (在 cmd 視窗中執行以下指令):

C:\Program Files\Sikuli\Sikuli-IDE.bat -r "\path\to\your\sikuli project folder\xxx.sikuli" --args yourArgs

SIKULI 從 command line 接受到參數以後,會存在 sys.argv 裡頭 (其實底層就是 Python 啦),應用方式請參考:Handling command line arguments (sys.argv)。

這次遇到的問題

SIKULI Runtime Exception

有一次在實際執行 SIKULI script 的時候,經過了 30 個迴圈,忽然冒出以下這個 C++ Runtime Error,按下確定以後整個 SIKULI process 就消失了 (IDE 也掛了),完全不知道為甚麼 ... 但之後執行了很多次都不會遇到這個問題,可見現階段 SIKULI 還是不太穩定。



SIKULI Project Rename 後不會自動刪除舊的 .py 和 .htm 檔

在 SIKULI IDE 中可以選擇「檔案」->「另存為」將 project 取個新名字後另存,但是舊的 .py 和 .htm 檔不會自動刪除,必須手動刪除,有點小小的麻煩。



其他感想:
  • SIKULI IDE 不支援 ctrl-z,無法很快速的復原上一個操作。
  • 在 Windows 上,明明每次都在全螢幕模式下關閉程式,但 IE 和 Excel 在開關多次以後,有時候會以「非全螢幕」的方式啟動,導致我要另外叫 SIKULI 去視窗上按右鍵後輸入「x」來確保視窗是全螢幕執行,很麻煩。
  • 如果在設定「排定的工作」時選擇將電腦喚醒後執行 SIKULI script,當電腦進入待命/休眠狀態,再被喚醒執行 SIKULI script 時,往往會發生錯誤 (最常見的是無法辨認某張圖片),即使手動重新執行也可能會持續出錯,再重開機以後就恢復正常,不確定是啥問題。
  • SIKULI 執行時有時候會造成短暫的 delay (e.g., 0.x 秒),如此可能會造成某張圖片無法辨識,因為該跳出的對話視窗還來不及跳出來。我的解法是多利用 waitwaitVanish,讓 SIKULI 等到預期的對話視窗出現以後再執行動作。
  • 承上,wait 和 waitVanish 的預設 timeout 時間是 3 秒,但以「IE另存新檔」這個對話視窗為例,執行時間要視該網頁的複雜程度而定,有可能要超過 3 秒才能存檔完畢,因此適當的調整 timeout 秒數是很重要的,否則後面的程式一執行可能會讓系統整個亂掉。
  • 程式可攜性 (Portability):由於 SIKULI 的核心 & 最有魅力的特點是內建電腦視覺引擎,因此「抓圖寫程式」是一大賣點。但是仔細想想就會發現,如果用越多抓圖,就越會被綁在目前的操作環境中,如果把程式移到另一台電腦上,或者把 XP 的佈景主題改掉 (e.g., 藍色 -> 銀色),那 SIKULI 執行失敗 (無法辨識圖片) 的機率就會越高。

    就這點來看,SIKULI 比較適合用在自己的工作環境的自動化,除非企業有用 AD 或者其他可以讓每個使用者桌面都維持一致的管理機制,不然 SIKULI script 要大量佈署是有困難的。(當然也可以盡量用 hotkey (e.g., ctrl-c, ctrl-v 來取代點擊 GUI 環境中的按鈕,但是這樣就不炫了...)
經過這次的實作對 SIKULI 有了初步的認識,雖然目前暫時還沒想到其他的應用,但以後自己手上又多了一個好用的工具啦!

參考資料:
  1. SIKULI command line tool 
  2. How to force a running Sikuli script to quit? 
  3. An Introduction to Python: Control Structures
  4. The basic python datatypes (dictionary)
  5. Handling command line arguments (sys.argv)
  6. Exception FindFailed

2010年8月12日

[Linux/Unix] 讓 script 在登出後仍可繼續在背景執行 - at 排程

之前的文章中曾經提到,因為改了 cron job 的執行時間,導致 awstats.pl 執行失敗,必須重跑 cron job。由於是在週末發現這個狀況,因此我透過 VPN 連回公司下指令 (sh /path/to/awstats.pl -update ...),但由於 VPN 有限制幾分鐘內沒有向 server 要求資料就會自動斷線,但 awstats.pl 分析一個網站往往要耗時 15~20 分鐘,且 VPN 連線過程中若登出 server (手動 or 被踢出),則執行中的 script 就會被中斷了,最後發現利用 at 排程 + 背景執行就可以解決這個問題。

只要輸入 at HH:mm YYYY-MM-DD,按 Enter 後,再輸入「perl /path/to/awstats.pl -update ... &」,按 Enter,最後按 ctrl+d 結束 at 排程的編輯即可。

其中關於 at 排程的設定可參考:鳥哥-僅執行一次的工作排程,至於如何讓 script 於背景執行,請參考:鳥哥-job control的管理

利用 at 排程設定的工作,即使在執行此排程的帳號登出系統的狀況下仍然可以正確執行,就和利用 cron job 執行排定的工作一樣。

當然要對每個網站都手動輸入一次指令也太麻煩了,最好是把所有的 awstats.pl -update 指令包成一個 .sh 檔案,之後就只要執行那個 .sh 檔就可以啦!

參考資料:

2010年8月11日

[AWStats] 刪除因 awstats.pl 執行不完全造成的 awstatsMMYYYYDD.mySite.tmp.### 檔案

上一篇文章提到,前陣子調整 AWStats 更新統計資料檔的 cron job (其實就是執行 awstats.pl -update) 的時間後,AWStats 統計資料檔都沒有正常更新,除了會產生錯誤訊息以外,還會在存放統計資料檔的資料夾 (config 檔中的 DirData) 中留下檔名為 awstatsMMYYYYDD.mySite.tmp.### (數字可能從 3 位到 5 位) 的暫存檔案。

以我管理的 AWStats Server 為例,由於要分析的網站多達 26 個,因此我有利用 DirData 這個設定值來區分不同網站群組的統計資料檔,除此之外,每個網站群組下還另外細分月報表以及日報表資料夾,造成 xxx.tmp.### 檔案分佈在各種不同深度的目錄中,那麼要如何一次把這些檔案清光呢?

一開始我想要用 ls -lR | grep tmp 指令來找出所有的暫存檔案,這個方法雖然可以把檔案名稱 & 檔案屬性列出來,但由於缺乏檔案的完整路徑,因此無法對檔案進行刪除或者其他的操作。

後來(壞毛病又發作)我參考了 Renaming Files As Lowercase Using Perl 這篇文章,把 rename 的動作改成「rm -f」,由於 Perl 支援 Regular Expression,因此要找出檔名格式為 xxx.tmp.### 的檔案非常容易。

但是在測試 ok 以後我又覺得,如果每次要做類似的事情都要寫個 Perl script,或者把現有的 script 打開來編輯,未免也太麻煩了吧!後來同事提醒我,find 指令的回傳結果就是完整的檔案路徑,在查閱 find 指令的 man page 之後,終於發現只要用以下的一行指令就可以搞定了:

find [AWStats DirData] -name *.tmp.* -delete

由於 -name 這個 switch 本身就支援 Regular Expression,因此用來找檔名中含有 tmp 的檔案相當容易,不放心的話可以先不要加上 -delete 這個 switch,就可以把找到的檔案列在螢幕上逐一確認是否有誤判的情況。

確認把暫存檔案 (xxx.tmp.###) 都找出來以後,加上 -delete 這個 switch,find 就會幫你把找出來的檔案砍掉囉!

找到正確作法 (& find 的正確用法) 以後,感覺真是爽快阿 :D

2010年8月9日

[AWStats] [解法] Error: Command for pipe 'xxx/logresolvemerge.pl xxx.log failed, Setup may be wrong. 問題

最近發現 AWStats 更新統計資料檔耗時很久,現在都要拖到早上 8 點多才能完成,因此就調整了執行 AWStats 統計資料檔更新的 cron job,把執行時間往前移,沒想到改好以後連續兩天 AWStats 都沒有正確更新,查看執行結果以後發現如下的 log (這是自己把 awstats.pl 的 output 另存的 log,預設不會儲存):

Mon Aug  9 01:31:06 CST 2010 Start analyzing [mySite]
==================================================
==================================================
Create/Update database for config "/path/to/awstats.[mySite].conf" by AWStats version 7.0 (build 1.969)
From data in log file "/path/to/logresolvemerge.pl /path/to/logs |"...
Phase 1 : First bypass old records, searching new record...
Searching new records from beginning of log file...
Error: Command for pipe '/path/to/logresolvemerge.pl /path/to/logs2 |' failed
Setup ('/path/to/awstats.[mySite].conf' file, web server or permissions) may be wrong.
Check config file, permissions and AWStats documentation (in 'docs' directory).
Mon Aug  9 01:31:07 CST 2010 Finish analyzing [mySite]
==================================================
==================================================

如果根據 awstats.pl 的 output 去查看 config file 內容、檔案存取權限,或者 AWStats 的文件恐怕也找不出甚麼頭緒,後來我發現每天要分析的 log 檔根本沒有被抓下來,因為我把 cron job 的執行時間移到比 log server 準備好 log 的時間更早了!

接下來就可以很合理的懷疑,是不是「當 log 檔不存在時」awstats.pl 就會產生以上的 output?經過測試 (執行 /path/to/awstats.pl -update -DatabaseBreak=month -config= [mySite] 指令),果然當 log 檔不存在時,awstats.pl 就會產生以上的 output!

這個錯誤訊息跟 config 檔的內容、檔案存取權限等等是完全沒關係的 ...

[shell script] 驗證 tar 解壓縮的執行結果

前陣子在用 tar 解壓縮更新程式的時候,發現某個檔案沒有被正確被覆蓋,經過確認,tar 指令的確有用到 -m 參數 (用法參考:這篇),難道是 tar 這個全世界用了 N 年的工具出了問題?

雖然最後證實那個檔案是因為其他的原因被還原到舊版,但是在那段真相水落石出之前的空窗期我寫了一個短短的 script 來驗證 tar 的執行結果,完整程式碼如下:

#!/bin/bash
#created by Tim, verify the tar unzip operation is successful
#this file should be put in the /tmp directory

#read the log file from the output of "tar -zxvfm XXX.tar.gz > /tmp/tar.log" command

BASEDIR=`pwd`  cd /tmp
files=`cat tar.log`
count=0

for file in $files
do
   #check the last modified date of each file, it should be the same
   ls -l "$BASEDIR/$file" 
   count=`expr $count + 1`
done
echo "count: $count"

#verify files count
#precondition: there should be only 1 .tar.gz file in the /tmp directory
#the number of files in the .tar.gz file
tarCount=`tar -tv -f *.tar.gz | wc -l`   
echo "tarCount: $tarCount"

if [ $count -eq $tarCount ]; then

   echo "file count check OK!"
else
   echo "file count check FAILED!!"
fi 

程式很單純,只是先利用 tar 的 -v (verbose) 參數把執行過程中解壓縮的
檔案相對路徑紀錄到 /tmp 下的 tar.log 檔,而後逐一比對 log 檔中的
路徑與目前系統中實際的檔案修改時間是否相同,最後會比較 tar 檔中
所含的檔案數量與 tar.log 檔中紀錄到的檔案數量是否一致。 
 
雖然這程式應該沒啥用 (tar 出問題的機率超低),但還是擺著備忘一下,
當作 shell script 的範本也好 :p 

2010年8月1日

SIKULI 初體驗 - 利用 SIKULI 每日自動將 50 個 AWStats Report 另存成 mht 檔

話說今年 1 月底的時候,看到一篇很紅的文章:Sikuli 帶來的意義與無窮的潛力,作者是 vgod,當時有些知名的網站/部落客也寫過感想:
SIKULI 官網首頁有放一個 Demo,內容是自動設定網卡IP:


當時看完以後覺得超炫,但是後來也沒花時間去嘗試看看,直到上週想要作一件事:把 AWStats 每天產生的報表存成靜態網頁 (mht),才想到用 SIKULI 應該可以很簡單的完成這樣工作!

需求

之所以想要作這件事情,是因為每次瀏覽 AWStats 報表的時候都是連到一個如:http://myAWStatsReportSite/awstats/awstats.pl?&config=mySite 的 url,此時 awstats.pl 這隻程式會讀取事先計算好的統計資料檔,然後即時的繪製月報表

對於規模很小的網站來說大概沒啥感覺,但是對於每日流量到達 GB 以上等級的網站來說,在每月下旬的時候點選月報表的速度就明顯的慢很多,而若想要把 10 個左右的這類網站的流量合併統計,那麼到了月底的時候,即時繪製月報表最多可以花上超過 20 秒,這是個無法令人接受的速度!

仔細想想,這種報表的資料來源是歷史資料,一旦歷史資料分析完畢以後,往後不管在任何時間點選這張報表,內容應該都是一樣的,因此很適合以靜態網頁來呈現。為了方便檔案管理 & 加速網路傳輸,我決定把檔案另存成 mht 檔,這樣以後看報表的速度就快多啦!

問題是我的 AWStats 分析的網站很多,月報表 + 日報表總共有 50 個,叫我每天手動一個一個把網址貼到 IE,然後另存成 mht,再 FTP 到 Server 上 ..... 我才不要哩,又不是吃飽沒事幹!這就是 SIKULI 大顯身手的時候啦!(是說就是要把這種瑣碎工作弄成自動化,才可以每天吃飽沒事幹阿 ... Zzz)

SIKULI 初體驗

要使用 SIKULI,首先要去官網下載最新版的 SIKULI IDE: 1.0.1 (Java 6 or 7 is required, 2013-08-31 更新版本),目前對於 Windows & Mac 的支援較佳,聽說也有人把 SIKULI port 到 Linux 上。我抓的是 Windows 版,在 Win XPP 上安裝非常簡單,一路 Next 到底就好。

Sikuli IDE 打開以後大概長這樣:


版面配置跟很多主流的 IDE 差不多,很容易上手。

接下來就可以動手寫程式啦!在官網的 Documentation 中有 Tutorials & Examples 可以參考,花點時間看過去以後就知道程式大概要怎麼寫了。

基本上程式寫起來很簡單,由於 SIKULI 內建強大的電腦視覺引擎 (computer vision engine),內建的 function 如 find、findAll、click、paste 等都可以餵入一張圖片作為參數,當 SIKULI 執行 sikuli script 時就會去比對目前螢幕上可視區域中與指定圖片相符合的區域 (region),並且對該區域執行指定的動作 (e.g., click、paste)。

用文字寫起來太囉唆了,直接跑一個官網上的範例最容易瞭解了: Click all starts in Gmail

將 zip 檔下載解壓縮,用 SIKULI 打開後,再準備好一個 Gmail 視窗:



經過測試,如果用範例內的 find 函式會有問題 (TypeError: 'edu.mit.csail.uid.Match' object is not iterable,看來 find 函式的 return 值是單一的物件,不是如陣列一樣可以作 iteration 的資料結構),改用 findAll 以後就正常了:


當 SIKULI Script 在執行的時候,會看到一瞬間滑鼠游標依序由上往下把所有未標記成星號的 Gmail 郵件標記成星號,真的是非常有趣!

另外,SIKULI 可以用 click / doubleClick / rightClick 等函式來模擬滑鼠事件,以 type 函式控制鍵盤輸入,因此只要可以用滑鼠 + 鍵盤完成的工作,都可以寫成程式讓 SIKULI 自動執行 (應該有超過 90% 的工作都可以用滑鼠 + 鍵盤完成吧?所以 SIKULI 真的是潛力無窮呢!)

在以 type控制鍵盤輸入方面,SIKULI 支援 Windows Key, Ctrl, Alt, Tab, Up, Down, F1~F15 等特殊鍵,非常方便,我最常用的有以下幾種:
  1. type("c", KEY_CTRL):ctrl+c
  2. type("\t", KEY_ALT):alt + tab
  3. sleep(n):讓 process 睡 n 秒
  4. var = Env.getClipboard():把系統剪貼簿中的暫存資料存到變數 var
  5. paste("IE開啟舊檔.png", var):把變數 (URL) 貼到 IE 的「開啟舊檔 (ctrl-o )」視窗中
SIKULI 所支援的特殊鍵請參考官網文件:12. Key Constants 中的 12.1. Key Modifiers12.2. Special Keys

由於 Sikuli 是以 Jython 為基礎發展的,而 Jython 是 Python for the Java Platform,因此要查詢基本語法的話可以參考 Jython / Python 的資料。

我這次寫的 script 邏輯如下:


程式利用的技巧就如同上述 4 點,並不困難。

測試情境:
  1. AWStats Static Report test.xlsx 隨便放哪裡都可以,但是要先用 Excel 開過一次,讓檔名出現在最新開啟過的檔案清單 (MRU list)中
  2. 要在「我的文件」中建立一個名為「AWStats Static Reports」的資料夾 (不然就要自己重新抓圖,去改程式碼第12行)
  3. script 執行完畢後會回到 SIKULI IDE (執行過程中發生錯誤也會回到 IDE 中),此時可再檢視「我的文件」->「AWStats Static Reports」中是否有三個 mht 檔。

Sikuli IDE 的優點:
  1. 如同[T客邦] 抓圖寫程式,SIKULI 將改變世界一文中所說,Graphical Scripting Language 真的是非常有趣,實際上若打開 Sikuli source files 資料夾中的 ProjectName.py 檔來看就可以知道,在 Sikuli IDE 中看到的圖檔在程式碼中其實是檔名 (如「1.png」),但是 IDE 在 project 資料夾中找到這個檔以後,就把圖檔讀出來顯示在畫面上,令人覺得很親切,大大增加了程式碼的可讀性和易用性,該行程式要作甚麼真的是一目瞭然。
  2. 大大降低寫程式的門檻,讓一般人也有機會自己把平常操作電腦的瑣碎步驟自動化。
  3. SIKULI IDE 的配色看起來很舒服。

Sikuli IDE 目前的小缺點:
  1. 在 Win XPP 下,按 Alt + Tab 從 Sikuli IDE 跳到其他視窗,再跳回 Sikuli IDE 後,(有時候)會 focus 在 Sikuli IDE 的「檔案」選單,而非程式碼編輯器中,這點不太方便。
  2. 將程式碼從一個 project copy 到另一個 project,或者將 project 另存新檔後,有時候會有問題,例如 function 的左括號「(」看起來不見了 (但是看ProjectName.py 檔會發現還在,如果在 IDE 裡面多加一個「(」反而會讓 script 無法執行),或者是找不到圖檔 (這時要重新指定圖檔),會導致執行時的 SyntaxError。

未來目標:
  1. 設定 Windows 排程,在上班前把這個 script 跑過一次,等到上班時間就可以直接瀏覽靜態的 mht 報表了
  2. 在開啟 IE & Excel 之前,先把用來存放 mht 檔的資料夾清空
  3. 50 個 mht 檔都產生完畢以後,自動分門別類的以 FTP 上傳到 Server 中
經過這次的練習,以後如果要處理類似的繁瑣工作 (而且是跨應用程式的),又多了一個好用而且超酷炫的工具啦!

參考資料:
  1. Sikuli 帶來的意義與無窮的潛力
  2. PROJECT SIKULI (官網)
  3. PROJECT SIKULI documentation (官網)
  4. [T客邦] 抓圖寫程式,SIKULI 將改變世界
  5. [阿宅萬事通] Pranav Mistry 的第六感與高雄餐旅學院,還有來自台灣的 Sikuli~~~
  6. wwfc的遊戲世界 - for loop

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D