2013年6月30日 星期日

iOS 開發筆記 - 簡易 TCP Socket Client 筆記

最近有需求需要從裝置發 socket request 到指定的 socket server 上,丟一串字串就結束連線。

簡易範例:
- (void)sentAMessageTo:(NSString *)server_ip port:(int)port message:(NSString *)message
{
    NSInputStream *inputStream;
    NSOutputStream *outputStream;
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)server_ip, port, &readStream, &writeStream);
    
    inputStream = (__bridge NSInputStream *)readStream;
    outputStream = (__bridge NSOutputStream *)writeStream;
    
    [inputStream open];
    [outputStream open];
    
    NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSASCIIStringEncoding]];
    [outputStream write:[data bytes] maxLength:[data length]];
    
    [outputStream close];
    [inputStream close];
}
此例應該算使用 ARC 方案吧,沒去管記憶體。

[Javascript] 處理新舊網站網址對應問題,以 PIXNET 與 Blogger 為例

PIXNET 公告版面

最近剛從 PIXNET 移到 Blogger 服務,對於之前在 PIXNET 的資料(流量)是否有好的解法呢?嘗試處理一下,的確有解 :)

問題:
  • 舊網站網址與新網站的規則不一樣:http://old_site/blog/post/xxxx 與 http://new_site/2013/06/oooo.html
因此,就算一開始在舊網站採用個人 domain name 網址也無法透過更改 DNS record 方式無痛切換到新網站。

解法:
當使用者逛舊網站時,引導使用者到新網站。由於新舊網站的文章標題一致,可以善用這個特性。
因此,可以透過 Javascript 來解決!先建立一份新網站文章標題與網址對應表後,在舊網站植入 Javascript 程式碼後,每當使用者逛舊網站文章時,當下動態取得文章標題後,查表取得新網站的網址,引導使用者切換過去即可。
PIXNET 公告版面

對 PIXNET 來說,它提供公告版面,這是個不錯的 javascript 植入位置。我將 Javascript 擺放在 github.com 這免費空間中,每當使用者在舊網站讀文章時,我在公告版面顯示新網站位置以及新網站此文章的網址,方便使用者點選,若測試無誤後,也可以考慮直接用 javascript 將使用者導向新網站。

有興趣的可以繼續參考:

[Python] 製作 Blogger 文章標題與網址對應表 (JSON Format) - 簡易 Blogger Crawler

有一些需要,想要知道 Blogger 文章標題與網址的對應,所以寫了隻 python 程式,撈了一遍 blogger 出來 XD 其實 Blogger 有提供 APIs 可以來做這件事 (https://www.googleapis.com/blogger/v2/blogs/blog-id/posts),但因為需要額外提出申請才行,就先快速用 blogger.com/search?max-results=50 的概念進行。

有興趣可以參考:github.com/changyy/blogger-title-link-crawler

使用 Github.com 散佈 Javascript 程式碼

github.com 有提供 raw 存取方式,但其 content type 並僅 text/plain 而已,這會影響 Javascript 的使用。幸運的,github.com 有提供 text/javascript 的存取方式

例如原先 raw 網址:

<script type="text/javascript" src="https://raw.github.com/changyy/note/master/new-site-url/url.js"></script>

僅需改成:

<script type="text/javascript" src="https://rawgithub.com/changyy/note/master/new-site-url/url.js"></script>

即可處理 content type 問題 :)

2013年6月29日 星期六

[Python] 使用 BeautifulSoup 處理 HTML 程式碼 (HTML Parser) @ Mac 10.8

繼上篇撈一些 HTML 資料回來,接著想要取出 link 來分析,則使用 python BeautifulSoup 套件。

$ sudo port install py27-beautifulsoup

片段程式碼:

from BeautifulSoup import BeautifulSoup
import urllib, urllib2

url = "http://blog.changyy.org"
data = urllib2.urlopen(url)
soup = BeautifulSoup(data)

for article in soup.findAll("div", {'class':'item-title'}):
    print "Title: " + article.a.contents[0]

    print "Link: " + article.a['href']
    print ""


運行結果:

$ python2.7 /tmp/t.py
Title: [Linux] 使用 sed 更新 PATH 環境變數 @ Ubuntu 12.04
Link: http://blog.changyy.org/2013/06/linux-sed-path-ubuntu-1204.html

Title: 致我們終將失去的熱情
Link: http://blog.changyy.org/2013/06/blog-post.html

Title: [Linux] 透過 busybox nc 提供簡易 socket server/client 測試方式
Link: http://blog.changyy.org/2013/06/linux-busybox-nc-socket-serverclient.html

Title: [Linux] 查看主機板型號 @ Ubuntu 12.04
Link: http://blog.changyy.org/2013/06/linux-ubuntu-1204.html

Title: blog.changyy.org 正式啓用
Link: http://blog.changyy.org/2013/06/blogchangyyorg.html

Title: [PHP] 使用 Heroku 架設 Wordpress 免費部落格
Link: http://blog.changyy.org/2013/05/php-heroku-wordpress.html

Title: [Python] 備份 Github.com 上的資料&#65288;可指定 user&#65289;@ Mac 10.8
Link: http://blog.changyy.org/2013/06/python-githubcom-user-mac-108.html

Title: 暮色&#12289;好星晴
Link: http://blog.changyy.org/2013/06/blog-post_24.html

Title: [Raspberry Pi] 使用 Raspbmc 之 AirPlay 播放影音 @ Mac 10.8
Link: http://blog.changyy.org/2013/06/raspberry-pi-raspbmc-airplay-mac-108.html

Title: Android 開發筆記 - 使用 mDNS 偵測裝置與 TXT record 處理方式 @ Mac 10.8
Link: http://blog.changyy.org/2013/05/android-mdns-txt-record-mac-108.html

[Python] 使用 zlib 處理 gzip 資料,以 curl 與 web 資料為例 @ Mac 10.8

抽空復習一下 Python ,想到用 Python 撈資料。

這時就先用了 pycurl 去跟 Web server 要資料,接著嘗試跟 Web server 要 gz 形態的資料回來,並使用 zlib 解掉。

範例:

import pycurl
import StringIO
import zlib

def getWebData(url):
    c = pycurl.Curl()
    c.setopt( pycurl.URL , url.encode('utf-8') )
    c.setopt( pycurl.FOLLOWLOCATION , True )
    c.setopt( pycurl.HTTPHEADER , [
        'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0',
        'Accept-Language: zh-tw,zh;q=0.8,en-us;q=0.5,en;q=0.3',
        'Accept-Encoding: gzip, deflate',
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    ])

    open('/tmp/pycurl','wb').close()
    c.setopt( pycurl.COOKIEFILE , '/tmp/pycurl' )
    c.setopt( pycurl.COOKIEJAR , '/tmp/pycurl' )

    b = StringIO.StringIO()
    h = StringIO.StringIO()

    c.setopt(pycurl.WRITEFUNCTION, b.write)
    c.setopt(pycurl.HEADERFUNCTION, h.write)

    c.perform()
    
    body = b.getvalue()
    b.close()
    header = h.getvalue()
    h.close()
    
    return {'header':header, 'body':body}


target = "http://blog.changyy.org"
#data = urllib2.urlopen(target)
data = zlib.decompress(getData(target)['body'], 16+zlib.MAX_WBITS)

print data


透過 pycurl 的 request header 指定 gzip 形態,收回來後,在用 zlib.decompress 解開來使用。

2013年6月26日 星期三

[Linux] 透過 busybox nc 提供簡易 socket server/client 測試方式

最近在整合嵌入式的環境,碰到 socket server/client 的模式,正在想有沒合適的測試方式,就發現了 busbox nc 的用法!在嵌入式環境中真的是超方便的。

$ busybox nc
BusyBox v1.18.5 (Ubuntu 1:1.18.5-1ubuntu4.1) multi-call binary.

Usage: nc [-iN] [-wN] [-l] [-p PORT] [-f FILE|IPADDR PORT] [-e PROG]

Open a pipe to IP:PORT or FILE

Options:
-e PROG Run PROG after connect
-l Listen mode, for inbound connects
(use -l twice with -e for persistent server)
-p PORT Local port
-w SEC Timeout for connect
-i SEC Delay interval for lines sent
-f FILE Use file (ala /dev/ttyS0) instead of network

簡言之,若是整合的程式是一隻 socket server,要走 socket 跟他溝通,這時就可以用 nc 指令測試,假設 server 跑在 port 55688,且 server 是 read 一段話後,去判斷那段話來做事,例如 play boy 好了,那這時只需用 nc 就可以模擬 socket 連線,可省去寫一段小程式來測驗:

$ echo "play boy" | busybox nc server_ip server_port

除了上述 client mode 外,其實 nc 也能當 server:

$ busybox nc -l -p server_port

能夠有這樣的測試方式真是太幸福了 XD

修正 ARM device hostname 為 (none) 問題

hostname (None)
手上有台裝置是 ARM-based Linux device,在其上頭執行 busybox hostname 的結果是 (none) ,原先以為只要更新 /etc/hostsname 後即可改善,但結果仍是不行的。

最後的解法是更新 /proc/sys/kernel/hostname 來處理,由於此例 (none) 的影響某些網路程式的判斷,主要是不 unique 的影響,故手動處理一下,其片段程式:

# update /proc/sys/kernel/hostname
checkhostname=`grep -i -c "(None)" /proc/sys/kernel/hostname`
if [ $checkhostname -gt 0 ]; then                        
newhostname=n$(echo $macaddress | sed 's/://g')            
echo $newhostname > /proc/sys/kernel/hostname        
fi

2013年6月25日 星期二

blog.changyy.org 正式啓用

byebye

前陣子下了決定買了 changyy.org,覺得在資訊業打滾了一會兒後,應該多多建立個人品牌,除了持續將恰當的東西放在 github.com/changyy 外,再買了一個 domain name 來用用,一年也不貴,在 www.namecheap.com 約 10 塊美金,說起來還比一些台灣 .tw 系列的便宜 Orz 真不知該說什麼...連 .com 也是這等價

接著,以為用了多年的部落格只需買一下一般 VIP 會員就能設定使用自己的 domain name ,事實證明我錯了("個人化網址"不是這個意思) Orz 基於需求的不滿,我就試用退費流程(慶幸用的是信用卡,退費無痛),便開始認真地思考搬家議題,把原先一直同步備份在 Blogger 的網站公開了,沒想到就這樣正式啟用了 XD

就這樣,要來適應新的文章撰寫環境了,至於程式碼的部分會在試看看,也可能大部份都擺在 github.com/changyy 吧!

雖然 Google Reader 剩幾天就收了,但這邊還是提一下,原本 Blogger 提供的訂閱位址,在 Google Reader 裡排版都會亂掉且沒法顯示圖片,所以我還是申請了 feeds.feedburner.com/changyyorg 來用用,還有興趣的可以改訂閱這邊,但有三分之一都在碎碎念!

至於部落格廣告嘛,就當作從搜尋引擎過來查資料的過路費吧 XDDD 可以拿來支援買 domain name 囉!

2013年6月24日 星期一

暮色、好星晴

2013/06/24 好星晴


多久沒抬頭望望天空呢?今日台北好星晴,下次不知何時能放鬆地望著天,把飛機的軌道當流星呢?(F1.8、5s、ISO100)


今天開完後賴著不走,遠端登入整理別人寫的 code ,弄一點簡單的 Daemon 雛形,忽然覺得好快樂啊,好久沒這輕鬆地邊寫邊學啊!希望能慢慢找回自己的步調!


2013年6月23日 星期日

[Raspberry Pi] 使用 Raspbmc 之 AirPlay 播放影音 @ Mac 10.8

Raspbmc-Pi AirPlay Enable


AirPlay 對 iOS Device 來說是個很美妙的東西且 Apple TV 獨秀的管道,從 iOS Device 將播放的影片透過 AirPlay 協定輸出到 Apple TV ,簡言之,你可以用 iPod touch、iPhone、iPad 甚至 Macbook 播放 PPS,然後嫌螢幕太小,而家裡剛好又有大螢幕,此時就透過 AirPlay 輸出到大螢幕上,學弟的老爸也特地買了 Apple TV 做這件事呢!


這次使用 Raspbmc 套件:


$ wget http://download.raspbmc.com/downloads/bin/filesystem/prebuilt/raspbmc-final.img.gz
$ cd ~/Downloads
$ gzip -d raspbmc-final.img.gz
$ diskutil list
...
/dev/disk1
  #:                       TYPE NAME                    SIZE       IDENTIFIER
  0:     FDisk_partition_scheme                        *7.7 GB     disk1
  1:             Windows_FAT_32                         58.7 MB    disk1s1
  2:                      Linux                         1.9 GB     disk1s2


$ sudo diskutil unmountDisk /dev/disk1
Unmount of all volumes on disk1 was successful
$ sudo time dd bs=1m if=raspbmc-final.img of=/dev/rdisk1
1300+0 records in
1300+0 records out
1363148800 bytes transferred in 269.010945 secs (5067261 bytes/sec)
  269.02 real         0.00 user         0.98 sys
$ sync
$ diskutil list
...
/dev/disk1
  #:                       TYPE NAME                    SIZE       IDENTIFIER
  0:     FDisk_partition_scheme                        *7.7 GB     disk1
  1:             Windows_FAT_32                         73.4 MB    disk1s1
  2:                      Linux                         1.3 GB     disk1s2
$ sudo diskutil unmountDisk /dev/disk1
Unmount of all volumes on disk1 was successful


Raspbmc-Pi


接著就把 Raspberry Pi 接上剛剛弄好的 SDCard、HDMI線、滑鼠(鍵盤倒可以不用)、網路(可用RJ45或USB wifi 網卡)跟 MicroUSB 電源線,就會看到畫面進入初始化的階段,如果是用 Wifi USB 的話,需要切進程式設定。而當有了網路後 Raspbmc 也能更新系統(是否進行kernel更新),那就擺一下讓他跑一會(大概需要25分鐘吧?)


更新前(藍色系):


Raspbmc-Pi


更新後(紅色系):


Raspbmc-Pi


大概設定完網路後,接著再啟用 AirPlay 功能:


系統設定 -> 服務 -> AirPlay 


最後就可以透過 iOS device 進行 Airplay 輸出到螢幕啦!如果你的螢幕不支援 HDMI,但是跟我一樣是透過轉接頭 (DVI-I) 轉換的,那會碰到音源輸出的問題,所幸這也能解決,在播放過程中,移動滑鼠就可以看到下面有聲音的icon,點選後可以選擇音源輸出,此例採用"類比"輸出,並記得把 Raspberry Pi 接上喇叭(或螢幕支援的小喇叭),這樣就能享受 AirPlay 了


在 Raspbmc 界面打滾一番,發現他做了不少東西,包含提供 HTML5 的 remote player,也有紅外線遙控等(大概要外接USB IR receiver),服務方面還有 FTP、網路芳鄰等,說真的還滿完整的。美中不足的是 AirPlay 在 PPS 等相關 iOS app 內不順,但在 Youtube app 上倒很 OK。


Raspbmc Web Controller


2013年6月22日 星期六

ACER Aspire 4810TZG 拆卸硬碟

4810TZG-04


這幾年比較有裝置可以把玩,就拆拆看,原先還看不太懂,研究後覺的設計的也還不錯啦!


拆機流程,大概就看到那邊有個黑色塑膠片,提起來就行了


4810TZG-01


4810TZG-02


[OSX] MacBook Pro 更換硬碟、查看硬碟傳輸速度 @ Mac 10.8

MBP-HDD-T型


原先添購的 1TB 硬碟是要給舊筆電用的,卻意外不合,就...轉給 MBP 使用了。由於新購那顆有支援 SATA III ,故查閱一下自己這台 MBP 13" 2011 late 是否有支援。


螢幕快照 2013-06-22 下午2.41.10


查證方式很簡單,只要從左上角 -> 關於這台 Mac -> 更多資訊 -> 系統報告 -> 硬體 -> Serial-ATA:


連結速度:MBP 裝置支援的最高速度,其中 SATA3 = 60億位元、SATA2 = 30億位元等


協調的連結速度:硬碟與 MBP 溝通的真正速度


故上頭的那張圖是原先買 MBP 的內建硬碟,僅 SATA2 等級,接著更換後:


螢幕快照 2013-06-22 下午4.21.18


就看得出來有 SATA3 的等級啦!不過更換硬碟又是一門學位,因為 MBP 真的安置硬碟太好了,還需要特別的T型螺絲起子,所幸在附近傳統百貨五金店花了 99 元舊買到了!此次使用 T-6 大小:


tools


2013年6月16日 星期日

[Python] 備份 Github.com 上的資料(可指定 user)@ Mac 10.8

github-backup-routine;


最近在 github.com 上弄了些程式,想說也該備份一下。所以順手寫了隻 script,可定期把 github 的資料備份(git clone/git pull)下來。有興趣可以逛逛 changyy / github-backup-routine.git,記得執行前要把 username 換掉 XD 


[Python] 從 PIXNET 匯入 Blogger 心得 (MT to XML & Blogger Import) @ Mac 10.8

blogger import


最近 PIXNET 的變化不少,不少人都開始搬家了,我雖然還沒搬家的 fu (覺得要重弄CSS很煩XD)也覺得 PIXNET 在某些技術上還是領先群雄,但不免要先試用一下搬家功能 XDDD 當年挑選 PIXNET 的主因除了年輕、活力又熱血的工程師,最大的考量是支援部落格匯入匯出功能(MT格式),讓我能夠時時備份資料,當初為了 portable 的關係,至今並沒有使用 PIXNET 相簿的功能,完全用 flickr (好像賭對了 XD 當年 flickr 就可以無限量丟圖當免空使用,只是官網瀏覽時僅能看到最後200張,但其他圖只要有連結仍看的到),這樣的好處是一樣的文章我拿去其他家發表時(或是被盜文 XD),圖不受影響(只是前陣子發現有些圖被鎖了?不知是不是流量還是我之前用 flickr 手殘不小心鎖到,總之已經都修正)


blogtrans


回歸主題,接著我就開始著手嘗試匯入到 blogger 的流程,並透過 BlogTrans (修改版) 將 MT 格式轉成 XML 格式。然而開始碰到奇妙的問題了,例如 Blogger 一次只能匯入 300 篇,後我就開始想能不能分批匯入?於是就修改 blogtrans 讓他可以指定文章的起始、blogger 網址、作者名字跟是否匯出留言等(當初可能為了開發方便,所以這邊都是寫死的資訊,擔心是不是這樣影響匯入功能)


article end article begin skip comment


試了一卡車後,還真的如網友說的,有時要挑離峰時間來使用就能正常匯入了 XDDD 所以,我認為修改版的最佳功能是指定匯出文章的範圍,如從第 301 篇到 500 篇,這樣至少可以批次匯入 :) 此外,Blogger Import 不必擔心匯入同樣的文章,因為每篇文章都有個 ID 辨識(程式有寫好的話),故 Blogger 會幫你 skip 掉。


另外,我在 wordpress 嘗試用 MT 跟 XML 格式匯入還沒成功過 XDD 但自己架的 wordpress 倒沒問題!嗯,其實 PIXNET 也很努力的活著,只不過這類服務背後若沒強而有力的金主,漸漸地為了生存將會改變許多,不少使用者就會發現與當初挑 PIXNET 的初衷開始矛盾就外移。


此外,若要更 portable 的話,應該要申請一下 domain name ,只是一些 url 規則不是換過去就行了 Orz 且不同 domain 在 search engine ranking 上分數也是不一樣的唷(簡稱可能換了 domain 後,搜尋的排名變高或變低)


2013年6月13日 星期四

[Linux] 使用 sed 更新 PATH 環境變數 @ Ubuntu 12.04

以前還滿常用 PATH="$PATH:/path/bin" 的方式進行更新,但不知為何在 /etc/environment 會出錯?如:


PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
PATH="$PATH:/path/bin"


登入後 echo $PATH 會僅剩 /path/bin,不知是不是沒 export PATH 的關係?暫時先用 sed 來處理這段:


$ sed 's/^PATH="\(.*\)"/PATH="\1:\/path\/bin"/g' /etc/environment > /tmp/environment
$ mv /tmp/environment /etc/environment


[Linux] 查看主機板型號 @ Ubuntu 12.04

查詢主機板資訊:


$ sudo dmidecode -t 2


# dmidecode 2.11
SMBIOS 2.6 present.


Handle 0x0002, DMI type 2, 15 bytes
Base Board Information
    Manufacturer: ASUSTeK Computer INC.
    Product Name: P8H61-M PLUS V2
    Version: Rev x.0x
    ....


 


更多豐富的資料:


$ sudo lshw


[Linux] 修正 xRDP 遠端登入空白桌面的問題 @ Ubuntu 12.04

xRDP

最近有一台比較有力的機器,主要是安裝 Ubuntu 12.04 Desktop 版,想說趁它還沒那麼忙時,在上頭跑跑 Virtualbox 玩玩,就想到該怎樣使用它的問題,第一個則是遠端登入的方式,試過了 VNC 後,發現一開始沒登入還不能用,所以就改用 xRDP !但登入後卻只能看到一片空白的桌面,於是找了一下解法(Ubuntu 12.10 xrdp gets blank screen at login),筆記一下。

解法:

$ sudo apt-get install xrdp gnome-session-fallback
$ echo "gnome-session --session=gnome" > ~/.xsession
$ sudo vim /etc/xrdp/startwm.sh  (
#. /etc/X11/Xsession
if [ -e $HOME/.xsession ]; then
. $HOME/.xsession
else
. /etc/X11/Xsession
fi
$ sudo /etc/init.d/xrdp restart

此外,如果希望連線過程有加密的效果,可以考慮 ssh tunnel 的用法:

$ ssh -N -L 3389:localhost:3389 remote_server_ip

之後就可以用 RDP 遠端桌面連 localhost 即可

若龜毛一點想要更安全一點,那就用 iptables 擋掉外面來進來 3389,僅允許從 localhost 過來的:

#!/bin/sh

# BIN
BIN_IPTABLES=`which iptables`

# reset rules
$BIN_IPTABLES -F
$BIN_IPTABLES -X
$BIN_IPTABLES -Z

# vnc, rdp: use ssh tunnel

$BIN_IPTABLES -A INPUT -i eth0 -p tcp --dport 5900 -j DROP
$BIN_IPTABLES -A INPUT -i eth0 -p tcp --dport 3389 -j DROP

2013年6月12日 星期三

[Python] Blogger XML Parser @ Mac OS X 10.8.4

最近試了 blogtrans (稍微修改版) 將 PIXNET 網誌備份格式從 MT 轉成 XML 格式,順便研究一下,所以就需要有一支 parser 來處理。


找了一下,在 python 套件中有一套 feedparser 可以使用,十分方便:


$ sudo port install py27-feedparser


用法:


$ ipython
Python 2.7.5 (default, May 28 2013, 22:38:37)
Type "copyright", "credits" or "license" for more information.


IPython 0.13.2 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.


In [1]: import feedparser


In [2]: xml = feedparser.parse('/tmp/test.xml')


In [3]: xml.entries[0].keys()
Out[3]:
['updated',
 'updated_parsed',
 'published_parsed',
 'tags',
 'title',
 'links',
 'summary',
 'content',
 'guidislink',
 'title_detail',
 'href',
 'link',
 'author',
 'published',
 'authors',
 'author_detail',
 'id']


In [4]: for e in xml.entries:
    ...:      print e.title
    ...:


2013年6月11日 星期二

致我們終將失去的熱情

2013/06/10


青春不再,熱血難耐


最近周邊的情感像極了以前當兵的時候,雖被條款限制在同一艄船上,彼此的方向並不同,隨著船長給予的酒肉短暫狂歡。出了社會後,發現這樣的現象並沒減少反而更加鮮明,同濟之間漸漸地用薪資來衡量未來,似乎年紀增長後,這是回憶起來最不浪費青春的方式吧?盡管現實,但也漸漸地在想自己何時也會掉落到這樣的漩渦呢。


致青春,雖不常在,相繫的可能是生存壓力、往日情感、抑或一丁點的夢想也罷,都該持續珍惜 :)


2013年6月7日 星期五

有感科技業 大陸(上海) VS. 台灣(台北)?



This is Shanghai from Rob Whitworth on Vimeo.

最近跟一位上海 RD 聊了幾句,普遍都說上海在硬體跟消費水平都已超越台灣,說起來大概只剩人文素質或福利相關的部份,聽起來滿感慨的。簡言之,硬體不用說,可以看看影片,消費的話大概比台北貴 30% ,至於人文素質,舉個例就是過馬路要十分小心 XD 據說早期大家出手都很闊,甚至全身穿滿家當,但回家依舊苦哈哈,現況不太清楚,至於暴發戶是政策的關係,例如一胎化導致小孩繼承很多家當,而政府在推動城市時,在都更時用兩間房換一間房的機制,導致換了房後可以收房租過生活,更別說上海被炒起來的價碼,更別說一胎化小孩繼承爸媽、爺奶的房子個數,可能一次就來個 3~4 房呢。

除此之外,這邊要提的則是像機上盒這類科技產業,據在大陸工作 5 年的 RD 分享,台灣了不起就 3000 萬人口,最大咖的就中x電信,最了不起的就 500 萬用戶,在怎樣算也了不起 50 萬台機上盒,在怎樣每年頂多更換 50% 的數量。在大陸隨便一個省就拼過台灣了 Orz 這也就是台灣科技業漸漸也不把台灣放重心的主因,想起來也滿感傷的。

瞧,一年只有 20 萬台的業績,要跟大陸百萬甚至千萬台的量拼,誰會留意台灣啊?

最近在接觸類似機上盒的產業,我發現搞硬體的軟體並非寫的差,倒是因為多了硬體這個維度後,根本沒其他精力去把軟體寫好 Orz 若熟 Web service 的話,應該很清楚只要去把 backend service 、 ui/ux 等的弄好,一切建立在穩當當的 x86 平台,但機上盒底下可能是 MIPS 、可能是 ARM 等類的,一堆應用程式本身都不是為他們設計的,先別說 porting 的痛苦感,連合作硬體穩不穩都是嚴重的問題,還得靠別人家的 SDK 才能生存下去(有沒bug又是另一個故事了),在這樣的環境上,很難會有心力把軟體寫好,或則說,心力都花在搞好硬體上面了

想著想著,覺得從 web service 跨到 embedded 行業,可以有另一層的體驗,那種感覺若要以當紅的 mobile app 來說,那就接近寫 ios app 跟 android app 的差別,在 ios app 硬體環境明確,但 android app 硬體環境不明確,導致在 ios device 上可以有一致的體驗,而 andorid app 很難或要花更多精力才能達成的啊

2013年6月1日 星期六

[PHP] 使用 Heroku 架設 Wordpress 免費部落格


最近大家對 PIXNET 部落格發展方向似乎有不少負面聲音,對我而言倒是還好,但也抽空嘗試其他家服務,其中看到一篇文章:Hosting a WordPress Blog on Heroku with the Svbtle Theme for free ,挺有意思的,就是試了一下。試完的結果是...免費的空間不夠用 XD


根據 Heroku Postgres Basic Plan and Row Limits @ 2012/07/16


Accompanying this announcement is the implementation of a 10,000 row limit on the dev plan. This row limit was designed to correspond to the 5mb limit on the existing free shared plan.


以此 Blog 為例,進行匯入時最後只匯了約 400 篇文章,然後機器就連不到了 XDD:


$ heroku pg:info
=== HEROKU_POSTGRESQL_XXX_URL (DATABASE_URL)
Plan: Dev
Status: available
Connections: 1
PG Version: 9.2.4
Created: 2013-06-01 13:57 UTC
Data Size: 10.4 MB
Tables: 11
Rows: 1584/10000 (In compliance)
Fork/Follow: Unsupported


大概是我比較愛打字 XD 所以使用 Heroku 免費架 Blog 的方案不適合我,但 5MB size & 10000 rows 倒還可以用在其他應用囉 :D


剩下是此次操作方式:


$ git clone git://github.com/webjames/heroku-wordpress-svbtle.git
Cloning into 'heroku-wordpress-svbtle'...
remote: Counting objects: 1447, done.
remote: Compressing objects: 100% (1286/1286), done.
remote: Total 1447 (delta 130), reused 1428 (delta 120)
Receiving objects: 100% (1447/1447), 7.00 MiB | 1.16 MiB/s, done.
Resolving deltas: 100% (130/130), done.


$ cd heroku-wordpress-svbtle


$ heroku create
Creating xxxx-xxx-####... done, stack is cedar
http://xxxx-xxx-####.herokuapp.com/ | git@heroku.com:xxxx-xxx-####.git
Git remote heroku added


$ heroku addons:add heroku-postgresql:dev
Adding heroku-postgresql:dev on xxxx-xxx-####... done, v3 (free)
Attached as HEROKU_POSTGRESQL_RED_URL
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pgbackups:restore.
Use `heroku addons:docs heroku-postgresql:dev` to view documentation.


$ heroku pg:promote HEROKU_POSTGRESQL_RED
Promoting HEROKU_POSTGRESQL_RED_URL to DATABASE_URL... done


$ git checkout -b production
Switched to a new branch 'production'


$ cp wp-config-sample.php wp-config.php
$ >.gitignore
$ git add .
$ git commit -m "Initial WordPress commit"
[production #######] Initial WordPress commit
2 files changed, 93 insertions(+)
create mode 100644 .gitignore
create mode 100755 wp-config.php


$ git push heroku production:master
Counting objects: 1450, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (1278/1278), done.
Writing objects: 100% (1450/1450), 7.00 MiB | 173 KiB/s, done.
Total 1450 (delta 132), reused 1445 (delta 130)


-----> PHP app detected
-----> Bundling Apache version 2.2.22
-----> Bundling PHP version 5.3.10
-----> Discovering process types
Procfile declares types -> (none)
Default types for PHP -> web


-----> Compiled slug size: 16.0MB
-----> Launching... done, v6
http://xxxx-xxx-####.herokuapp.com deployed to Heroku


To git@heroku.com:xxxx-xxx-####.git
* [new branch] production -> master


其他部分:


將 Wordpress 設定為必須登入才能看到文章:


$ cat wp-blog-header.php
<?php
/**
* Loads the WordPress environment and template.
*
* @package WordPress
*/
if ( !isset($wp_did_header) ) {


  $wp_did_header = true;


  require_once( dirname(__FILE__) . '/wp-load.php' );


  if ( !is_user_logged_in() ) {   // 太久沒用 wordpress ,印象中有選項可以設定:限定登入才能看到文章
    auth_redirect();
    exit;
  }


  wp();


  require_once( ABSPATH . WPINC . '/template-loader.php' );


}


啟用 MT 匯入功能:


$ wget -qO- http://downloads.wordpress.org/plugin/movabletype-importer.zip | tar -xvf - -C wp-content/plugins/
$ git add .
$ git commit -am 'add movabletype-importer plugin'
$ git push heroku production:master


由於 heroku 僅能上傳 2MB 大小的檔案,若你的 Blog 之 MT 備份檔超過 2MB 的話,可以擺在 blog site 匯入。


$ cp /path/you_blog_backup.txt wp-content/mt-export.txt
$ git add .
$ git commit -am 'add mt-export.txt'
$ git push heroku production:master


接著就可以去後台管理來匯入資料。