八月 25, 2016
» 聊天機器人一份,不加咖啡



「聊天機器人一份,不加咖啡」是今年在 Coscup 2016 分享的講題,投影片在此
內容包含介紹聊天機器人與 Hubot,轉換Coffeescript到ES6,與移植經驗總結。
 
Webbybot 是我們將 Hubot 完全移植到 ES6 的成果。在準備這場演講時,有鑑於Server Side聊天機器人設定上還是稍嫌複雜,於是我參考 Hubot 架構,做了原始版本只有80行的網頁端聊天機器人。除了支援聊天機器人基本功能外,同時也支援擴充腳本(plugin)與擴充功能(addon)。由於參考了Hubot架構,於是命名時就取了Saihubot 這個既包含 Hubot,又有濃濃台味的名稱(SaiHu 即台語的「師傅」)。

這次活動官方有提供 LINE 版的聊天機器人。我在活動早上花幾小時基於 Saihubot 做了 Coscup 2016網頁版機器人,可以上去玩玩。

要做一個自己的網頁聊天機器人,只須在 github 上 fork 專案,然後就可以直接在 Github 上編輯,修改後的結果直接反應到 https://[your name].github.io/saihubot 網站上。修改極端容易,畢竟核心只有不到100行,對聊天機器人有點興趣的人可以照著上述說明試試,看看原始碼,當然若能送個 Issue 或 Pull Request,這場「扎根」議程達到的效果就最好了。
 

四月 8, 2016
» Setup a skype chatbot on Respberry pi with 4GB SD Card

It's a small challenge and fun to setup a chatbot on a small device with restrained resource.

Here's the instruction to setup a chatbot on Respberry pi with 4GB SD Card.


1. Download respbian lite

We need respbian lite because normal Respbian took more than 4GB space. If you have 8GB or larger SD Card, normal Respbian works fine for you.

You can download them from https://www.raspberrypi.org/downloads/raspbian/

2. Flash image to sdcard

I did it in Mac with diskutil. You can check the install guide from https://www.raspberrypi.org/documentation/installation/installing-images/README.md for other platforms.

$ diskutil list
/dev/disk0 (internal, physical):
...
/dev/disk1 (internal, virtual):
...
/dev/disk2 (internal, virtual):
#:                       TYPE NAME                    SIZE       IDENTIFIER
0:     FDisk_partition_scheme                        *3.9 GB    disk2
1:             Windows_FAT_32 boot                    58.7 MB    disk2s1
2:                      Linux                         3.8 GB     disk2s2

$ diskutil unmountDisk disk2
$ sudo dd bs=1m if=2016-03-18-raspbian-jessie-lite.img of=/dev/rdisk2

3. Login to respbian

Respbian lite does not provide desktop environment, so we'll do everything with command line.

Insert SDCard, bootup and login into respbian with
name: pi
password: raspberry

Refer from http://elinux.org/RPi_Distributions#Raspbian


4. Install node and redis

Refer from https://nodejs.org/en/download/package-manager/

$ curl -sL https://deb.nodesource.com/setup_5.x > script
$ chmod 755 script
$ sudo -E ./script
$ sudo apt-get install -y nodejs build-essential redis-server
$ node -v
v5.10.1
5. Install webbybot

Webbybot is the rewrite of hubot from coffeescript to ES6, its will be more maintainable in the future.
In respbian lite, the git is not pre-installed, so we need install git-core from apt-get as well.
sudo apt-get install git-core
git clone https://github.com/gasolin/webby-template pibot
cd pibot
npm install
./bin/webby
webby> webby test
webby> pong

6. Deploy on messengers

Check Workable adapters section to install your bot onto telegram, facebook messenger, or skype
https://github.com/gasolin/webby-template#workable-adapters

Let's take skype for example. First you need sign up an skype account, then put the username/password on to .env file.

 
vi .env

HUBOT_SKYPE_USERNAME=name
HUBOT_SKYPE_PASSWORD=password
 
Then install hubot-skyweb adapter and switch the core to webbybot

npm install hubot-skyweb
vi node_module/hubot-skyweb/src/skyweb.coffee
replace require 'hubot' to 'webbybot'.
Then run
 
./bin/webby -a skyweb 

You are good to go! You can add new skills on your pibot by following https://github.com/gasolin/webbybot/#add-plugins
which is same as hubot, and create your own plugin to control the respberry pi https://github.com/gasolin/webbybot#write-your-own-plugin.

Have fun!

三月 14, 2016
» How we ported Hubot from Coffeescript to ES6


Hubo

We (Fred Lin & Ray Lin) have ported Github's popular chat robot framework 'Hubot' from Coffeescript to plain Javascript with ES6 features. Currently I name it webbybot to denote ES6 version of hubot, to better test the port result and avoid the naming confusion with the original hubot.

Now webbybot is fully functional and still support all coffeescript written plugins.
If you have an existing bot generated by hubot-generator, you can install webbybot via `npm install webbybot` command, follow with simple instruction and see your bot works smoothly with webbybot core.

(For experienced developer, the instruction guide you to replace script in generated '/bin' folder from 'hubot' to 'webby'. And change the adapter library import from 'hubot' to 'webbybot'.)


As time goes to 2016, there're less reason to use Coffeescript instead of standard ES6 Javascript. During the porting we do learned something that might helpful for your projects.

1. Use npm script directly instead of gulp or grunt

With npm we can define some scripts directly in the 'script' attribution of 'package.json' file. Webbybot use 'npm run build' command to compile ES6 to plain javascript via Babel. Do style checking via 'npm run lint' command.

2. Use babel directly instead of webpack

At the beginning we count on webpack's babel-loader to convert ES6 to plain javascript. Alas its a beginning of 'Try and Error' journey. Webpack is originally designed for front-end packaging and works very well on that purpose. But for backend program like webbybot that feature is not important for us. Webpack also bring 'require' keyword to the front-end, but its not suit for backend program that depends on dynamic import. As a framework, hubot heavily counts on NODE require to load plugins. Webpack treat all 'require' as its keyword and try hard in vain to find external modules from packed files.

We tried several ways to detour these side effects, and finally replaced the full webpack stack with one line npm build script. Now its easier to debug and no hacks needed in source code.

3. return or not return, its the question

We use the "Try Coffeescript" utility provide form Coffeescript official site, which you can paste Coffeescript the page will convert the source to Javascript instantly.
The converted code is... not all pretty for human read, and all converted functions will contain a return statement even its unnecessary. It needs check by hand.

4. test cases matter

Hubot itself contains good coverage of unit tests. So we are able to test one ported script file with one ported test file when we start the porting. The unit test files contain great number of redundant return sentences when convert from coffeescript.

5. class and super

Hubot use Class syntax from Coffeescript。Thanksfully ES6 support the Class syntax, which is a bit different from Coffeescript. You can check how to use Class and super on MDN.

6. Default + rest + spread

Hubot contain several syntax like 'reply(strings...)'. The syntax 'strings...' in Coffeescript is correspondent to "...strings" in ES6(The order of '...' is reversed).
'...strings' denotes an array and I feel its a bit hard to figure out when to expand it or not.

7. for..of instead of for..in

To use for..in loop in ES6, we need add 'hasOwnProperty' check to make sure inherited property are not looped. Or we can rewrite for..in loop in Coffeescript to forEach iteration. Though there are some cases that need 'break' or 'return' from a loop.

Now we use ES6 for..of loop in Webbybot to replace forEach and for..in loop. You need wrap object with Object.keys syntax to iterate with object. ex: `for (let item of Object.keys(TargetObj)) {...}`.

8. Object.assign instead of Extend

We can use Object.assign to extend a object without handmade extend function or lodash!

9. Do you know hubot also support write plugin with plain javascript?

Learning how chat bot works is the main reason we start porting hubot to ES6!
A simple plain javascript plugin could be as easy as: (src/simple.js)

module.exports = function(robot) {
  robot.respond(/(hello)/i, function(res) {
    res.send('hi');
  });
}
You can put it in generated plugin folder and it will just work.


I've created a ticket on hubot issue list to start a discussion if hubot would like to go with ES6 in its future version.

The webbybot source is at https://github.com/gasolin/webbybot

Do you have a project ported from coffeescript to ES6? Welcome to drop by your thoughts.

» 將聊天機器人框架 hubot 從 Coffescript 移植到 ES6

Hubo


(English Version available here

用兩周多的時間,路路續續把原本用 Coffeescript 撰寫的 Hubot 聊天機器人框架移植成使用到 ES6 特性的純 Javascript 版本。

現在這個移植版本已經可供使用。移植後依然可以使用 Hubot 原來以 Coffeescript 撰寫的各種擴充套件(Plugins) 。

https://github.com/gasolin/webbybot

(目前的版本完全移植 Hubot 的功能,已開 Issue 詢問 Hubot 是否有興趣 merge 回去,在此之前先放在自己的 webbybot repo 裡)

移植的動機之一是為了了解整個聊天機器人框架,為後續可能的修改打基礎。
其二則是嘗試平常不常用到的ES6新特性。

過去 Coffeescript 和 Typescript 等最終編譯成 Javascript 執行的語言,都走在 Javascript 之前,提供了許多語法上的新特性。但在 2015 年 Javascript 開始的新發佈規劃(一年一版)下,ES6(ES2015)已將 Coffescript 眾多特性都收編了。且現在透過 Babel 可以將 ES6 編譯成現有的 Javascript 直譯器能讀懂的語法。在這樣的趨勢下,過去開發者想為這些新特性多學一套語言的誘因就不再存在了。

移植過程中採用的作法與遇到了一些坑,在此一一列出來。

1. 不用 grunt gulp, 直接使用 npm script

在 package.json 裡可以直接在 "script" 屬性中定義一些要執行的腳本,例如 webbybot 透過 "npm run build" 來將 ES6 轉換成 Javascript 直譯器能讀懂的語法。用 “npm run lint" 來做 style check。

2. 不用 webpack, 直接使用babel

移植之初決定使用 webpack 的 babel loader 來轉換 ES6,但這是一連串從「錯誤中學習」的開始。 webpack 支援使用 require 命令載入各種檔案,而且webpack 在轉換的過程中會將檔案打包成一份。但後端程式其實不太需要打包,而且 Hubot 作為一個框架,執行後從外部讀取 Plugin 是非常重要的功能。 使用 webpack 時,它會將程式中出現的 require 都視為它的 require,而嘗試從打包好的檔案中找到我們需要的外部 plugin,結果是徒勞的。當我們換用 npm script 直接呼叫 babel-cli 來打包,原來使用 webpack 時出現的諸多問題也都一併解決了。

3. 該不該 return

在移植的過程中常用到的工具是 Coffeescript 官網的 "Try Coffeescript" 分頁。可以即時將 Coffeescript 結果轉換成 Javascript。 但是真的把程式碼貼上去會發現, Coffeescript 所轉出來的 Javascript 所有的函式都會回傳值。需要手工一個個確認。

4. test cases

Hubot 本身有很完整的單元測試。所以每移植一支程式碼時,只要一併移植對應的單元測試,就可以捉對拿來直接測試。單元測試移植時出現最多該不該 return 的問題。

5. class and super

Hubot 使用了很多 Coffeescript 的 Class 語法。Class 與 super 的用法在 MDN 上可以找到相關教學。

6. Default + Rest + Spread

Hubot 程式碼裡常常會出現諸如 reply(strings...) 的語法。Coffeescript 裡的"strings..."可以對應到ES6 的 "...strings"(...放置位置剛好相反)。
"...strings" 代表的是一個陣列。在程式中有時要展開有時不用,其實頗令人苦惱。

7. 使用 for..of 替換 for.. in 迴圈

碰到 for..in 迴圈有幾種解法,最不會出錯的是將 Array iteration 改寫成 forEach。但是用 forEach ˇ的話無法在執行中使用 break/return 跳出是其缺點。其二是在 for..in 迴圈裡加入 hasOwnProperty 確認不會跑到無關的 function。
在 Webbybot 的第二版中已使用 ES6支援的 for..of 迴圈 來取代 forEach 和 for..in 迴圈。由於 for..of 迴圈只支援 iteratable ,不支援一般 Object,所以碰到要對 Object 跑迴圈時可以在 Object 外包一層 Object.keys,例如 `for (let item of Object.keys(TargetObj)) {...}`。

8. 使用 Object.assign 替換 Extend

要擴展一個物件的功能不用再用 lodash 或是自己寫 extend 函式,直接用 Object.assign 吧。


以上是移植過程中碰上的問題。感謝同事 Ray Lin 一起幫忙完成這次的移植。

現在 Webbybot (Hubot ES6 port) 整套都可以用 Javascript 寫了,歡迎試用或上 Patch 喔。

https://github.com/gasolin/webbybot

九月 28, 2010

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 使用 Google AJAX Libraries API 時,無法離線撰寫網頁程式?

在網頁程式中,我都是使用 Google AJAX Libraries API 來 host jquery 程式庫的,然而這麼作有一個缺點,如果你是在離線作程式設計時,要手動修改樣版,把 Google 來源的 js 檔改成從本機讀取,是有點麻煩,但致少作得到。

但若是將來在系統上線後,使用者上得了你寫的網頁系統,卻無法連至 www.google.com 呢? 那怎麼辦,雖然這個機率會滿低的,但也是有可能會發生在這個網頁系統屬公司內部系統,而對外連線卻被中斷的情況下。

別怕! 很簡單,下面就是一個範例,第 6、7、8 行改成本機 host 的檔即可。



1 <link rel="stylesheet" title="default" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/smoothness/jquery-ui.css"> 2 <script type="text/javascript" src="http://www.google.com/jsapi"></script>
3
4 <script type="text/javascript">
5 if (typeof google == 'undefined') {
6 document.write(unescape('%3Cscript src="/localmedia/jquery-1.4.min.js" type="text/javascript"%3E%3C/script%3E'));
7 document.write(unescape('%3Cscript src="/localmedia/jquery-ui-1.7.2.custom.min.js" type="text/javascript"%3E%3C/script%3E'));
8 document.write(unescape('%3Clink type="text/css" href="/localmedia/smoothness/jquery-ui-1.7.2.custom.css" /%3E'));
9 } else {
10 google.load("jquery", "1.4.0");
11 google.load("jqueryui", "1.7.2");
12 }
13 </script>


延伸閱讀: Using CDN Hosted jQuery with a Local Fall-back Copy

七月 14, 2010

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 3+2 = 5 碼郵遞區號查詢離線網頁程式(已放上 Google Code)

當我開始開發資訊系統時,就一直認為地址處理是一般資訊系統中最基本且常見的功能。不過,目前使用過的資訊系統,了不起就是把 3 碼郵遞區號作完而已,很少看到網頁系統有作到無碼 5 碼的地址處理功能(當然啦,郵局自家的確有提供 5 碼查詢功能,但是不好用)。所以我想郵局苦心推動大家使用 5 碼,除了能讓寄信速度加快外,未來在許多 GIS 應用愈來愈普及下,我相信大家都會利用 5 碼郵遞區號來作加值應用的。

所以為了搔自己的癢,我寫了 http://zipcode.ho600.com/ 網站,除了可作網上查詢 5 碼功能外,也把 HTML5 的 Offline 作進去,讓查詢功能可在無網路的本機端處理。另外也提供其他人嵌入「地址查詢表單」的方法。詳細說明請見「嵌入方法」,本專案我也放到 Google Code 開發,授權條款是 NEW BSD License ,希望能聽到您們的聲音。

這個程式是跑在 GAE 上的,不過可以很容易地移稙到其他框架中,因為這個功能,我主要是用 javascript 開發的。 GAE 不過提供檔案放置的功能。

注意,第一次瀏覽會比較慢,因為要把約 2MB 的郵遞區號資訊下載下來。不過,如果你用的是支援 html5 offline 功能的瀏覽器,像 Firefox3.6+, chrome4+, safari4+ 的話,之後就不用再下載了。

範例:

二月 23, 2010
» 'hello world' ab tests between pylons 0.9.7 and node.js v0.1.30

A rough play, just for fun.

pylons code:

class HelloController(BaseController):

    def index(self):
        return 'Hello World'


Configuration of prod.ini:

debug = false
...
set debug = false

run with:
paster serve prod.ini

node.js code:

var sys = require('sys'),
   http = require('http');

http.createServer(function (req, res) {
    res.writeHeader(200, {'Content-Type': 'text/plain'});
    res.write('Hello World');
    res.close();
}).listen(8000);

sys.puts('Server running at http://0.0.0.0:8000/');

//(filename: serv.js)

run with:
node serv.js
Result of Pylons:

 % ab -kc 10 -t 10 http://192.168.7.77:8000/

Benchmarking 192.168.7.77 (be patient)
Completed 5000 requests
Finished 6325 requests


Server Software:        PasteWSGIServer/0.5
Server Hostname:        192.168.7.77
Server Port:            8000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   10.094 seconds
Complete requests:      6325
Failed requests:        0
Write errors:           0
Keep-Alive requests:    0
Total transferred:      1341099 bytes
HTML transferred:       69575 bytes
Requests per second:    632.49 [#/sec] (mean)
Time per request:       15.810 [ms] (mean)
Time per request:       1.581 [ms] (mean, across all concurrent requests)
Transfer rate:          130.90 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  84.2      0    2997
Processing:     2   12  22.1     10     644
Waiting:        1   10  22.0      8     640
Total:          2   15  90.4     10    3639

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     12
  75%     12
  80%     13
  90%     15
  95%     17
  98%     22
  99%     47
 100%   3639 (longest request)


Resulf of node.js:

% ab -kc 10 -t 10 http://192.168.7.77:8000/

Benchmarking 192.168.7.77 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Finished 50000 requests


Server Software:       
Server Hostname:        192.168.7.77
Server Port:            8000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   6.185093 seconds
Complete requests:      50000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    0
Total transferred:      3750000 bytes
HTML transferred:       550000 bytes
Requests per second:    8083.95 [#/sec] (mean)
Time per request:       1.237 [ms] (mean)
Time per request:       0.124 [ms] (mean, across all concurrent requests)
Transfer rate:          592.07 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     0    0   3.5      0      81
Waiting:        0    0   3.5      0      80
Total:          0    0   3.5      0      81

Percentage of the requests served within a certain time (ms)
  50%      0
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      2
 100%     81 (longest request)

十二月 15, 2009
» 微軟中國模仿噗浪

關鍵字遊戲:微軟,中國,模仿,噗浪。

"Imitation may be the sincerest form of flattery, but blatant theft of code, design, and UI elements is just not cool, especially when the infringing party is the biggest software company in the world." ~ Microsoft China rips off Plurk@amix.dk

我對這段話的翻譯:

「模仿可能是最真誠的奉承形式,然而明目張膽的瓢竊程式碼、設計及使用者介面元素,這一點也不酷,特別是當侵害的一方是世界上最大的軟體公司。」

不禁想到一句:「勢者,因利而制權也。」真好奇他們伺服器端是不是也要來搞 Python + Tokyo Cabinet

其它參考:

  • 微軟中國推出「山寨版」的Plurk噗浪-MSN聚酷
  • Plurk 聲明的中文版
  • MSN聚酷上的服務使用條款連結
    10. 軟體

    如果您在我們的服務過程中收到軟體,則必須在接受使用權條款下才能使用該軟體。若沒有使用權條款或除非本合約另有說明,則只能在您的服務商品所述的一定數量的電腦所授權使用的服務上,使用該軟體。我們保留軟體的其他所有權利。

    我們可以自動檢查您的軟體版本。我們可以將軟體升級自動下載到您的電腦,執行更新、加強功能及進一步開發服務。

    除非我們另行通知,否則軟體的使用權限會在服務結束日期終止,您必須立即解除安裝軟體。在服務結束日期後,我們會停用軟體。

    您不能對服務所包含的任何軟體反組譯、反編譯或反向工程,除非 (也僅限) 法律明確允許此類活動。

    此軟體受美國輸出法令及法規約制。您必須遵守軟體所適用的所有國內和國際輸出法和法規。這些法律包括目的地、終端用戶和最終使用的限制。若需其他資訊,請參閱 http://www.microsoft.com/exporting (英文網頁)。

    若您使用軟體存取受到 Microsoft 數位版權管理 (DRM) 保護的內容,為了讓您能播放此內容,軟體可能會自動在網際網路上向版權伺服器要求媒體使用權,並下載安裝可用的 DRM 更新。如需相關資訊,請參閱 http://go.microsoft.com/fwlink/?LinkId=123883

  • Evil-smelling 的同義字

七月 28, 2009
» IBM 教學

五月 31, 2007
» Google gears !

今天進 google reader的時候發現右上角多了幾個字: offline

好奇的按下去之後發現 google reader已經引進了
google的離線儲存新技術: google gears.

也就是說安裝之後,
google reader瞬間變成離線也能閱讀的RSS瀏覽器了 !
看來離線的gmail也不遠了...

以技術面來說google gears
以new bsd license放出,是完完全全的自由軟體.
支援Windows/Mac/Linux ,
並且支援IE/Firefox/Safari(未來將會支援,目前在mac上支援firefox)
等於所有主流系統全部支援.

google gears除了離線存取現有的web application之外,
還提供了一個WorkerPool的API幫助programmer將資源吃重的一部份程式以非同步方式存取,
並且還內建輕量級資料庫sqlite 支援使用javascript撰寫sql
(沒錯... 就是像下面這樣
var rs = db.execute('SELECT dish FROM recipe WHERE recipe MATCH ?', ['tomatoes']);
)
之前雖然也有如dojo storage之類的解決方案.但總不如早已習慣的rdbms來的方便. google幹的好啊!

google gears目前雖然仍是beta中,
但解決了web application離線存取這個麻煩的問題,
由於是完完全全的自由軟體(允許商業使用)
在未來有機會成為業界的新標準.

更多詳細的資訊請參考:

http://code.google.com/apis/gears/index.html
http://gears.google.com/

五月 5, 2007
» [link] 誰說只有wiki可以這樣搞.....orz

pure html+js ... 越來越有趣了 :P

Terminal

Home

Blog

biggo.com.tw

A Django site.