2016年4月7日 星期四

用 python 撰寫 GTK+3 架構下的視窗介面

最近想要寫一個小程式,隨手挑了一套 solution:

python - 程式語言
GTK+3 - 視窗介面程式框架
glade - 畫視窗介面的 IDE

其中 glade 可以把用 IDE 畫好的視窗 layout 直接存成 GTK 可以理解的 xml 格式檔案,藉此增加開發設計視窗外貌的速度。

選擇 GTK+3 的理由滿單純,因為我使用的系統** 上的 glib 會抱怨我所使用的 glade 必須是 3.x 版 ***


** 我是用 Ubuntu 14.04 64 bit
*** import gtk 這種語法似乎就是支援 GTK+2.x,細節可參考這個 stackoverflow 連結



步驟一:使用 glade 畫 layout 後轉成 XML


首先啟動 glade,接著創建一個視窗(在工作 panel 中按視窗即可),注意這個視窗有個名字(預設是 window1),這個名字會被 python GTK+3 拿來取得該視窗物件,所以如果你有更改視窗名稱的話,程式中呼叫的名字也要跟著改。

畫好之後就存檔,檔案本身就會是 XML 了。

步驟二:開始寫程式


整個 python GTK+3 架構大致如下:
使用 builder 取得視窗物件、註冊 signal、設定組態等等。最後開始執行 Gtk main loop 等待事件。

範例如下:

from gi.repository import Gtk

class HellowWorldGTK(object):
    """This is a Hello World GTK application"""
    def __init__(self):
        # layout generated by glade
        layout_filename = "layout.xml"
        builder = Gtk.Builder()
        builder.add_from_file(layout_filename)
        #builder.connect_signals(self)
        self.window = builder.get_object("window1")
        if self.window:
            self.window.connect("destroy", Gtk.main_quit)
        self.window.show_all()
if __name__ == "__main__":
    hwg = HellowWorldGTK()
    Gtk.main()


其中 layout.xml 是步驟一用 glade 存成的 XML 檔案名稱,window1 也是步驟一中提到的視窗名稱。這裡比較要注意的是使用這行程式碼來讓我們可以關掉視窗的時候,同時退出 Gtk main loop。如果沒有這行,程式一但執行後就會一直跑,只能另外請作業系統殺掉它了。

self.window.connect("destroy", Gtk.main_quit)


步驟三:執行


步驟二中的範例程式碼存成 go.py,執行 go.py 即可。




更多資訊可以參考 Python GTK+3 Tutorial (剛好昨天才 release!)

2016年3月3日 星期四

snap 套件包簡介

Canonical 公司最近提供了一種叫做 snap 的套件包格式,目的是希望可以改善開發 IoT 裝置的流程,甚至是進一步培育 IoT 的 App ecosystem。綜觀整個 snap 的孕育過程,snap 的前身似乎可以說是 click package,後來再針對 snappy 架構** 而改良的格式。以 snappy、Ubuntu core***、和 snap package 三者構成的開發與系統環境,成為 Canonical 公司的產品重心。這兩天 Canonical 和 MTK 合作的消息便是一個這樣的例子。

** snappy 是系統架構的方式。意指是一種使用 snap 當作系統管理(安裝、移除軟體)單位的手段。
*** 最常見的詞是 snappy Ubuntu Core,因為 snappy 架構常常和 Ubuntu Core 搭配使用。解讀方式是 snappy (形容詞) Ubuntu Core(名詞),就是 墊基於 Ubuntu Core 之上的 snappy 架構。Ubuntu Core 和以往的 Ubuntu (現在稱為 Ubuntu Desktop)的架構不同,細節請參考官方網頁


今天要介紹打包一個 snap。

實作上官方網頁其實寫得很清楚了,基本上下面的內容直接是取自與摘要該網頁 XD


  • 打包的工具叫做 snapcraft。Trusty 上面沒有,可以透過增加 PPA 來安裝。(我自己有試過編 github 上面的 source code 來玩,但不知道為什麼會 crash;我推測是因為最近自己系統上的 python 被我有點弄髒了 =.= )
  • 打包的設定寫在 snapcraft.yaml,這基本上可以類比於 debian/rules 這類型的檔案。
  • snapcraft 五大步驟是:pull build stage strip snap, 合稱 assemble
  • 概念上就是通通摻在一起做撒尿牛完:有點像是編靜態 shared library,把所有需要的東西拉下來、編譯、踢掉執行階段用不到的 binary、把剩下的 binary 弄成一包。這樣的設計應該是為了 IoT device 而做的。(是的,我也推測會相對肥大)

2016年2月17日 星期三

Ubuntu 下把 NEF 檔轉成 jpg


NEF 是 Nikon 系列相機的 raw 檔案,Ubuntu 可以使用 shottwell 或是預設的圖形瀏覽器去瀏覽。

如果想要抽取 RAW 中的 jpg 的部份(例如想要讓檔案尺寸小一些),可以使用 imagemagick 來批次轉檔。使用前要先另外安裝 ufraw-batch

sudo apt-get install ufraw-batch

接著(不會覆寫原本的 RAW)

for i in `ls *.NEF`; do convert $i $i.jpg; done

或是(會覆寫原本的 RAW)

convert xxx.NEF xxx.jpg

或是(會覆寫原本的 RAW)(試了一下這個指令,不知道為啥會失敗[1])

mogrify xxx.NEF xxx.jpg

PS 沒仔細研究,但看起來 RAW 往往會是 jpg + 一卡車自己定義的 EXIF 資訊?
PS2 mogrify 看起來是整合在 convert 裡面的工具之一

[1] 錯誤訊息:mogrify.im6: unable to open image `zzz.jpg': No such file or directory @ error/blob.c/OpenBlob/2638.

2016年1月14日 星期四

以 SOLVCON 專案為例,使用 conda 來維護、建立 python 執行與開發環境

一套可以正常運作的應用程式往往需要有很多其他配套的軟體互相支援,這造成了建構軟體中常見的「版本相依性」問題。如果是使用者的身份,這類問題可以透過(雖然這不一定是最好的方法)將所有相依的軟體都打成一包釋出。但身為開發者,常常遇到的問題是「開發者自己的作業系統環境」和「想開發的應用程式所需要的環境」有所不同。一般來說,開發者大概不太願意去更動自己的作業系統環境來配合自己的開發標的軟體,因為這可能會導致開發者自己的作業系統本身、或是作業系統下的其他應用程式無法正常運作。一個直觀的解決方案當然就是「那我弄一個專門給想開發的軟體使用的環境總可以了吧?」,conda 就是這樣的一個工具。

conda 是 anaconda 和 miniconda 所羅列的工具之一 。anaconda 和 miniconda 也是想做一樣的事情,但是前者可以堪稱是「包山包海」;這是優點也是缺點,優點就是一口氣把所有第三方的軟體都先準備好,以後幾乎不用再煩惱,缺點就是一定會準備了很多其實用不到的東西。miniconda 可以想像成是精簡版本的 anaconda 、然後有管理 python package 功能的 virtualenv[1]。

最近 SOLVCON 從原來的 python 2 移植到 python 3 ,主要的核心移植已經堪稱完成。然而最近想持續開發的 parallel 運算能力則在移植前便已經過時,剛好趁這次大搬家把這個 feature 修回來。

要熟悉一個程式的 feature,我還滿喜歡從研究它相關的 unittest 開始著手。理由如下:

從 unittest 中,我們可以看到
  1. 使用者的角度 - 這個功能如何被使用
  2. 測試者的角度 - 這個功能所產生的結果如何被解讀
有頭(如何 input 和使用)有尾(如何解讀 output)的情況下,就可以開始從外部行為來觀察程式執行 runtime 這個可以被視為黑盒子的部份。可以觀察外在的行為(unittest)加上可以觀察內在的行為(例如 source code)的話,幾乎就是一個說明清楚的 step by step tutorial。

有點扯太遠,總而言之要處理下面這兩件事情:
  1. 準備可以運行的 SOLVCON。SOLVCON 不再使用 scons 做套件管理(悲劇!!打包成 debian package 的 rule file 又要重寫 XD ),而改為使用 python setuptool ;因此要把對應的第三方工具告訴 setuptool。這裡我們採用 conda 當作解決方案。
  2. 利用 ftests 中的 nosetest 去研究和修復 SOLVCON 的平行運算功能。

準備好 conda 之後(這部份略過啦!好久以前就裝好了 XD 裝 anaconda 或是 miniconda 之後就有這個指令可以使用),先確認環境變數有告訴系統哪裡去找 conda 這個工具(通常是 anaconda 或是 miniconda 當初安裝的位置),例如有加入 PATH 變數。

啟動並且進入 conda 環境;我自己是把他寫成一個 alias 比較方便
alias solvconenv="export PATH=$MYLOCALINSTALLATION/miniconda3/solvcon-dev/bin:$PATH; source activate $MYLOCALINSTALLATION/miniconda3/solvcon-dev"

接著使用這個指令去安裝缺少的套件
conda search <package name>

安裝則是
conda install <package name>

例如安裝 python
conda install python
安裝 python3
conda install python=3
後面的等於3表示指定特定版本號碼。


更多使用方法請見 help
conda -h

[1] virtualenv 是用來建立獨立 python 套件環境的工具。









2016年1月13日 星期三

使用 flake8_docstrings python package 將 docstring 格式納入 flake8 檢查項目

長久以來一直都習慣在 Ubuntu 下使用 flake8 這個工具來檢查自己 python source code 有沒有符合 pep8 規範。

在 Ubuntu 下安裝 flake8

sudo apt-get install python-flake8

使用

flake8 <your source code>

這個工具同時也可以和 vim 共用,使得使用者在用 vim 的時候可以即時看到檢查結果。(但我今天沒打算聊這個 XD)

但今天被強者我同事糾正我的 docstring 沒有符合規範,建議我可以使用 flake8-docstrings 這個工具將檢查更完善一些。我才注意到 1. Ubuntu 下沒有這個 package 2. 以往我都漏掉這個檢查了。於是趕緊補上:

因為 Ubuntu 沒有納入管理 flake8-docstring 這個套件,所以我改用 pip 安裝工具來安裝:


sudo pip install flake8_docstrings

安裝之後再使用 flake8 就可以看到它會去掃出不符合規範的 docstring 了,例如:

$ flake8 <my source code>
......
D300 Use """triple double quotes"""
D400 First line should end with a period
D102 Missing docstring in public method
......


環境:Ubuntu Trusty

2016年1月11日 星期一

使用虛擬機器測試 secure boot (四) 使用 OVMF

前面提到我們已經用 OVMF (open source virtual machine firmware)建立一個虛擬機器了。現在我們想要讓 OVMF 這個 firmware 啟動 secure boot ,並且可以讓我們放入自己的 key 。這樣之後就可以模擬真實的 secure boot 的情形。

方法主要參考這篇文章,另外再根據自己環境的情況做調整。

使用 virsh 重新啟動稍早建立的虛擬機器

virsh list --all
virsh start <domain name>

開啟螢幕

virt-viewer <domain name>

啟動後,會 pop up 「Tianocore」,這是因為 OVMF 是移植並且開源 Intel 開發的 Tianocore 這個 firmware。因為還沒有安裝作業系統、虛擬機器的硬碟中也沒有 efi binary,所以會進入 OVMF 的 UEFI shell。輸入 exit 跳出後會進入到設定的畫面。如圖一路可以選到使用檔案匯入 key 的選項。當然,現在什麼檔案都沒有。所以問題變成是,我們要怎麼準備 key file 呢?










2016年1月6日 星期三

使用虛擬機器測試 secure boot (三) 使用 virtsh


呼叫使用提示
virsh help

顯示選項 list 的使用提示
virsh help list

連結本地端 qemu 這個 hypervisor (virsh 可以管理多種不同的 hypervisor,qemu 只是其中一種)
virsh connect qemu:///system
連進去後,
顯示 domains (但 inactive domain 不會顯示;一開始還以為沒有連成功,因為啥都沒顯示)
virsh list

顯示 domains (包括 inactive domain)
virsh list --all

立刻終止 active domain (相當於 virt-manager 下使用 force off )
virsh destroy <domain name>

刪除已經建立/定義好的 domain(要先 destroy 才可以 undefine)
virsh undefine <domain name>

virt-tools.org 這裡有簡單的教學。



virt-tools.org 的這個教學網頁裡也有提到如何透過 /proc/cpuinfo and demsg 檢查自身的機器是否支援虛擬化技術;如果有,又是哪一種虛擬化技術。簡單直白,值得一看(下面直接摘要):

/proc/cpuinfo flags #

/proc/cpuinfo will tell you if the processor supports virtualization and if it is enabled (but it could not show up in flags because it is disabled — more on this below).
The flags to look out for are:
  • vmx — Intel VT-x, basic virtualization
  • svm — AMD SVM, basic virtualization
  • ept — Extended Page Tables, an Intel feature to make emulation of guest page tables faster.
  • vpid — VPID, an Intel feature to make expensive TLB flushes unnecessary when context switching between guests.
  • npt — AMD Nested Page Tables, similar to EPT.
  • tpr_shadow and flexpriority — Intel feature that reduces calls into the hypervisor when accessing the Task Priority Register, which helps when running certain types of SMP guests.
  • vnmi — Intel Virtual NMI feature which helps with certain sorts of interrupt events in guests.

Kernel messages (dmesg) and the BIOS #

The next thing to look at are the kernel messages by running the command:
dmesg | less
The two messages to look out for are:
kvm: no hardware support
and
kvm: disabled by bios




詞彙:
hypervisor - 不精確地講,就是虛擬機器層。
domain - virtual machine instance