2015年5月4日 星期一

GAE 筆記 - 將 Google App Engine 之儲存資料 DataStore 匯出處理

前陣子寫小的程式不斷地將資料儲存起來,最近想處理一下,打算用 offline 的方式處理。接著就是要把資料先匯出,再用程式分析每筆資料。

匯出方式很簡單,只需到 Google App Engine -> Application -> YourApp -> Data -> Datastore Admin -> 勾選想要的資料表(Entities) -> Backup Entities ,不一會兒就可看到 Backups 有資料了。

接著是下載方式,有一派是說用 gsutils ,但我沒試成功,可能跟 gsutils 使用時機有關,我則是透過網頁把各個檔案下載來使用:Google App Engine -> Application -> YourApp -> Data -> Blob Viewer -> 可看到幾個小檔資料,就簡易人工點擊下載。

最後,寫簡單的程式來分析吧:

import webapp2

from google.appengine.api.files import records
from google.appengine.datastore import entity_pb
from google.appengine.api import datastore

class MainPage(webapp2.RequestHandler):
        def get(self):
                self.response.headers['Content-Type'] = 'text/plain'
                for record in records.RecordsReader(open('file-part-1', 'r')):
                        entity_proto = entity_pb.EntityProto(contents=record)
                        entity = datastore.Entity.FromPb(entity_proto)
                        self.response.write(entity)

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

2015年4月28日 星期二

AWS 筆記 - 關於 Load Balancers 之 Health Check 處理心得

若是 web server,通常 Health check 都是定期去請求 /index.html 是否正常,以此來判斷服務是否正常。而檢查 /index.html 有很多含義,例如當 server response time 超過 10 秒,也能標記為不正常等。

最近碰到一個案例,是在處理外包案時,發現對 / 或 /index.html 時,一直不正常,但用瀏覽器去看又覺得無恙,例如用 wget -d 也行,最後發現用 telnet 看到問題 XD

$ telnet server_ip 80
GET / 或 GET /index.html


接著看到一些 PHP 噴 error message。

發現,外包在一些設定檔內,透過判斷 $_SERVER['HTTP_HOST'] 是不是他們家的 server ,以此決定開啟 debug mode。

<?php
if ($_SERVER['HTTP_HOST'] == 'xxx.yyy.com') {
    $is_test_server = true;
} else {
    $is_test_server = false;
}


這件事大概只能透過 telnet 等不送 HTTP header 要求時,才會發現的 bug。這個 bug 還滿好解的,例如加上一些 isset($_SERVER['HTTP_HOST']) 等,但有一些 PHP framework 使用上會要求提供網址位置,例如:

<?php
$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
$config['base_url'] = $protocol . '://' . $_SERVER['HTTP_HOST'] . '/';


這時又只能再爆一次。若有心解決,就繼續改 code ,無心解決的話,可以把一些 error message 都關掉,或是把 Health check 改成 TCP 80 模式吧 XD

2015年4月27日 星期一

透過 Script 合併 MPEG2-TS (Transport Stream / TS) 與 ffmpeg 轉檔

因緣際會,處理一些用 M3U 串起來的一堆瑣碎的 .ts 檔案,這些檔案透過 M3U 的格式,可清楚描述第幾秒要播放哪個片段。然而,在一些測試上會略顯麻煩 Orz 所以撰寫一些 script 跟 ffmpeg 來把這些東西在整合成單一檔案 :P

眾多 ts 檔案該怎樣合併成一則?其實單純用 file append 即可:

$ cat 1.ts 2.ts 3.ts > output.ts

所以,假設有一個 M3U 時,可以透過以下指令抓出:

$ grep -v "#" list.m3u | xargs
1.ts 2.ts 3.ts ...


可惜啊,資料比數太 command line 可能會出爆,建議改用 script 來處理,例如 PHP:

<?php
foreach(explode("\n", file_get_contents($m3u_input)) as $line) {
if (empty($line) || $line[0] == '#')
continue;
$raw = file_get_contents($file);
if (!empty($raw))
file_put_contents("$output.raw", $raw, FILE_APPEND);
}


如此一來,就可以把一票 .ts 檔重新建立成單一檔案 .raw 。接著,再用 ffmpeg 轉成想要測試的格式吧!關於 ts 轉 mp4 ,可以透過 ffmepg 處理,其中 ffmpeg 會自己判斷輸出的格式(此例是 mp4),所以有需要也可以用 output.avi:

$ ffmpeg -i input.ts -vcodec copy -acodec copy output.mp4
$ ffmpeg -i input.ts -vcodec copy -acodec copy -bsf:a aac_adtstoasc output.mp4


如果有一票目錄 + M3U 的話,就掃一下目錄建立一票相關的,接著可以用 find 再把這一票轉一轉:

$ find . -name "*.raw" -exec  ffmpeg -i {} -vcodec copy -acodec copy -bsf:a aac_adtstoasc {}.mp4 \;

2015年4月25日 星期六

PHP CodeIgniter - 使用 Memcached

官方文件寫得很簡單,簡單的無法看懂:

@ https://ellislab.com/codeigniter/user-guide/libraries/caching.html
$this->load->driver('cache');
$this->cache->memcached->save('foo', 'bar', 10);


後來我自己去 trace 原始碼才知道該怎樣設定跟測試。首先,新增一個設定檔:

$ vim application/config/memcached.php
$config['memcached'] = array(
        'hostname' => 'Your_memecached_cluster',
        'port' => 11211,
        'weight' => 1
);


接著,使用:

class My_Library {
public function __construct() {
$this->ci =& get_instance();
$this->init();
}
public function init() {
$this->ci->load->driver('cache');
return $this->ci->cache->is_supported('memcached');
}
public function set($key, $value, $tts) {
return $this->ci->cache->memcached->save($key, $value, $tts);
}
public function delete($key) {
$this->ci->cache->memcached->delete($key);
}
}


關鍵之處就是要呼叫 $this->ci->cache->is_supported('memcached') 這段,才會從 application/config/memcached.php 把資訊更新進來 Orz

若需要 debug 的話:

$ find . -name "*mem*"
./system/libraries/Cache/drivers/Cache_memcached.php


找到 $this->_memcached 可以善用它,例如 $this->_memcached->getResultCode();

2015年4月21日 星期二

iOS 開發筆記 - 製作 iOS Simulator app 版本送交給 Facebook 進行 review (creating-ios-simulator-build-for-review)

似乎...Facebook SDK 文件沒找到?只好隨意 Google 一些資料

$ cd /path/project
$ xcodebuild -showsdks
OS X SDKs:
OS X 10.9                     -sdk macosx10.9
OS X 10.10                     -sdk macosx10.10

iOS SDKs:
iOS 8.3                       -sdk iphoneos8.3

iOS Simulator SDKs:
Simulator - iOS 8.3           -sdk iphonesimulator8.3

$ xcodebuild -arch i386 -sdk iphonesimulator8.3


若用 CocoaPods (碰到 ld: library not found for -lPods-XXX ) 或 xcworkspace 維護的,需要多一點指令:

$ xcodebuild -arch i386 -sdk iphonesimulator8.3 -workspace YourName.xcworkspace -scheme YourName

接著,想執行看看:

$ ios-sim launch /Users/user/Library/Developer/Xcode/DerivedData/YourName-xxxxxx/Build/Products/Debug-iphonesimulator/YourName.app

其中 ios-sim 可以逛一下這邊:https://github.com/phonegap/ios-sim