2012/04/28

音樂人也選擇 Python

阿海跟小怪,都是愛玩科技的音樂人。

阿海: 該學 Rails 嗎? 小怪: 音樂人當然是學 Python 囉 Django 就是少了嘴炮的 Rails

他們選擇 Python,也值得你來認識。 PyCon Taiwan 2012 等你哦!

2012/04/18

If You Love Python (Really Love Python)

If the sun should tumble from the sky
If the sea should suddenly run dry
If you love Python, really love Python
Let it happen, I do care.

If it seems that everything is lost
I will smile and never count the cost
If you love PyCon, really love PyCon
Let it happen, darling I do care

Shall I catch a shooting star
Shall I bring it where you are
If you want me to, I will.
You can set me any task
I'll do anything you ask
If you'll only love Python still.

When at last, our life on earth is through
I will share eternity with you
If you love Python, really love Python
Then whatever happens, I won't care

When at last, our life on earth is through
I will share eternity with you
If you love PyCon, really love PyCon
Then whatever happens, I won't care

2012/04/12

Import Steps for Content Types

建立新的內容型別後,最基本的啟用方式是到 Plone Setup 用 QuickInstall 來生效,另一種方式,是到 ZMI 的 portal_setup 透過 Import 指定 import step 來生效。

下列是幾個可能相關的 import step 項目:

  • ATContentTypes Tool
  • Archetype Tool
  • Content Type Registry
  • Types Tool
  • Portal Factory Tool
  • Portlets

2012/04/11

Plone Package Renaming

假設有個名稱是 my.packages 的模組,用了一陣子,產生許多 MyType 的內容項目,想要把它改名為 my.package,下列是處理經驗記錄。

第一次的嘗試,是在 src 目錄裡把 my.packages 複製並修改成 my.package,停用 my.packages 再啟用 my.package 模組後,存取 http://localhost:8080/mysite/myfolder/my-item 時,會遇到 <persistent broken my.packages.content.mytype.MyType instance '\x00\x00\x00\x00\x00Un^'> 訊息。當然,使用 migration 程式碼是個方法,但實在是殺雞用牛刀。

有個輕量級的方案,是先在模組的 __init__.py 裡用 sys.modules 來建立相容資訊:

import sys
sys.modules['my.packages'] = sys.modules[__name__]

不過,我的模組還額外有用到 content type based portlet,它同樣把舊的模組名稱記到 instance 裡,在 https://dev.plone.org/ticket/7375 有提到處理方法,試了沒成功,有成功的方式是到 @@types-controlpanel 先取消 portlet 的設定值,再啟用 my.package 模組。這時候出現一些警告訊息,但是系統看起來運作正常,應該是提供相容資訊後的暫時訊息:

INFO Archetypes
ArchetypesTool: Trying to register "my.package.MyType" which has already been registered.  The new type my.packages.content.mytype.MyType is going to override my.package.content.mytype.MyType

再到 ZMI 裡 archetype_tool,執行 Update Schema 後,希望這樣就算是把 instance 更新了。

2012/04/10

Paperwalking Installation

Walking Papers 是 OpenStreetMap 的衍生服務,它讓地圖資訊的更新有了新途徑,藉此希望大幅降低 OSM 資訊更新的門檻。應用的工具包括了 Scale Invariant Feature Transform 和 QR Code 等。

服務網站的程式碼是 paperwalking,附的文件說明了 Ubuntu 9 環境的安裝方式,下列是對應的 CentOS rpm 資訊:

curl vim-enhanced screen tcsh sudo git
python-imaging numpy java-openjdk
php-gd php-mysql mysql-server php-pear gdal-python gdal

一時沒找到 python-pyproj 的 rpm,必要時要改用 pip 去裝,另外也遇到抱怨 libgeos.so.2 相依問題的訊息。看來要在 CentOS 5.8 成功安裝是要花一番工夫。

我實際上是在 Ubuntu 11.04 安裝成功,要留意的地方是 Smarty 下載網址改變了,原本寫死在 site/lib/Makefile 裡的程式碼要對應修改。啟動系統前,要編輯 site/lib/init.php 檔案內容,至少要修改的有 TZ=Asia/Taipei, DB_DSN, API_PASSWORD, DEFAULT_LATITUDE, DEFAULT_LONGITUDE, DEFAULT_ZOOM 等設定值,想要新增地圖服務,要修改 TILE_PROVIDERS 設定值,格式是 URL, tab, ServiceName。

其中離線編輯圖檔的工作,由 decoder/poll.py 執行,在 decoder/compose.py 檔案裡有 geotiff, print_url, preview_url 的處理函式,網頁顯示的主檔案在 site/templates/index.html.tpl,顯示 PDF 檔案的網頁模版在 site/templates/en/print-info.htmlf.tpl,處理 PDF 位置 (pdf_url) 的網頁在 site/lib/data.php,產生 PDF 檔案的程式碼在 site/lib/composition.php 裡,包括標頭文字:

$pdf = new FPDF( \
       get_page_orientation($print['paper']), \
       'pt', get_page_size($print['paper']));
$pdf->addPage();
...
$pdf->text(62.61, 68.49, 'Waling Papers');
...
$print['pdf_url'] = \
post_file("prints/{$print['id']}/walking-paper-{$print['id']}.pdf", \
          $pdf_content, 'application/pdf');

參考 FPDF 中文支援資訊。

2012/04/09

Running Plone Profiles On the Fly

想在執行 buildout 時,自動啟用或更新 Plone Site 的擴充模組設定值,可以藉助 collective.recipe.plonesite 來控制。下列是執行成功時的訊息範例:

Added Plone Site
Quick installing: []
Running profiles: []
Finished
Running profiles: ['first.product:default', 'second.product:default']

2012/04/07

Archetypes ReferenceField and Bidirectional References

Archetypes 的 ReferenceField 搭配 ReferenceBrowserWidget 可以選取參照項目,不過問題之一,是重複的有序項目只能被選擇一次。後來想出一個變通方法,是建立一組內容型別,第一個內容型別具備目錄屬性,用來包含另一個內容型別,花點工夫改善顯示方式就行。

接著按照範例,透過 reference_catalog 的 getBackReferences() 可以顯示 bidirectional reference 的結果,不過,除了直接記錄 reference 資訊的項目外,我們也想顯示上一層的資訊。

之前的討論裡提到,如果物件是繼承 Acquisition.Implicit 或 Acquisition.Explicit 而來,稱之為 Acquisition aware,它們就能使用 context.aq_parent 或 context.aq_inner 功能,除此之外的物件,要用下列的方法才行:

from Acquisition import aq_inner, aq_parent 
parent = aq_parent(aq_inner(context))

在 Products.ATContentTypes/skins/ATContentTypes/unittestGetTitleOf.py 看得到四種範例:

## Script (Python) "unittestGetTitleOf"
##title=Helper method for function tests
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=

return "%s,%s,%s,%s" % (
    context.title_or_id(),
    context.aq_parent.title_or_id(),
    context.aq_inner.title_or_id(),
    context.aq_inner.aq_parent.title_or_id())

2012/04/06

jQuery.fn.prepOverlay

jQuery prepOverlay 在 Plone 裡經常被使用,它是透過 plone.app.jquerytools 提供 AJAX form helper 服務,像 tile 就可以結合這項工具,提供更具彈性的版面設計。