2017年12月28日 星期四

WeChat 瀏覽器檢測

最近想把一個 Facebook 項目同時放到 WeChat 內執行,但流程上會作出改變,需要一個方法去分辨是否在 WeChat 瀏覽器之內。原來可以從 User Agent 入手:
//----------------------------------------------------------------------------------------
//  Reading parameters
$userAgent = $_SERVER["HTTP_USER_AGENT"];
$userAgent = strtolower($userAgent);

if (strpos($userAgent, "micromessenger") !== false)  {

   $html = file_get_contents("./views/_inside.html");
   echo($html);
   exit(0);
}

$html = file_get_contents("./views/_outside.html");
echo($html);

2017年12月23日 星期六

聖誕小禮物


上年的聖誕節推出了絲帶版可口可樂,我買了回來作為小禮物送給 IT Team 同事,借此多謝他們過去一年的付出。雖然只是一瓶汽水,不是貴重的禮物,卻是我小小的心意。

今年我想感謝的人多了,而且不限於 IT Team 的同事。知道有些同事注重健康不喝汽水,改為冰糖雪梨,可以在這乾燥的時候帶來小小的滋潤;有同事想品嘗日本版芝士杯麵,給我找到了;至於咖啡,那位同事最近心事重重,希望咖啡可以為她提提神。

本來我想為每位同事都獨立繪畫一張心意卡,但畫了一位後畫不出第二位,最後偷懶只畫一張共通的圖案。希望下年有機會吧,不過下年應該會有再多一點同事希望感謝。大家收到小禮物後都很開心;有同事甚至珍而重之把它過膠紀念。喜悅是可以感染,希望大家有一個快樂的聖誕節。

2017年12月16日 星期六

Inspirational Fimmicker Award 2017


昨天是公司舉行 Annual General Meeting 的日子。今年設立了一個名為「Inspirational Fimmicker」的獎項,去表揚過去一年值得嘉許的同事。好開心得到這個獎。

2017 年對我來說是一個艱苦的年頭。艱苦不在體力上,而是感情上。試過很開心、也試過很唔開心。試過逃避、想過放棄。試過把不開心的事放得很大很大,個天似要塌下來。無論這個世界不似預期,也不要放棄,只要看看身邊,總會有支持自己的人,總找到值得快樂的事。我很喜歡太極圖案,黑暗中總帶一點光明。如果你正在人生低潮,請不要放棄,總會找到出路。我撐得過,你們都撐得過。

好多謝組員在我情緒不安時能做好工作,不用我擔心。好多謝 Matthew 主動關心,讓我好快重拾正面的力量。好多謝 Clare 找我談天,我藉此得到減壓。

我聽過一句很有意思的說話:「當學生準備好,老師就會出現」。意思是,當自己準備好突破時,困難會自然出現;當自己準備好被愛時,愛人會自然出現。2018 年將會是充滿機遇及挑戰的一年,我很希望跟各位同事並肩作戰,衝出香港,面向亞洲。

2017年12月10日 星期日

MIST


最近買了一本「寫給未來社會的新帳本・區塊鏈」書,知道了有一個叫 Ethereum 的以太坊平台,能讓開發者提供以太坊應用程式去賺取以太幣。當使用以太坊應用程式時就需要用到以太幣。Ether 以太幣就像 Bitcoin 比特幣一樣,同樣應用了 Blockchain 技術的加密貨幣;價格也有升有跌。而使用以太坊應用程式時,需要使用一個名為 MIST 的瀏覽器去執行。不過,我認為目前使用的門檻較高。用戶除了要對以太坊有一定概念外,還需要安裝 MIST,建立以太幣錢包,購買以太幣。如果像我般不懂得設定 MIST 瀏覽器,還會把整條以太坊的區塊鏈下載回來,動輒花去數小時至數天時間,視乎電腦的效能而定。不過,我認為以太坊是一個很有潛力的平台。

2017年12月3日 星期日

模擬 iPhone 8 Plus 視差濾鏡效果


同事生日,另一位同事拿出 iPhone 8 Plus 展示了視差濾鏡效果,感覺不錯。很想買一台。但我喜歡 iPhone 8 多過 Plus,就算買也只會是細機,而細機是沒有雙鏡頭,拍不出帶視差數據的照片。我在想,Apple 的濾鏡也只是軟件,能不能在 iPhone 7 Plus 上編寫而達到相同效果呢?結果是可行。

2017年11月29日 星期三

IN117 Team Song


詞:Pacess, Johnson, Mandy

想起那天一同前行 全力一拼衝極限
意識到我唯有去愛 才令世上添新機
交出我心方能完全 朝著我路總未倦
理想方向全力去拼 終可會得到

願為理想 全力去幹不怨命
若遇挫時 仍然毫無懼與驚
若沒跌到 其實也已肯定
若犯錯時 容我 Break Through 再起
能時常懷自信 令你令我添力量
有勇氣創高峰 跨過千百山嶺
讓昨日無數夢 能一一的得到
我發亮尤如耀晚星

想起那天一同前行 全力一拼衝極限
意識到我唯有去愛 才令世上添新機
交出我心方能完全 朝著我路總未倦
理想方向全力去拼 終可會得到

為著理想 誰亦要去起革命
若遇挫時 仍然毫無懼與驚
為著理想 寒夜裡也不間斷
若犯錯時 容我 Let Go 說清
能時常懷自信 令你令我添力量
有勇氣創高峰 跨過千百山嶺
讓昨日無數夢 能一一的得到
我發亮尤如耀晚星

想起那天一同前行 全力一拼衝極限
意識到我唯有去愛 才令世上添新機
交出我心方能完全 朝著我路總未倦
理想方向全力去拼 終可會得到
<Repeat Twice>

停望障礙 忘記過去 終可會衝線

2017年11月26日 星期日

相信自己,隨心出發


應承了同事在十一月內完成某個功能,這兩天努力趕工,但還是徒勞。進度行慢,很多部份都不似預期,很有壓力、很想放棄。承諾了就要做到,但思想混亂,程式更易出錯。怎麼好?畫了一張畫鼓勵自己:「相信自己,隨心出發」。

2017年11月23日 星期四

支持你


這兩天悶悶不樂,有點情緒,想抓點抒發的渠道,於是用畫作來達成。在午飯時間隨手畫了四個公仔,我最喜歡這張。神態鬆容自然,好像有個少女在背後默默支持自己一樣。公仔的造型是一位我很著緊的同事,同時也是為她而繪,希望能支持到她的心靈。

2017年11月19日 星期日

IN117


IN117,誠信網絡 Integrity Network 第 117 班。轉眼間已經畢業了十八個年頭。今日再次相聚,大家繼續成為領袖,生活也有很多轉變。Buddy 的孩子,由當初的小朋友變得婷婷玉立、有的 Buddy 成家立室、有的將近退休、有的已經成為導師。IN117 出產的導師應該是歷屆 IN 之冠。

很懷念當日的衝刺,也懷念自己在 IN 期間的創作。人生第一首 Team Song 歌詞、第一個團體標誌設計、第一輯海報設計、第一套 Team 衫設計。當時我更準備多一套作為紀念。再一次多謝各位 Buddy 的支持。沒有你們,沒有我今日的成就。I am proud of IN117.

2017年11月13日 星期一

在 AR Studio 用腳本播放音效


舊同事在 Facebook 求救,想知道怎樣在 AR Studio 內用腳本播放音效。這個我沒有試過,也想學習一下,於是查看 Facebook 的說明文件。翻來找去,還是不清楚要如何播放音效。示範程式也沒有相關的內容。教學影片又只叫人看文檔。在沒有任何資源下,只好不斷嘗試。AudioSource 沒有屬性及函數,所以不是直接呼叫。而它是基於 Scene 的,所以要從 Scene 著手。找到原來要用 Audio.play(Scene.root.child('audiosource0')); 就會成功。

2017年11月10日 星期五

Robi 技術研究・五


要開發編輯器,得先讓程式讀懂 RM4 檔案內容,變成一個個物件,方便重新組合及排列。

於是,我著手解析 RM4 內的結構,自行編寫匯入程式;可是,這不是件容易的工作,有很多不同的處理。像是如 medit 般有開始的標籤,也有完結的標籤;像 return 是一句都尾;像 block 是有很多不同的參數;要準確讀取,得下很多功夫。於是我在想,PHP 應該有現成的功能去處理自訂 XML,結果找到 xml_parse_into_struct()。

我把 RM4 內容直接拋給 xml_parse_into_struct(),結果只有第一個 medit 發其內在句子能解讀成功。估計是因為程序把 XML 內第一個標籤當為根,當同一個標籤完結時,程序便會結束。於是的為 RM4 內容外圍包一層 <robi></robi>,結果能解讀出更多內容。不過,還算不上是成功;因為結果中出現很多不知明的部份,而程序也只能解讀到包含日文字參數為止;即是上圖中的「立ち状態?」。研究過後,那些不知明的部份是用 \r\n 引發,於是利用 str_replace() 把它們清除。至於日文字參數方面,則用 mb_convert_encoding() 把原本為 Shift-JIS 的日文編碼轉換為 UTF-8 無國籍碼,問題便得到解決。可是,還是遇到新的問題,程序還未能完整解讀 RM4 內容。追查之下,發現有參數的數值內容包含 << 及 >>,導致 XML 解讀失敗。今次我同樣用 str_replace() 把它們清除。最後,能成功解讀了。

2017年11月9日 星期四

先相信後成真


最近聽到同事的一個回應是「人地做到,我都做到」。不約而同,前拍檔也有跟我這麼說。回顧一下,我是有說這番話,但次數應該不多;為何大家都有相同的感覺?當然,我心底裡一直有這股信念。

兒童時代,不可上街,只能留在家中拼砌樂高積木,砌得膩了,便嘗試模仿、嘗試修改、嘗試創造。建立了只要肯研究,別人能做的事情,我也能做的信念。複製是我的強項,創造也不弱。很多時候,只要有參考,便能造出差不多的東西。學習多了、技術累積了,造出來的東西更加專業。人就應該要不斷學習、不斷成長、不斷進步。突破了界限後,事情變得一般,可以再找新挑戰。

有時,不要小看自己,有信念便能突破難關。我跟一位很夾的同事都有著相同的信念:「先相信後成真」。

2017年11月8日 星期三

Robi 技術研究・四


Robi 的資源及程式都存放在 SD 卡內。香港版內置的 SD 卡有 4GB 容量,但程式連內容則只有約 612MB。當中仍然保留了很多日語音效,相信是沒有使用。單單聆聽日語語音檔,回答「係」這個音,起碼有十款不同的錄音,有長有短、有神氣的、有淘氣的、有消沉的。意味著原來日本版有很多細緻的地方,在香港版都刪除掉,變得很基本。既聲音檔案然沒有用,又沒有拿走檔案;雖然騰出的空間也沒有用處,但感覺十分馬虎。


朋友問 Robi 內置了多少首歌。查看 /voice/Music 目錄,發現有五首歌。當中只有 osouji.wav 及 timer.wav 是廣東話,其他都是日文歌。除此之外,日本版 SD 卡分為三個版本:Robi Heart, Robi Heart 2, Robi Heart 2DX。最後一個版本於 2016 年中推出,賣 9800yen 再加稅,裡面共有六首歌及多了幾支舞。不過,香港只有第一代版本。

朋友又問:「可否自行加入歌曲?」。原本 Robi 沒有這個設計,不過有日本用家把 Robi 的 XML 程式修改,使得能自行加入;但由於沒能加入更多聲控指令,歌曲一是取代原本的,又或者是修改程式,變成隨機出現。我相信還有其他可行性,正在研究編寫網頁版修改程式;畢竟目前只有 Windows 版本,我全家是 Mac 機,要用模擬器才能使用。以下網頁有詳細的 XML 編碼解說:

週刊ロビ 増刊71号:ロビのココロを探る1
週刊ロビ 増刊72号:ロビのココロを探る2
週刊ロビ 増刊73号:ロビのココロを探る3
週刊ロビ 増刊74号:ロビのココロを探る4

2017年11月7日 星期二

把圖片設定為 360 格式

同事為我慶祝生日,我們用了一台 360 影相機拍照。照片經過 WhatsApp 傳送後變成普通相片,上傳到 Facebook 也無法變回 360 照片。這是因為相片中的 360 Metadata 消失了。解決方法是到 https://www.sno.phy.queensu.ca/~phil/exiftool/index.html 下載 ExifTool;它支援 Mac, Windows, Linux。用它補回 Metadata,指令如下:

exiftool -ProjectionType="equirectangular" birthday.jpeg

2017年11月6日 星期一

Robi 技術研究・三


要把 Robi 改造成遙控版本,需要東芝 FlashAir W-03 或 W-04。在觀塘樓上舖找到了東芝 FlashAir W-04 版本,售價為 HK$268。與觀塘廣場的 W-03 32GB 版本相差 HK$18,但無線傳送速度由 10.8Mbps 提升到 31.4Mbps、支援 Eyefi Connected。花這 HK$18 很值得。



把 FlashAir 插進 MacBook Pro,看到初設的檔案結構是:


跟 W-03 的檔案結構相比,少了 /GUPIXINF 目錄。我先把 /SD_WLAN/CONFIG 拷貝一份為 CONFIG_ORIGINAL 以作不時之需。然後在 iPhone 上安裝 FlashAir 應用程式。連上 flashair_xxxxxxxx 的 WiFi 後,在應用程式內進行設定,如:修改 SSID 名稱及 Mastercode。


起初設定 Master Code 時出現錯誤,後來發現 Code 的長度一定要為 12 字符:


回到 FlashAir 的 /SD_WLAN 目錄,比較一下原廠設置,多了數行。而我們需要手動加入 WEBDAV=2 及 UPLOAD=1:

這樣便能遙距對 FlashAir 進行讀寫動作。

最後,我在 iPhone 上看一看連線內容。IP 地址是 192.168.0.x:

2017年11月5日 星期日

Robi 技術研究・二


其中一項改造,是把原本聲控的 Robi 改為遙控。目前最方便的做法是使用支援 WEBDAV 的 Toshiba FlashAir W-03 或 W-04。今日在觀塘廣場見到 W-03 版本,16GB 要 HK$208,32GB 要 HK$250。另外,在網上找到香港也有 W-04 版本出售,32GB 約 HK$268。

只要為 Robi 加入 MicroSD 轉 SD 卡接線,將 Robi Heart SD 卡內的檔案拷到 FlashAir,配合修改過的程式檔及 HTML 控制介面,插入 FlashAir 便能以電腦或手機控制。我在收集有關資料及購買所需零件,成功後會分享出來。至於 FlashAir 相關資料要參考日文版網頁 https://flashair-developers.com/ja/discover/overview/w04/,因為最新的資料在日文版,其次是英文版。這張 FlashAir 除了是一張帶有連線能力的 SD 卡外,還支援 Lua 編程及 GPIO 控制,對於改造 Robi 來說有更大的想像空間。

2017年11月4日 星期六

Robi 技術研究


砌好了 Robi,試了幾個動作指令:Balance game、sit up、唱歌、跳舞...等,同事看得很開心,甚至覺得能做出平衡動作是很驚訝的事情;而我,則想 Robi 做得更多;於是著手研究它的構造。

網上有很多關於 Robi 的資料。我是先讀 Robi 技能強化,然後再讀 うちのロビ&ロボホンROBOMICコンピュータ制御システム ロビ/ロボゼロ編。上圖是 Robi 附帶的日本版 SD 卡內容。香港版及台灣版在動作上有不同,語音也不同。原來 Robi 在啟動時,會載入 STARTUP.XML:

主要是設定 Robi 名稱「deago4」,那段 0x64,0x65,0x61,0x67,0x6f,0x34 就是「deago4」的 ASCII 碼。然後設定音量、伺服機的參數及 LED 顏色。如要修改音量,可把 <mem_w size="2" adr="0x0046">0x0000</mem_w> 中的 0x0000 最大,改為 0x0001 大、0x0002 中、0x0003 小。在 STARTUP.XML 最後一句是跳到「main5_InitFlag確認補完無し_シーン1固定0415_test2.RM4」動作設定檔。

2017年11月2日 星期四

香港粵語版 Robi 初起動問題


花了接近兩個星期的拼砌,終於完成了 Robi 組合工作,可以首次正式啟動。


啟動後是設定程序,用以設定 Robi 的性格。可是無論我怎樣回答「係」還是「唔係」,Robi 都沒有反應。以為是咪高峰裝得不好,於是拆開頭部及身體,重新接合電線;可是結果一樣。後來在 YouTube 發現台灣也有相同遭遇的用家,原來回答「係」,需要接著說「Robi」。我太心急沒有看清楚說明書。這樣回答後,Robi 也成功設定好,可以直接聲音操作。

2017年10月31日 星期二

AR Studio 萬聖節效果


約莫在八月中左右,曾向 Facebook 申請成為 AR Studio 的封測人員,可是等了一個月也沒有迴音,事件也不了了知。個多星期前,另一位同事再次通知我 AR Studio,於是我再次申請。跟上次一樣,分別用了公司及個人電郵申請,今次竟能以個人電郵成功申請。得到許可後,立即用相關的 Facebook 帳號登入試玩。看過簡單的影片教學,我很輕易地載入自己的素材,同時能下載到 iPhone 版的 AR Studio Player,方便隨時在手機上測試。

今日在 Facebook 見到同事把初生女兒的影片配上萬聖節 Camera Effect,心血來潮想製作一個屬於自己的版本。即時在網上找了回素材,拼拼揍揍地製成了「萬聖節」版本,雖然只用到平面貼圖,沒有用上立體模型及粒子處理,但出來效果不錯!

2017年10月19日 星期四

最終買了 Robi


Robi 日本版推出時,已經很想訂購;到香港中文版,差一點衝動就買;畢竟 70 期 Robi 都接近一萬港元,在還有其他引誘之下,拿出來有點吃力。到後來有朋友以 HK$8000 全套放售,還是沒有行動。

直到一星期前在 Carousell 見到有人以 HK$4000 全新一套連鬧鐘及椅子放售,加上生日將至,有一個籍口給我去衝動,最終買了 Robi 下來。為免內子得知花費甚巨,我急急地把 70 期 Robi 帶回公司,好在老闆還挺支持員工把公司當作家一樣。明天開始,我會早一小時回公司,利用早上及午飯時間,把 Robi 組合出來。

2017年10月17日 星期二

修理 Canon 打印機錯位問題


家裡的打印機出了狀況,每逢要打印黑色的地方都會移位,導致列印內容錯誤。打印機用了不到一年,內子嚷著要換台新,我雖然覺得浪廢,但文件還是要印,只好買台新的,但買之前還是要挑選一下。今晚心血來潮,反正都打算由噴墨換成雷射列印,那倒不如把目前的 Canon 打印機拆解一下,修得好可以省回千多元,修不好也沒壞,於是動手開工。

回憶當初打印機開始出狀況是因為食紙問題,打紙張拉出來時用力過度,打印機之後便出現移位問題。用電筒東照西照,發現打印頭後方有一條淡灰色的膠帶;細看之下,那不是灰色,而是一條條黑色幼線垂直排列。我拆過三四台打印機,見過類似的東西,通常是圓盤形狀的膠片;在開發機械人時,也遇過類似的東西;那些黑線是用來定位,讓機器知道自己跑了多遠。再看清楚一點,膠帶上有很多污漬,相信是食紙時弄污。直覺話我知列印移位是因為定位錯誤,於是我拆開打印機,把膠帶清潔一下。裝回原狀,試試打印,成功了!

本來要花 HK$1200 左右買台新打印機,現在可以省下。真開心!地球伯伯病重,能修的應該修理好繼續用,不能修的才扔。資源不是永恆,要懂得珍惜。

2017年9月24日 星期日

ChatBot 解碼專家


寶寶最近給我一條網址 http://www.clarins-decoder.com/chat/doubleserum17/webserver/index.php。她在玩這個 ChatBot 時,分別用了中文及英文回覆;而 ChatBot 都好像理解箇中內容,便詢問我這個 ChatBot 是不是用了 Machine Learning 之類的技術,以及有沒有能力開發。於是我花了點時間研究一下。

首先,這個不是真正的 ChatBot,而是一個網頁。只是介面偽裝成 ChatBot 的模樣。看看溝通時的對話,ChatBot 明顯詢問是非題;而問題是經過設計,帶引導性;所以我認為不需要使用 Machine Learning 技術,單憑關鍵字已經做到不錯的效果。再利用 Chrome 的 Network 監視器,發現所有對白都有語音,並分別放在三個音效檔:voice_over9.mp3, voice_over_respA3.mp3 及 voice_over_respB3.mp3。證明了對白早已決定,當程序找到正向關鍵字時便播放正向組對白;當找到負向關鍵字時便播放負向組對白;當不理解時便播圓場對白。所以,要編寫這個 ChatBot 是很容易的,反而設計問題才是關鍵所在。

2017年9月21日 星期四

SnowNLP 載入自行訓練的模型


明天打算向同事說明一下最近關於 NLP 的成果,於是寫了一個簡單的 Python 程序去看看原生模型及自行訓練模型的差異。要載入模型,除了直接在 site-packages 內塞入 marshal 檔案外,還可以調用 load() 指令來載入;對於要更換模型的程式來說,這個設計十分方便。

2017年9月16日 星期六

使用 Python 的 reshape 功能


最近安裝了 Jupyter;因版本不同,用 scikit-learn 做預測時會出現「DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19」錯誤,需要 reshape 後才行。

2017年9月12日 星期二

在 Ubuntu 14.04 安裝 SMB 服務器

之前為了重置 Nvidia Jetson TK1,找了一台舊的 PC 並安裝了 Ubuntu 14.04;之後沒有特別用途。今日安裝了 Jupyter 進去,希望能隨時執行 Python 指令。同時也安裝了常用的程序庫,如:OpenCV, Ski-learn, Pandas, Jieba,...等。我把上年寫好的認臉程序放進去,利用 OpenCV 3 來收集同事的面部資料,並儲存成 PNG 圖像檔案。一下子收集了過千個檔案,為方便篩選,我安裝了 SMB 服務器,步驟如下:

  • sudo apt-get update
  • sudo apt-get install samba
  • sudo smbpasswd -a ubuntu-user
  • sudo nano /etc/samba/smb.conf
       [Home]
       path = /home/ubuntu-user
       read only = no
       guest ok = no
  • sudo service smbd restart
     
    由於 SMB 有自己一套的登入帳戶,所以上面要另外建立 ubuntu-user。
  • 2017年8月15日 星期二

    用 Gmail API 讀取 Label 清單

    平時的工作中,經常都會在伺服器中加入電郵通知,當有任何值得留意的狀況發生時,我會收到電郵說明內容;因為這樣能比較主動地帶出重要的資訊。然而,很多時候像運行記錄之類的電郵通知都沒有保留在伺服器,電郵一經發出,數據便不再存在。如果拿來作為數據分析或繪畫圖表,相信會有一點啟示。由於公司是使用 Gmail 系統,要做到這點,可以用 Gmail API。

    我習慣用 Label 來把電郵分門別類;所以要達到以上目的,我得先取得 Label 的清單。以下是我的代碼:
    <?php
    //----------------------------------------------------------------------------------------
    //  Gmail API DEMO
    //----------------------------------------------------------------------------------------
    //  Platform: macOS + PHP + Apache
    //  Written by Pacess HO
    //  Copyright 2017 Pacess Studio.  All rights reserved.
    //----------------------------------------------------------------------------------------
    
    header("Access-Control-Allow-Origin: https://www.pacess.com");
    header("Access-Control-Allow-Methods: POST");
    header("Content-type: text/html");
    header("Cache-Control: no-cache, must-revalidate");
    header("Expires: Tue, 10 Mar 1987 00:00:00 GMT");
    
    date_default_timezone_set("Asia/Hong_Kong");
    mb_internal_encoding("UTF-8");
    ini_set("memory_limit", "-1");
    ini_set("default_socket_timeout", 10);
    set_time_limit(0);
    
    session_start();
    
    //----------------------------------------------------------------------------------------
    //  * Order is important
    require_once "./libraries/vendor/autoload.php";
    
    //----------------------------------------------------------------------------------------
    //  Global variables
    $_apiName = baseName(__FILE__);
    
    //----------------------------------------------------------------------------------------
    //  Check if logout
    if (isset($_REQUEST["logout"]))  {
     unset($_SESSION["access_token"]);
     exit(0);
    }
    
    //----------------------------------------------------------------------------------------
    //  Check if code provided for authentication
    $client = new Google_Client();
    $client->setAuthConfig("./client_secret.json");
    $client->addScope("https://mail.google.com/");
    $client->setRedirectUri("https://www.pacess.com/gmailGrabber");
    if (isset($_REQUEST["code"]))  {
    
     $client->authenticate($_REQUEST["code"]);
     $_SESSION["access_token"] = $client->getAccessToken();
    
     $auth_url = "https://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"];
     header("Location: ".filter_var($auth_url, FILTER_SANITIZE_URL));
     exit(0);
    }
    
    //----------------------------------------------------------------------------------------
    //  Check if access token created
    if (isset($_SESSION["access_token"]))  {
     $client->setAccessToken($_SESSION["access_token"]);
    }  else  {
    
     //  Not yet
     $auth_url = $client->createAuthUrl();
     header("Location: ".filter_var($auth_url, FILTER_SANITIZE_URL));
     exit(0);
    }
    
    //----------------------------------------------------------------------------------------
    //  Create Google service
    $service = new Google_Service_Gmail($client);
    
    //----------------------------------------------------------------------------------------
    //  OK, everything is ready!
    try  {
     if (!$client->getAccessToken())  {
      echo("Something happened...");
      exit(0);
     }
    
     $accessToken = $client->getAccessToken();  
     echo("Access token: ".print_r($accessToken, true)."<hr>");
    
     $labelsResponse = $service->users_labels->listUsersLabels("me");
     if ($labelsResponse->getLabels()) {
      $labels = $labelsResponse->getLabels();
      foreach ($labels as $label) {
       var_dump($label);
       echo("<hr>");
      }
     }
    }  catch (Google_Auth_Exception $e)  {
     echo("### Error...");
    }
    
    ?>

    2017年8月13日 星期日

    為 LINE-Bot 加入鏡頭抓取功能


    我的私人助理是一個名為 Sita 的 LINE-Bot 程式,她除了能替我下載 Musical.ly 影片、下載 Packt 免費書、一般通知外,今日還加入了鏡頭抓取功能。這個 LINE-Bot 藏身的電腦是一台 Mac mini server,外接了兩台 USB 鏡頭,平時我會利用 OBS 來串流家中的畫面,但耗費的資源較多,最好是加到 LINE-Bot 中。

    要在 PHP 下抓取鏡頭畫面,除了 OpenCV 外,似乎沒有太多方法。而我不想用 OpenCV,所以改為使用 exec 執行外部抓取程式 imagesnap。要安裝 imagesnap 只需要在 Terminal 輸入「brew install imagesnap」。以下是 LINE-Bot 的相關程式:
    //  Default camera 1: Microsoft
    $filename = date("YmdHis").".png";
    $filePath = "/Users/Sites/sitaChanBot/".$filename;
    $response = exec("/usr/local/Cellar/imagesnap/0.2.5/bin/imagesnap -w 1 $filePath");
    
    $imageURL = "https://127.0.0.1/sitaChanBot/".$filename;
    $previewURL = $imageURL;
    $_lineBot->replyImage($replyToken, $imageURL, $previewURL);
    
    //  imagesnap -d "USB 2.0 PC Cam"
    $filename = "PC-".$filename;
    $filePath = "/Users/Sites/sitaChanBot/".$filename;
    $response = exec("/usr/local/Cellar/imagesnap/0.2.5/bin/imagesnap -w 1 -d 'USB 2.0 PC Cam' $filePath");
    
    $imageURL = "https://127.0.0.1/sitaChanBot/".$filename;
    $previewURL = $imageURL;
    $_lineBot->sendImage($senderUserID, $imageURL, $previewURL);

    2017年8月8日 星期二

    包車帶孩子遊沖繩・六


    今次為期六日的旅程來到最後一天。原本是五天,但擔心天氣會影響行程,所以預訂時加多一天。今日也沒有特別的安排。考慮到飛機 16:10 起飛,我們要 14:10 到達機場,扣埋乘車時間,13:10 便要從酒店出發。得一個早上,三個多小時,去的不遠。最後就是回到距離牧志兩個站的おもろまち站,Main Place 的 Namco 世界。


    由おもろまち站步行到 Main Place 約十五分鐘。之前途經 Tsutaya 大型書店卻沒時間,今次先去那裡。發現到 Robi 2 的蹤影。


    同場加映十多部夾公仔機。孩子們當然不會放過。然而,今次她們有收穫了!


    除了玩夾公仔機,也玩了兩局籃球。之後我們便繼續向 Namco 世界出發。媽媽們逛街,爸爸們帶著孩子又再放下銀両。



    今次孩子同樣沒有收穫;但爸爸卻發現找換機跳了一個未曾見過的 100 円出來。我決定留為紀念。


    一點鐘,是時候回程了。為了節省車費,女子組乘搭單軌電車去那霸機場;男子組回到酒店提回行李;大家約在國內線航廈會合,那裡有很多商店。女的可先吃點東西、逛逛街、買手信。

    在那霸機場,碰到很久沒見的朋友。她帶著孩子到沖繩玩,碰巧同一班機回港。


    回到香港了。旅程結束。努力掙錢,下一站名古屋。

    2017年8月7日 星期一

    包車帶孩子遊沖繩・五


    我們如常 8:30 起床食早餐,9:30 出發去玩。昨晚買了杯麵,女兒急不及待要品嚐一下,大人則吃三文治,飲果汁。今天選了舊海軍壕公園。查過巴士路線,剛好在酒店樓下有 9:40 的班次,錯過了要等到下午五時多才有;但 9:25 分時小朋友還說要大解,落樓等升降機也要時間,恐怕未能趕上。我們立即處理,趕緊到巴士站,終於趕上 88 號線巴士。



    在第 53 號站「宇栄原団地前」下車步行約 5 分鐘,穿過一條隧道便到達舊海軍壕公園。


    選擇舊海軍壕公園是因為它有沖繩最長的溜滑梯,而且不用自駕也能輕鬆到達。不過,相信是溜滑梯日久失修,加上曝曬,滑輪已經很轉得不順暢,玩起來經常卡住。幸好在公園內還有揪遷,小孩才能玩過痛快。


    太陽很猛烈,大女玩一會便覺得頭暈,需要飲水及休息;而我也要試試昨晚在超級市場買的飲品。


    公園內有雪糕機,買了一支來降溫。


    玩了一個小時,約 11:35 分,在我們下車的車站有巴士去下一站 Ashibinaa Outlet Mall。上車時拿下整理券,在下車時只要看看車頭屏幕 17 號格的金額,便知道要付多少車費。


    一下車,走進旁邊的商場,被扭蛋機吸引住了。孩子們抽了幾隻蛋。在二樓有遊樂場,夾公仔機再次出現,又放低了銀両。我們順便在這裡吃個午飯,選了一家烏冬店。吃飽到旁邊的 ¥120 店,消耗了不少時間。買了些竹碗、竹杯、麵豉湯、公仔玩具、健身球...等。


    朋友推介一定要食 Blue Seal 雪糕,這幾天一直無緣,不是遇不到,就是要去吃正餐時才路過,又或是已關門。今天有緣一試。味道可以,但溶得較快,要快快口食。


    對我這個只對動漫電玩電子有興趣的人,Outlet 真的很悶。這個 Outlet 不大,有退稅服務,但只限某些商店。我應內子要求,買了一對波鞋。行程比想像中提早完成,而朋友的兒子可能在舊海軍壕公園曬得利害,有點不舒服。我們下一站是再次回到奧武山公園。經過商量後,朋友太太帶兒子回酒店休息。無論是公園還是酒店,我們都是搭相同巴士。

    在巴士途中,輪到內子不適,還吐了幾次,幸好我們都有膠袋,不然真的不知要如何處理...。原本我們打算取消活動一起回酒店,不過小朋友很想再去公園,最終我們還是繼續。我再次交代她們下車的地點及如何看車費,也說明了 Plan B,假若她們錯過了酒店下車,只有幾個站能補救,否則便會去了很遠的地方,大家沒上網到時便很難找。


    我們再次回到奧武山公園,朋友兒子兩次不適都錯過了。微雨過後,滑梯很滑,得加倍小心。可惜朋友女兒因滑梯衝力跌到沙地上擦損了;及後一名香港女仕也有相同情況發生,不過她更是臉部著地,割破眼角,血流滿臉。她的丈夫呆了,我立即給她送上濕紙巾清潔。過程真的很嚇人 (>_<)。


    晚上,我們到了位於國際通頭的燒牛肉店,是包車朱先生介紹。


    這裡算是大,而且機乎座滿。我們被安排到一個看到夜景的角落,孩子再吵也不太影響其他客人。內子在酒店休息一會後,原本也想過來。但要自行乘搭兩個單軌電車站過來,最後還是算了。朋友的兒子睡了沒醒,決定繼續休息。只有兩大三小去試一試高級牛肉。







    大人少了,食物也不用太多。我選了人生中最貴的一餐。點了一份和牛,約 HK$1000。難得來到,也希望女兒能品嚐一下。她們都覺得非常好味道。