電影流水帳(2015/11/1~2015/11/25)

Pimchanok Luevisadpaibul "baifern"
พิมพ์ชนก ลือวิเศษไพบูลย์ ,初戀那件小事的女主角,在電影裡扮醜。

 

隔了一段時間才想起來要寫。

  • 捉妖記 (IMDB, Wikipedia)。大公子跟我說他在學校裡有看過這電影,所以才找來看看。原本以為電影裡的妖是恐怖的,不過這部電影裡的妖是用 CG 繪製,相當可愛。以一部真人與動畫互動演出的電影來說,我覺得這部電影的成就蠻高的。主打孩童市場也相當正確,故事很溫馨,不過我個人覺得故事有點弱。
    妖界發生大事,妖后懷著小妖王逃到人間,遇到了主角宋天蔭,妖后死了,小妖王到了宋天蔭肚子裡。霍小嵐則是天師,天師是來捉拿妖的,遇到了宋天蔭,與宋天蔭合謀要帶著肚子裡的小妖王去領賞。後來小妖王在領賞的路上出生了,好歹總是肚子裡的一塊肉,於是宋天蔭跟小嵐就對小妖王有了感情。領賞的路上有不少阻礙,三人一一克服了,到了城裡找湯唯要領賞,宋天蔭雖然捨不得,卻還是留下小妖王。小妖王就被送去有錢人的廚房。在電影裡的設定,妖怪不是殺人,就是被人吃,所以有特別的妖怪廚房,專門宰殺妖怪供人食用。小妖王是皇族之後,被認為有特殊的療效,所以也特別珍貴。宋天蔭事後覺得捨不得,就說服了小嵐,想要贖回小妖王,但是小妖王已經被送到葛千戶那兒去了。於是兩人就上葛千戶那兒去找人。
    葛千戶就是下令要捉拿小妖王的人,小妖王送到他那兒去以後,他就預備了一桌筵席,並且讓人預約來食用。宋天蔭兩人潛入以後,開始救援計畫,原本帶著妖后一起逃亡的隨從也一起來攪和,一陣攪和之下,發現了葛千戶也是個妖,經過一番打鬥,消滅了葛千戶,救回小妖王。這一行人也發現妖並不全都是壞的,宋天蔭讓妖怪隨從帶著小妖王回到深山裡去,他則是跟著小嵐繼續營救妖怪。
  • สิ่งเล็กเล็กที่เรียกว่า…รัก (IMDB, Wikipedia),台譯:初戀那件小事。是因為「我的少女時代」的新聞才會想看這部電影。
    故事蠻簡單的,就是少女小嵐暗戀學長小莫,然後努力改變自己。到了畢業,兩人分開,但是經過9年以後,小莫成了攝影師,小嵐成了知名造型師,兩人重新在電視節目上相遇。
    電影還不錯,但也沒辦法說很好看就是。男主角是真的很帥,女主角也不錯,真正讓我驚訝的是女配角,如果我沒看錯的話,她也在「撞鬼那件小事」裡演出,在那部電影裡她看起來身材有點小胖,但是在這部電影裡,就判若兩人,整個漂亮很多。

截至目前看完 53 部電影啦!

Django model 的 validate

同事問,為什麼用 model 建立 instance 以後,呼叫 save 沒有觸發 validate?

上網找了一下,大致有兩種方法:

  1. 用 ModelForm 的 is_valid() 做檢查,Correct Way to Validate Django Model Objects?
  2. 覆寫 model 的 save(),Django model mixin to force Django to validate (i.e. call `full_clean`) before `save`

事情沒有這樣結束,因為很好奇 Django 的作法,就去追 Code。

如果是走 is_valid() :

  1. forms/models.py:ModelForm 繼承自 BaseModelForm,而 BaseModelForm 又繼承自 BaseForm,這個檔案裡,沒有看到 is_valid
  2. forms/forms.py:
    1. BaseForm.is_valid() 很簡單的只回傳 self.is_bound and not self.errors ,self.is_bound 跳過不看,self.errors 是一個 property,裏面呼叫了 self.full_clean()
    2. self.full_clean() 呼叫了 self._clean_fields(), self._clean_form() 與 self._post_clean() ,關鍵在 self._post_clean() 。BaseForm 裡的 _post_clean() 是空的,讓繼承 BaseForm 的類別去決定。
  3. forms/models.py: 回頭看 BaseModelForm._post_clean(),這裡呼叫了 self.instance.full_clean() ,並處理 ValidationError 。instance 就是 model 類別所創出的實體,Model 繼承自 ModelBase 所以接著看 ModelBase 類別。
  4. db/models/base.py: ModelBase 的 full_clean() 呼叫了 self.clean_fields(), self.clean() 與 self.validate_unique ,並且在這裡處理了 ValidationError 例外,最後判斷了 errors 裡是否有東西,有的話,丟出 ValidationError。先看 self.clean_fields() ,函式裡去取得定義在類別裡的欄位,並且呼叫每個欄位 (Field) 類別的 clean() 函式。如果有錯誤就丟出 ValidationError()
  5. db/models/fields/__init__.py:Field 類別定義在這個檔案裡,裏面的 clean() 呼叫了 self.validate() 、self.run_validators()

至此,ModelForm 的路徑就確定了。

來看看第二個方法,他是要求 Model 類別除了繼承 Django Model 之外,再繼承 ValidateModelMixin 這個自訂類別以覆寫 save() ,看看裏面的 save(),就只是多呼叫了 full_clean() 來檢查,也就是走上述步驟 4 以後的路線。

Django 官方網站不建議直接去呼叫 full_clean() 這件事,不過找了一下,也沒找到什麼更好的解法~

P.S.

Github ATOM

Github 推的編輯工具,還蠻好用,跟 Sublime Text 比起來,至少可以打中文… XD

安裝相當簡單,到 ATOM 網站,下載對應的安裝檔案安裝就可以了,我是用 Ubuntu,下載 .deb 用 dpkg -i 安裝就可以了。

安裝以後,需要調校一下,因為字型的關係,中文會顯示不出來。設定可以參考下面來進行調整:

不過說真的,我不是很常用這個,大部份還是用 vim。這兩天再拿出來用,才發現多了一個 apm 的指令,顧名思義就是管理 ATOM packages 用的,像是安裝、反安裝或更新等等,都可以透過這個指令進行。

不過,要檢查 ATOM 更新的話,就比較麻煩了,還好有 package 可以幫忙做這件事情,我是用 atom-update 這個 package。

補充:參考這篇 Atom 使用心得與 Package 推薦 跟根據自己需求,裝了一些 packages/themes:

  • atom-beautify
  • atom-hexo
  • atom-material-syntax
  • atom-material-ui
  • atom-update
  • autocomplete-python
  • color-picker
  • ex-mode
  • file-icons
  • git-blame
  • git-log
  • git-plus
  • highlight-selected
  • indent-helper
  • linter
  • linter-flake8
  • markdown-preview-plus
  • markdown-toc
  • merge-conflicts
  • minimap
  • project-manager
  • recent-projects
  • vim-mode

Migrate ghost to hexo

Hexo 是一個快速、簡單且強大的網誌框架,Ghost 是一個用 javascript 寫的 Blog 平台。

我在公司有用 Ghost 架一個小小的 Blog ,紀錄一些事情,後來想把 Ghost 搬到 Raspberry PI 上,但是 Raspberry PI 的效能不是很好,就轉念改用 Hexo。Raspberry PI 只架設單純的 Web server,桌機用 Hexo,在產生完網頁之後,再 Deploy 到 Raspberry PI 上。

要搬家基本上不難,Hexo 這邊先安裝 hexo-migrator-ghost,然後依照說明,先到 Ghost 那邊 (http://yourblog.com/ghost/debug/) 匯出資料,然後回到 Hexo ,用 hexo migrate ghost exported_json 匯入剛剛在 ghost 匯出的檔案就可以了。

圖片的話,要自己處理,最快的方法是複製 your_ghost_folder/content/images 到 your_hexo_folder/source/images ,然後將文章裡圖片路徑的 /content 移掉就可以了。

Hexo 在處理文章圖片上有更好的方式,可以參考這篇文章:Asset Folders ,在 _config.yml 裡啟用 post_asset_folder: true 以後,在建立新文章時,hexo 會自動建立以文章標題為名的資料夾,把圖片放到該資料夾下面,然後引用就可以了。這樣做比大堆頭的擺在 source/images 下自己管理來的好。

error, fat_get_cluster: invalid cluster chain

Android 手機沒辦法掛載 MicroSD,插到多合一讀卡機裡,接到桌機上,用 dmesg 看,發現有這樣的訊息:

error, fat_get_cluster: invalid cluster chain

請 Google 大神幫忙找答案:

循線找到 testdisk 這工具,sudo apt-get install testdisk 就可以安裝。

安裝以後,直接執行 sudo testdisk,大致就依照畫面,依照下面的選擇去選就可以了。

>Create a new log file
[Choose Disk]
>Intel/PC partition
>Advanced
[Choose Partition]
>Boot
>Repair FAT
[Accept Defaults and Write]
>(Q)uit until exited

大體來說,就是選磁碟、選 Intel/PC partition,選分割區,選 Boot,選 Repair FAT,再選 Accept default and Write 就行了。

想不到有這麼神奇的指令,托福,我的 MicroSD 救回來了。

gitlab 的備份檔

gitlab 的備份是一個 tar 檔案,用 tar xf 解開以後,會依照你 gitlab 裡的 user/group 區分目錄,解開以後,會發現裏面又是一堆 .bundle 檔案。

.bundle 該怎麼解開呢?其實它也是一個 tar 檔案,用 tar tf 就可以看到內容,所以如果要還原的話,就先建一個目錄,再切到該目錄下解開就可以了。

取得 KVM 執行中 VM 的 IP

在建立並執行 VM 以後,除了利用 console 登入取得 IP 之外,有沒有辦法不要利用 console 取得 IP 呢?

第一個找到的是這篇:Tip: Find the IP address of a virtual machine,他的作法是取得 VM 的 MAC address ,再以 MAC address 去 arp 裡找到對應的 IP。這方法很簡單,但是有一個缺點,就是 VM 必須要有跟 host 有網路動作,arp 裡才會有這資訊。作者是用 perl 開發的,我改寫成 Python

這樣並不符合我的需求,所以又繼續找。後來找到這篇:linux kvm – Find IP of VM running KVM – Super User  ,裏面的前幾個回答也是說要用 arp,但是最後一則回覆提供了不同的答案,他是用 virt-cat 。查了一下,virt-cat  需要安裝 libguestfs-tools ,安裝好以後,就可以用 sudo virt-cat -d your_domain /var/lib/dhcp/dhclient.eth0.leases 去查看 /var/lib/dhcp/dhclient.eth0.leases 檔案並取得 IP 了。整理一下,使用這個方法必須:

  1. 安裝 libguestfs-tools 以取得 virt-cat
  2. VM 是使用 DHCP,如果是固定 IP ,我想這在製作 image 的時候,應該就能確定了,所以這不是問題。
  3. 網路介面是 eth0,如果是其他的 eth1 或什麼的,就自行把 eth0 換掉就可以。

缺點大概就是要 sudo 吧,不 sudo 的話,會有錯誤。查了一下,發現這是因為存取 /boot 下 kernel image 時,權限不夠所引起的,沒找到方法解決。

編譯 Raspberry PI Kernel

本意只是想在 Raspberry PI 上裝 Ghost ,結果 node-sqlite3 裝不上去,Raspberry PI 版子速度又太慢,就想乾脆用 QEMU 摹擬 Raspberry PI。

用 QEMU 摹擬 Raspberry PI 可以參考這篇:Raspberry Pi • View topic – HOWTO: Virtual Raspbian on Qemu in Ubuntu Linux 12.10

裏面的步驟大致是這樣:

  1. 取得 qemu 用的 kernel
  2. 取得 Raspbian imgae
  3. 安裝 QEMU:sudo apt-get install qemu-system-arm
  4. 執行 QEMU:qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -hda raspbian-jessie.img -kernel zImage -append “root=/dev/sda2” -net nic -net user,hostfwd=tcp::2222-:22 -serial stdio

我目前是卡在 qemu 用的 kernel 上,原本想說直接拿 raspbian 的 kernel.img 來用,但發現不行。如果用文章裡作者提供的 zImage 是可以開機,但會有找不到 init 的情況。所以現在就朝自己編譯 kernel 的方向來做,這部份可以參考:

儘管如此,我編譯出來的 kernel 仍然無法順利開機,找時間再研究吧~