Skip to main content

· 4 min read

前幾天 Facebook 開放上傳 360 影片,經過幾番嘗試後,終於找出直接在手機上直接上傳 360 照片的方法。

剛嘗試的人建議使用 Google Street ViewCardboard Camera 試試效果,這兩個 App 可以在 Android 或 iOS 應用商店中找到。

透過這兩個 App 拍攝的 360 影片,直接上傳到 Facebook 應該是沒問題的。

但現在有更方便的 360 影片拍攝工具如 Ricoh Theta S 或是 LG 360 CAM,這類設備搭載兩個鏡頭,拍攝時只要按一下拍攝鈕,就輕鬆完成全景照片。

使用全景相機拍攝 360 照片或影片 有的設備如 LG 360 CAM,目前 Facebook 還無法辨認(更新:現直接上傳 360 照片已經可以正確辨認),所以只能用一些繞過的方法。朋友傳來這篇教學文章。根據這篇文章的說明,我做了些嘗試與改進,並最終成功透過手機上傳 360 照片。

  1. 首先準備一張 360 照片 (我用的是 LG 360 CAM)

  1. 接著從應用商店取得可以編輯照片 Exif 資訊的應用。我選的是免費的 Photo Exif editor。
  2. 從照片 (Gallery, Photo) App 預覽到想要修改的 360 照片,選擇分享(Share)到 Photo Exif editor。  4. 照著修改 以下欄位的值:
Camera maker: **Ricoh **(首字母大寫)**
**
Camera model: **RICOH THETA S**** **(全大寫)

5. 最後再透過相片軟體選擇分享到 Facebook 即可。如果成功,可以看到相片下角出現球狀 360 影片圖示。

我的觀察啦,360 相機使用上相當方便,按一下拍攝鈕啟動相機,再按一下就拍張照。長按就開始拍攝影片。

拍照時只要把相機往上平舉,就整個環境都拍到了(一個小技巧:拍攝時將相機舉在頭上就不會拍到自己),不需要什麼特別的攝影技巧。這對只是想分享當下體驗的我相當適合。這種特性也很適合團體拍照。這樣方便的新品,加上 Facebook 這樣容易分享相片的環境,相信很快 360 相機就會流行起來。   目前拍 360 相片時,附近的人其實並沒有意識到我在幹什麼,但其實附近的人也是全部入鏡的。使用 360 相機時要如何兼顧隱私的保護也會是一個議題。

· 2 min read

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.

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/

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):
... 2: Linux 3.8 GB disk2s2

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

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

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

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**

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!

· 4 min read

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.

· 6 min read

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

· 2 min read

前陣子在 Medium 上看到 Tor Bair 寫的 Your Life is Tetris, Stop playing it like Chess, 談到作者認為俄羅斯方塊比起棋局更接近人生。

棋局是種非贏即輸的零和遊戲,而俄羅斯方塊則是不斷重複,幾乎不可能獲得最終勝利的遊戲。

作者的論點如下:

1. 人生中你唯一的對手是你自己

真實的人生遊戲是內化的,而不是靠向外找尋對手或打敗大魔王來獲取積分。

2. 人生中,事情不會變得更難,只會變得更快

3. 人生中,你無法控制接下來會發生什麼

你只知道下一個拿到的方塊是什麼,你只能活在當下,試著組織起最好的結果。

4. 人生中,沒有人告訴你什麼時候你贏了

不是為了贏而遊戲,而是為了樂趣而遊戲。

"人生如俄羅斯方塊",實在是很有趣的人生觀阿!