電影流水帳(2020/03/16~2020/03/25)

sophie turner
Sophie Turner

Dark Phoneix

之前同事已經去電影院看過了,他覺得很可惜,沒能好好發揮。我看過之後的感覺跟他一樣,就是可惜。原本應該是個好題材,卻被糟蹋了。

X-Men 由 Raven 帶領,帶著 Jean, Cyclops 等人一同上太空救人,大部分的人都被會瞬移的 Kurt 救到了,但隊長在別的位置,所以沒有。Raven 原本打算就此打道回府,可是 Professor X 堅持要救到所有人,Raven 拗不過 Professor X ,派了 Jean 過去撐住船體,由 Kurt 再去找人。眼看不明能量就要擊中船體,大家都非常緊張,可是 Kurt 順利完成任務,救回隊長。只是 Jean 呢?Jean 來不及,硬是被不明能量擊中。大家以為 Jean 已經犧牲了,過了沒多久,Jean 居然還活著,趕緊把她救回來。

回到地球以後,Raven 不爽 Professor X,她覺得 Professor X 變了,太在乎名聲,太在乎人類。Jean 則是沒有大礙,檢查時,只發現了體內的能量活動異常的高。檢查完,就去參加慶功派對了。在派對上,Jean 好像想起了什麼,整個能量大爆炸。Jean 就這樣離開,去找他的生父。之後,Professor X 才解釋他在 Jean 小時候做了一件事情,因為 Jean 小時候因為超能力意外害死了母親,Professor X 為了讓他能走過去,利用超能力掩蓋了她這段記憶。Jean 找到父親以後,跟父親簡短的交談,這讓她想起了自己所做的事情,她感到痛苦。這時候 Professor X / Beast / Raven 等人也趕到,想要帶回 Jean ,在溝通失敗的情況下,雙方起了衝突,這場衝突導致了 Raven 意外死去。Jean 感到很抱歉,就走了。Beast 不能釋懷 Professor X 的作為,他只想要找到 Jean ,讓她罪有應得。

Jean 跑去找了 Magneto ,想找他聊聊。此時的 Magneto 還不知道 Raven 的事情,只跟 Jean 聊了幾句話,軍方就趕來追捕了。Jean 起了殺心,想把來追捕的人都幹掉,Magneto 阻止了 Jean,並要軍方跟 Jean 都離開。Jean 離開了,軍方也離開了,Beast 這時找上了 Magneto ,說了 Raven 的事情。這下可好,兩個都曾愛上 Raven 的男人,聯手想為 Raven 復仇,就一同去追趕 Jean。這時候 Professor X 也找了Cyclops 等人,想要阻止 Beast ,拯救 Jean。因為意外殺人而內疚的 Jean ,沒有人聽她的話,反倒是跟隨那股不明能量的外星人找到了她,並用言語引誘她送出力量。Jean 萬念俱灰,就把力量給了外星人。Professor X 等人趕到,問出了事情的情況,趕來的 Beast 跟 Magneto 也聽到了,至此轉變成大家一起幫助 Jean。Jean 覺醒了,知道自己力量不該給外星人,就重新拿回力量,打敗了外星人。後面結局有點忘記了,忘記 Jean 後來如何,只記得 Professor X 深切的反省了自己對 Jean 所做的事情。

サバイバルファミリー

生存家族,這個蠻有意思的電影。

故事從一個家庭的日常開始,爸爸是個典型的上班族,上班認真,在家就是廢,所以跟孩子的感情也不好。媽媽是典型的好媽媽,照料家裡,但管不太動孩子。哥哥個性內向,很靜,每天就是聽音樂,不太跟家人交談。妹妹有點叛逆,只想跟學校的姊妹淘打好關係,在家愛理不理的,看不太起自己的父親。這一天,爸爸起床發現已經8點多了,他搖了搖鬧鐘,發現指針沒動,以為是忘了換電池,想說糟了,趕緊匆忙的起身。他趕忙叫了孩子跟妻子,匆忙的準備,當然也來不及吃早餐。媽媽則是趕著做早餐,她發現怪怪的,以為是停電。爸爸跟哥哥去重新啟動總電源,但沒有用。就這樣,媽媽早餐也來不及做,爸爸跟孩子們就匆忙的出門了。在通勤的路途上,他們都遭遇了困難,交通運輸都不通。好不容易趕到學校,只說是大規模停電,公司跟學校只能屈就於沒有電力的情況下去上班跟上課。媽媽在家也遭遇了沒水,跟採買結帳速度很慢的情況。

這樣的情況持續了兩三天,公司的主管宣佈停止上班,學校也宣佈了停課。爸爸回家跟媽媽商量以後,決定去投靠在鹿兒島的岳父。妹妹發了很多牢騷,覺得為什麼要放棄這麼便利的生活去鄉下的鹿兒島,但也只能屈就於目前的情況,遵從父母的想法。全家把該帶的衣服、行李跟錢糧打包好以後,就出發了,首先先去成田機場探一探,看能不能搭飛機。四人騎了腳踏車到機場,想當然爾,機場封閉。四人無奈,只能改走高速公路去鹿兒島。失去電力以後,整個日本陷入混亂的狀態,拿大把的錢還不一定換的到食物跟水,四人只能將就的前進。之後就是講他們的歷程,碰到暴風雨,碰到沒水、沒食物的各種情況,四人的相處因此慢慢有了改變,也更加瞭解彼此。最終他們還是到了鹿兒島,順利投靠了岳父。時間匆匆過了三年,電力突然回復了,他們回到東京,但他們在這三年裡學會了了解彼此,學會了怎麼過沒有電力的生活。

筆記:Firebase functions with authentication

主要可以 trigger 兩個,一個是 onCreate,一個是 onDelete

onCreate 在以下情況會被觸發

  • A user creates an email account and password.
  • A user signs in for the first time using a federated identity provider.
  • The developer creates an account using the Firebase Admin SDK.
  • A user signs in to a new anonymous auth session for the first time.
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
  // ...
});


onDelete 在使用者被刪除時觸發

exports.sendByeEmail = functions.auth.user().onDelete((user) => {
  // ...
});

裡面的 user 主要就是 UserRecord

email / displayName / customClaims / uid / …. 等欄位都有。

onDelete 可以用來做刪除 firestore/realtime database 上的資料,需要考慮 functions 能執行多久。

修改 git commit 的 author name

因為 commit 時的作者身份錯亂,所以要改掉。在 StackOverflow 查到這篇:How to change the commit author for one specific commit?

  1. 先 git rebase -i ,然後把 pick 全改成 edit
  2. 接著,git 會切到第一個 commit 結束的時間點
  3. 輸入 git commit –amend —author=”Author Name <email@address.com>” –no-edit ,這樣就會把這次 commit 的 author 修改為 Author Name <email@address.com> 。對,別忘了,這邊要改成你自己的名字跟 e-mail 。
  4. 再輸入 git rebase –continue 切到下個 commit
  5. 就這樣依序作業直到結束。

很麻煩,如果有上千個 commit 的話….(眼神死),所以以後還是要把 author 設定好,否則又要再苦一次。

axios catch

一般是寫 .catch((err) => {console.log(err);}

這樣只會看到 http status 的錯誤,不能取得 response。那該怎麼取得 error response 呢?axios 文件有寫了,用 err.response: https://github.com/axios/axios#handling-errors

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);    // 取得內容,用 error.response.data
      console.log(error.response.status);  // 取得狀態碼,用 error.response.status
      console.log(error.response.headers); // 取得表頭,用 error.response.headers
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

電影流水帳(2020/03/01~2020/03/15)

https://www.flickr.com/photos/135504457@N06/28730311681
Cara Delevingne
  • Time Freak (IMDB, Wikipedia),台譯:時間怪客。
  • Valérian et la Cité des mille planètes (IMDB, Wikipedia),台譯:星際特工瓦雷諾:千星之城。

Time Freak

Time Freak 故事蠻有趣的,是講男主角 Stillman 為了追求女主角 Debbie 製作了時光機器,然後試了無數次才成功的跟 Debbie 結婚,可是到了後來卻發現Debbie 沒有了熱情,他認為也許是自己扼殺了 Debbie 的熱情,為了讓心愛的人能更開心的生活,就決定回到過去讓自己無法製造這機器。跟著 Stillman 一起改變歷史的好友 Evan ,也跟著 Stillman 一起回到過去,已經享受過時光機器紅利的 Evan 試著阻止 Stillman 。但沒辦法阻止,Evan 只能眼睜睜看著 Stillman 無法發明時光機器了嗎?可是想不到,這時候 Debbie 赫然出現,知道真相的她相當的生氣,也透過時光機器回到過去,她很明白的告知 Stillman ,你不能這樣地隨意的操弄我的人生,把話說開以後,Debbie 跟 Stillman 相擁而吻,結束這故事。

Valérian et la Cité des mille planètes

盧貝松拍的,整個電影很有「第五元素」的既視感。基本上我蠻喜歡這故事的,有娛樂性,故事也有意思,只是後面有點拖戲了,沒有「第五元素」來的緊湊,蠻可惜的。除了故事以外,我也很喜歡女主角 Cara Delevingne ,她有點 Eva Green 的氣質,有點壞壞的,又很有魅力。

特工 Valerian 愛上女搭檔 Laureline,跟他告白,想說出完這次任務就結婚,一同去度假。想不到這次任務卻是意外的驚險,兩人歷經千辛萬苦,好不容易才取得神獸。回到星際城市阿爾法以後,本以為可以去結婚度假了,阿爾法有了狀況。這暫且按下不表,先說說阿爾法,阿爾法是個巨大的星際城市,裡面有各種不同的地形、環境,也有各種不同的人種,是個相當特殊的城市,這個城市由不同人種組成的政府來管理。那阿爾法出現什麼狀況了呢?在城市的某個角落沒有了通訊,也無法控制,派軍隊去了幾次,但都沒有人能回來。指揮官為了這事情傷透腦筋,開會討論,回來以後的 Valerian 跟 Laureline 奉命保護指揮官。會議才開到一半,就被人襲擊,指揮官被擄走。追蹤了訊號,發現訊號是消失在之前那個沒通訊的角落,Valerian 就開著飛艇到那邊去了。只是這次 Valerian 任務並不順利,Valerian 的飛艇被擊落,留守總部的 Laureline 為了救 Valerian ,違抗總部命令,隻身前往救援。

Laureline 透過關係,通靈到 Valerian 墜落的位置,然後前往那邊救出 Valerian。救出以後,他們決定更深入去尋找指揮官,卻也因此陷入了更多事件裡。不過在追查的過程裡,他們慢慢發現事情不簡單,指揮官這個人的意圖也不簡單,在總部代理指揮官也發現了這事情。追查到最後,他們終於把事情弄清楚,指揮官在數年前在打仗時,打算發射毀滅性武器幹掉敵人,敵人在某個星球附近,指揮官想說星球上應該沒人,也疏於調查,就決定發射了飛彈。敵人被滅掉了,而那星球上的種族也被滅了一大部分,殘存的人慢慢的學習科技,並逃到了阿爾法,並在裡面的某個角落生活下來,這個時間點也正好是阿爾法總部無法掌握那個角落的時間。後來指揮官知道了這事情,就想要把他們都滅了,永絕後患。總之,Valerian 跟 Laureline 透過該族的人了解了整件事情的前因後果,阻止了指揮官,揭發了他過去的罪行,該族的人民回歸和平,Valerian 跟 Laureline 結婚去了。

用 snap 跑 Folding@Home

環境:Ubuntu 18.04

這是看到 分享:處理 COVID19 之軟體專案數則 ,裏面提到 Folding@Home 可以幫忙運算與武漢病毒相關資訊,所以想裝起來幫忙。官方網站有提供 Linux / Windows / MacOS 的軟體,基本上裝起來就可以了。T客邦有篇介紹文章:

我不想裝 Debian package,想用 snap 來安裝,網路上有好心人打包好了。

安裝步驟很簡單,因為 Ubuntu 18.04 已經預先裝了 snap,接著只要用 snap 來安裝就可以:

sudo snap install folding-at-home-fcole90 --edge # 安裝
snap connect folding-at-home-fcole90:hardware-observe # 允許檢查硬體 (這是為了檢查 GPU 用,可以用 GPU 輔助運算)
snap services folding-at-home-fcole90.FAHClient # 檢查服務是否運行。

安裝好以後,在選單可以找到 FAHControl,執行它。第一步是先設定,按下工具列的 Configure,在 Identity 填入名字,以及 Team number。名字可以自己取,Team number 的話,請填 31403 ,這是台灣隊的編號,說明可以參考這篇 Folding@Home Taiwan Team。設定好之後,按下 “Fold” ,就會開始下載資料並進行運算了。以我的電腦配備,一個回合大約要兩小時。我有看到可以用 GPU 加速,我就依照這篇 How to Check Which GPU Is Installed on Linux 查了一下,看我的電腦有沒有支援 GPU,看了以後,我覺得應該是有,但 FAHControl 卻說沒有 (切到 System log 可以看到),查了半天都沒查出原因,後來才在 fah-snap 的 issues 看到這條 FAHClient cannot detect OpenCL correctly 。嗯,那看來只能等作者解決了,或者,裝 Debian package 試試看囉。

讓 docker daemon可以給別台電腦存取

docker 官方並不建議使用這方法,但還是有文件:Configure where the docker daemon listens for connections

不建議的原因很簡單,安全性。docker daemon 是用 root 權限在執行,而 docker 又沒有這方面的安全機制去處理帳號驗證,自然不建議這樣使用。 目前的主流是使用 kubernetes,另外,docker 最新的版本是有提出 docker context,利用 context 可以管理多種連接方式,其中一種連線方式是走 ssh ,會比較安全。

目前我只是想方便的操作虛擬機,所以可以不需要太考慮安全性問題。

編輯 systemd unit:sudo systemctl edit docker.service,把下面幾行貼進去

[Service] 
ExecStart= 
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 

讓 systemd 重新載入設定: sudo systemctl daemon-reload

重啟動: sudo systemctl restart docker

檢查: sudo netstat -lntp | grep dockerd

在別台電腦上,先設置環境變數:export DOCKER_HOST=tcp://your_docker_host:2375 , 然後用 docker 指令就可以存取該台 docker 主機了。

用 redoc 來顯示OpenAPI規格文件

之前有找過怎樣輸出 OpenAPI 規格為文件,有試過 swagger-codegen 先轉成 HTML 再轉 PDF,但其實效果不好,也一直沒找到滿意的。

今天再來找一次,找到 redoc,依照 github 網站上的說明來作,用 redoc 提供的 docker image 就可以跑起 API 文件的 Live 網站,效果挺好的。

docker run -p 8081:80 --rm -v $(pwd)/api.yml:/usr/share/nginx/html/api.yml -e SPEC_URL=api.yml redocly/redoc

網站上還有提到一個 redoc-cli,說明說可以 bundle 成一個靜態HTML文件。有 homebrew ,就想說 homebrew 會不會有這個 formula,找了以後,發現是沒有,只好認命的用 npm 來裝

npm install npx npm install redoc-cli 

裝 npx 是為了可以方便的呼叫 node module 裡的指令來用,這部份的使用說明可以參考這篇:Introducing npx: an npm package runner 。 裝好以後,就可以使用了:

npx redoc-cli bundle api.yml 

輸出的檔案固定是 redoc-static.html,用瀏覽器開啟就可以了。

筆記:Queries, Part 1: Common SQL Queries Converted for Firebase

依照 Queries, Part 1: Common SQL Queries Converted for Firebase 來練習

  • By ID ,路徑指定好就可以了 firebase.database().ref(‘/messages/’ + messageID).once(‘value’, function(snap) { … });
  • WHERE, 除了路徑之外,還要指定 orderByKey() 或 orderByChild(),然後再用 startAt/endAt
    • orderByKey 是依照 key 的值:firebase.database().ref(‘/messages’).orderByKey().startAt(‘user001’).endAt(‘user010’).once(‘value’, function(snap) { … });
    • orderByChild 是依照子節點的值:firebase.database().ref(‘/messages’).orderByChild(’email’).startAt(‘user001@example.com’).endAt(‘user010@example.com’).once(‘value’, function(snap) {…});
    • 用 orderByChild 時,要在規則裡加上 .indexOn ,否則會有警告,警告的大意是說加indexOn 後,效能會比較好。
  • LIMIT,加 limitToFirst(10) 或 limitToLast(10)
    • 可以跟前面提到的 startAt / endAt 結合:firebase.database().ref(‘/messages’).orderByChild(’email’).startAt(‘user001@example.com‘).endAt(‘user010@example.com‘).limitToFirst(10).once(‘value’, function(snap) {…});
    • limitToLast 就是指定後面幾筆

筆記:firebase functions – realtime database

閱讀的文件:https://firebase.google.com/docs/functions/database-events

可以寫這些事件的處理常式

  • onWrite() 資料被建立、更新或刪除時,會觸發
  • onCreate() 資料被建立時,會觸發
  • onUpdate() 資料被更新時,會觸發
  • onDelete() 資料被刪除時,會觸發

可以只針對指定的路徑,對,也因為事件資料同時包含舊的跟新的,資料量有限制,資料量大的時候要針對個別路徑拆開來寫處理常式。

可以用參數,例如 ref(‘foo/{bar}’)  ,那麼存取 foo/hello 或 foo/firebase 時,都會觸發常式對 foo/ 寫入,像下面

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

會觸發兩次常式,一次是 foo/hello ,一次是 foo/firebase從 EventContext.params 可以用 bar 這個 key 去拿到 hello 或 firebase
範例

 
// 當有訊息加到 /messages/:pushId/original 時,執行這常式。 
// 這常式會把指定路徑下的值,轉為大寫,再放到 /messages/:pushId/uppercase 
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original') 
    .onCreate((snapshot, context) => {  // snapshot 是 DataSnapshot ,context 是 EventContext 
      // 先取得寫入的值 
      const original = snapshot.val(); 
      console.log('Uppercasing', context.params.pushId, original); 
      const uppercase = original.toUpperCase(); 
      // 把資料寫到 "uppercase" sibling 然後回傳 Promise 
      // snapshot.ref.parent -> /messages/:pushId 
      // snapshot.ref.parent.child('uppercase') -> /messages/:pushId/uppercase 
      return snapshot.ref.parent.child('uppercase').set(uppercase); 
    }); 

用 EventContext 的 auth / authType 就可以取得 authentication 資訊 (這邊我有點迷糊了,為啥 authType 可以是 ADMIN / USER ??

onWrite 的時候,是用 change, context change 是 Change,提供了 before/after property 可以存取寫之前/之後的值 。