星期四, 11月 01, 2012

[jQuery] Deferred Object : Callbacks

  最近在玩 NodeJS, 然後由於 NodeJS 有child_process的操作, 不過卻都是 non-blocking的東西. 所以如果需要blocking的功能的話, 就會需要額外處理. 這時候就會想要試看看 Deferred 或是Promise 的概念, 這物件的概念代表的是當你的程序執行B是要等待A完成,再接著執行, 這聽起來Javascript 基本上都是用callback function去完成.但是callback function 太過繁瑣,而且完成的程式碼會一層包一層包一層包一層(如果有很多程序互相相關).

  就覺得應該要來看看啥是 Deferred 物件. 跑去看 Vexe'd 先生的 jQuery Deferred Object . 裏頭說道去看 jQuery 原始碼 (搜尋 Deferred: ), 發現一堆啥Callbacks("once memory").  才發現要從源頭理解 Deferred 物件運作原理,就得先從 jQuery.Callbacks下手.

  當然先從官方文件著手.大概涵義翻譯一下, 主要是提供一個callback list object, 在這個callback list object當中,我先介紹最基礎的四項操作.

  1. callbacks.add()       - 新增callback function 到 list 當中.
  2. callbacks.remove()  - 同理,就是從callback list 移除callback function.
  3. callbacks.fire()        -  觸發callback list當中的function.
  4. callbacks.disable()   -  取消掉任何之後對此callback list object 的事件觸發, fire()
  操作就是這四個動作, 然後再衍伸還有四個 Support Flags組合, 我下面使用官方案例配上 Fiddle來實作,應該會好理解很多. (按下F12開啟 debug console)


  1. 範例1 - 無任何Support Flags. 有啥東西在 callback list object 就fire()!
  2. 範例2 - once 確保這個callback list只會被fire()一次.如範例, 第一次fire()之後, 第二個fire並不會被觸發.
  3. 範例3 - memory  這個 Flags比較有趣一點, 如果新增了一個callback function之後,他會立刻觸發 fire() , 然後在觸發新的值.在範例當中看2nd add 以及 2nd  fire以及比對下方沒有設定Support Flags的執行情況,就可以很明顯知道差別.
    (在Deferred 原始碼看到很多once 跟memory的組合用法, 之後再深入理解Deferred物件後應該會知道這樣時做的原因吧.)
  4. 範例4 - unique 概念很簡單, 就是重複的callback function將只會執行一次!
  5. 範例5 - stopOnFalse 概念也不難,就是遇到 callback function回傳false時候,中斷其執行.
  說到這裡, 對於Callbacks的概念也有點清楚了, 接下來就是這些Flag交互使用, 以Deferred 物件,最常用的就是once 以及 memory. 直接翻 jQuery 的Deferred 物件.

 Deferred: function( func ) {
  var doneList = jQuery.Callbacks( "once memory" ),
      failList = jQuery.Callbacks( "once memory" ),
      progressList = jQuery.Callbacks( "memory" ),

  這邊有三個 list : doneList, failList 以及progressList. 其中doneList 跟failList 都是 once 以及memory. 稍微做了一下範例實驗, 確保doneList 跟failList 只會被若增加新的 callback function都會執行, 但是最多只能fire() 一次內容. 而 progressList 則是每次有新的callback function加入都會觸發之外, 還可以被fire() 多次.

  目前就先就 jQuery.Callbacks做個簡單介紹, 之後會進入jQuery.Deferred 物件以及Promise()方法, 這可是之後語言幾乎都會參考的一部分程式碼啊!



星期五, 10月 19, 2012

[LOGO] 小莊標誌 - Designed by Arzon



  各位好, 之前有跟大家聊到電台的事情 (沒看到的話請看[Radio][Linux] 小莊電台 這篇文章), 這次要說到的事情也是因為架設了電台後才有的發想! 就是所謂的個人標誌 (Personal Logo). 最近偶爾會參加一些聚會,會看到很多箇中好手都會有自己形象的標誌. 我這種愛玩的人當然也會想要有一個辨識度高的標誌. 剛好也認識設計師好友 Arzon. 就請他設計了我的Logo!

  一開始是我先發想我的構思, 我們列出幾個要點
  1. 泛用度     - 是電台使用,還是要作為個人標誌使用? 
  2. 風格設計 - 極簡風格,或是要漫畫風等等風格? 
  3. 設計限制 - 不要太多筆畫, 顏色限制在三個顏色當中, 色調避免使用粉色系.
   這邊我要提一下設計限制, 撇開不合理的限制要求不提, 其實客戶提供設計限制是很重要, 因為有限制的設計代表你對自己的需求有思考過, 很多客戶在開需求的時候都沒有限制, 這其實代表的意義是,客戶沒有實際思考過自己想要什麼? 只是在那邊看到設計師設計出來東西客戶看了不爽而吹毛求疵而已.然後到最後時間來不及了,選了之前一開始打槍的初稿,來證明這人是豬頭. 在這邊我就很明確訂出我的限制!談好價格之後就開始進入實際設計過程.
   
    第一步設計師 Arzon提供了幾個草稿給我, 我會思考是不是我喜歡的方向. 漸漸就先定下來最基礎的原型, 包括核心設計, 要不要底色, 字是用縮寫還是全部寫出來.

第一版設計XDDD

  第一版的設計是草稿, 並不需要非常精緻.後來我也很細的提出我自己的需求, 像是名字用全名. 中間希望有機器人的感覺等等等.之後第二版就出來囉!

第二版設計

   第二版設計老實說就已經很細緻了, 下來就真的是一些設計師的細節, 以及我自己的期望.多細節呢? 包括腳要不要翹起來, 莊的艹頭所佔高度比例, 粗細寬度,設計細節到1像素在算的. 等大致底定之後 Arzon 開始配色碼, 所以就有下面...



 
很酷吧! 我自己最喜歡咖啡色這個! 他還幫我設計了在衣服上,以及在鑰匙圈的應用!

   在這邊真的要給大家一個很重要的觀念, 設計並不是免費的, 就如同黑暗騎士電影當中 Joker說的 "If you are good at something never do it for free.".反過來就是說,
"If you want something good, please pay for it". 就如設計界最有名的比稿.下面影片有很有趣的說明:

你能把100個律師叫來寫你的遺囑, 然後只給其中一個人錢麼?

  如果各位喜歡這風格, 想要有自己的標誌的話, 這是Arzon的社群,被設計工作者Arzon碎碎念. 歡迎各位找他在討論細節囉! 另外我po一下我自己覺得很不錯的幾位朋友的標誌設計.


前端工程師蔡秉諺先生的標誌 


軟體工程師大貓的標誌



星期三, 10月 03, 2012

[Radio][Linux] 小莊電台

小莊電台

緣起 : 自己以前就喜歡聽相聲, 也對電台很有興趣. 研究所時代就曾經使用學術資源架設, 出社會就想要重溫舊夢. 架設一個不營利的電台分享音樂.

已有資源 :

  • 一台 Pentium 4 , 512 SDRam Notebook (變壓器損毀). 250GB 硬碟. 
  • 1.5M CATV 寬頻.


缺少硬體資源 : 變壓器 (感謝肥貓支援)

軟體資源 :

  • OS :  Ubuntu 12 server console (很穩!)
  • Casting Server : Icecast
  • Source Client   : ices
    • 限制 - 只能撥放 ogg stream, mp3 需要轉檔.

架構 :







門檻值評估 :
  • CPU? RAM? Network?
  • 目前算過 Network 應該為最大門檻, 以 64kb 來算, 大概能承受最多 20 個 Client.
系統便利以及持續性運作 :
#!/bin/bash
find /home/kevin/music -type f -name "*.ogg" -exec ls -1 {} \; 2> ./log/output | sort >playlist.txt

  • 使用 Crontab 排程每禮拜 2 早上五點重開, 並且撰寫 Shell Script 置於 Ubuntu 的自動啟動程序所以服務.
  • 自動更新 DNS, 使用 FreeDNS 的 CURL 更新 DNS 指令.


目前問題 :
  • 偶發切換曲目時候使用者斷線, 必須要重連
  • ISP 可能跟中華電信之間有些問題, 一些朋友無法上來當 DJ. (請不要發 Ticket 給我)
  • 亂碼問題 (ID3 以及簡體中文檔名)

未來展望 :
  • 希望能有電台 DJ 加入!..


星期一, 8月 20, 2012

[git] tag checkout memo

Checkout a repository into your Github: (we fork yui3 into our github)
git@github.com:miiicasa/yui3.git

Checkout to your local repository.
git checkout git@github.com:miiicasa/yui3.git somefolder
or
git submodule add git@github.com:miiicasa/yui3.git somefolder

List all tag (go to somefolder):
git tag -l

Checkout tag:
git checkout "v3.6.0"

It will info you that the repository was detached from master.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

Checkout as a branch:
git checkout -b "v3.6.0"

星期五, 7月 20, 2012

[css] z-index test memo.

  所謂 z-index就是個靠爸的東西, 因為不管你的 z-index設定的多高, 跟別人比在一起只要你老爸(parent)的 z-index輸人家一節,你就很難翻身啦.XDD

  以下面案例來舉例:

Check out this Pen!

  我設定了幾個物件: bd, bd下的 draw; ft,  ft下的 img. 而 bd與 ft同一層(意味著兩著互相比較z-index).

  然後設定 bd: z-index為1, ft為2 ( ft比bd高); draw為3, img為-1.
  由此可知道最不成材的就是 img,可是!可是怎麼看他都是在最上層啊!(各位看官可以把img的top改為0,仍然會在ft的上層.

由此可知身為draw的你不管再怎樣努力,都比不過ft底下的img啊!

  而且物件生成的順序也會決定他的 z-index, 若我都設定 bd跟 ft為-1, 由於 ft較 bd後呈現, 所以 layer仍然比較高, 這樣一比較 img仍然比 draw來的高阿.

<div class="content">
    <div class="bd">
        <div class="draw"></div>        
    </div>
    <div class="ft">
        <img src="http://avekta.com/site2/wp-content/uploads/2011/10/ico_fb.png" />
    </div>
</div>Check out this Pen!


Check out this Pen!

[Youtube][JavaScript] How to get Youtube Streaming URL, subtitle and resolution.

[ 2012/9/27更新 ]

  Youtube 在擷取影音串流多將原本的 sig參數改為 signature,但是在取得 Video Information的網址並沒有跟著修改,我參照了 youtube-dl的改法將 parse的規則改了一下,應該就過囉.只是不知道何時會再修改就是了.
記錄在下方這個commit.
https://github.com/kvzhuang/video-parser/commit/1d2c6cb7b5de852951d1eaf8153a6e0ee984409a


  最近因為一些需求在研究youtube的影音串流網址,其目的就是有一個 youtube影片的URL,最後得到此影片真實的影音串流.

  分做三個部分:取得youtube的原始影音串流,取得字幕檔,處理解析度.


影音串流:
  首先是先研究 Python的 youtube-dl ,目的是傳入一個 youtube的影片網址然後取得其真實的影音串流,思考方式是設置一個 API Server,當有使用者送出 Request後,透過 youtube-dl取得影片的資訊,可以選擇格式下載檔案( FLV,  MP4..包括 srt字幕檔案),或是取得影音串流 URL並且回傳給使用者,功能相當齊全.

  然而有一個問題就是跨國之間 youtube的影音串流網址不同,如果我們使用一個 API Server架在台灣,若其他國家來跟我們詢問,透過的是我們網段取得的影音串流網址,再轉給其他國家將會無法使用. 

  所以把目標轉到 JavaScript,這個網路上有很多人做,主要就是透過 Bookmark(或是Greasemonkey),在使用者端執行 Script Injection.做法有很多,如 Vexe'd有介紹用我的最愛下載 YouTube 影片.如果要更複雜一點的就如下方的 Script,可以把它貼到bookmark裡面,在看影片時候執行即可以下載影片.


javascript:(function() {
    function get_filetype(fmt_id) {
        switch(fmt_id) {
            case '5':
            case '6':
            case '34':
            case '35':
                return 'FLV';
            case '18':
            case '22':
            case '37':
            case '38':
            case '82':
            case '83':
            case '84':
            case '85':
                return 'MP4';
            case '43':
            case '44':
            case '45':
            case '46':
            case '100':
            case '101':
            case '102':
                return 'WEBM';
            default:
                return 'unknown';
        }
    }
    function get_video_url(fmt_stream_map, 
                           chosen_fmt_id, 
                           avail_fmt_ids) {
        fmt_stream_map=unescape(fmt_stream_map);
        if(avail_fmt_ids.indexOf(chosen_fmt_id)===0)
            return 


fmt_stream_map.substring(4,
                         fmt_stream_map.indexOf('&quality='));

        if(avail_fmt_ids.indexOf(chosen_fmt_id)===avail_fmt_ids.length-1)
            return 


fmt_stream_map.substring(fmt_stream_map.lastIndexOf('http'),
                         fmt_stream_map.lastIndexOf('&quality='));
        var pattern=new RegExp('&itag='+avail_fmt_ids[avail_fmt_ids.indexOf(chosen_fmt_id)-1]+',url=(.+?)&quality=');
        return fmt_stream_map.match(pattern)[1];
    }
    (function main() {
        var args=yt.playerConfig['args'];
        var fmt_quality_list='';
        var chosen_fmt_id=0;
        var fmt_info=args['fmt_list'].split(',');
        var fmt_resolution='';
        var avail_fmt_ids=new Array(fmt_info.length);
        for(var i in fmt_info) {
            avail_fmt_ids[i]=fmt_info[i].split('/')[0];
            fmt_resolution=fmt_info[i].split('/')[1];
            fmt_quality_list+=(avail_fmt_ids[i]+' = '+fmt_resolution+' ('+get_filetype(avail_fmt_ids[i])+')\n');
        }
        loop: while(true) {
            chosen_fmt_id=prompt('Please enter a format id.\n'+fmt_quality_list, avail_fmt_ids[0]);
            if(chosen_fmt_id===null) {
                return;
            }
            for(var i in avail_fmt_ids) {
                if(chosen_fmt_id===avail_fmt_ids[i]) {
                    break loop;
                }
            }
        }

        window.open(get_video_url(args['url_encoded_fmt_stream_map'], chosen_fmt_id, avail_fmt_ids)+'&title='+document.getElementsByName('title')[0].content);
    }());
}());



  主要原理使用 Script Injection的概念透過 youtube當中的 JavaScript object: yt ,來取得所有的資訊.列出幾個比較常用的關鍵字:url_encoded_fmt_stream_map(原始影音串流URL),fmt_list(影片支援解析度列表).

字幕檔Subtitle:

  Youtube把字幕檔放在他們家的 video.google.com,所以當有 Video ID跟確認有此語言的代碼,即可取得字幕檔.不過格式為 Google設計的XML檔案,要直接使用或許要做一些手腳.
範例連結:http://video.google.com/timedtext?lang=en&v=j3avqi1zObE
  以下擷取 youtube-dl的轉換 xml->srt的操作.
def _closed_captions_xml_to_srt(self, xml_string):
srt = ''
texts = re.findall(r'([^<]+)', xml_string, re.MULTILINE)
# TODO parse xml instead of regex
for n, (start, dur_tag, dur, caption) in enumerate(texts):
if not dur: dur = '4'
start = float(start)
end = start + float(dur)
start = "%02i:%02i:%02i,%03i" %(start/(60*60), start/60%60, start%60, start%1*1000)
end = "%02i:%02i:%02i,%03i" %(end/(60*60), end/60%60, end%60, end%1*1000)
caption = unescapeHTML(caption)
caption = unescapeHTML(caption) # double cycle, intentional
srt += str(n+1) + '\n'
srt += start + ' --> ' + end + '\n'
srt += caption + '\n\n'
return srt 



影片格式 以及解析度:

  Youtube也提供許多種影片格式,我們回到上面的 Script Injection Code可以知道,yt.playerConfig裏頭的  args['fmt_list']有此影片提供的格式.並且參照一次搞懂十種YouTube格式.整理出各fmt參數相對應的影片格式跟解析度.

  舉例來說,如果我要取得720P的MP4影音串流,我就要設定我的影音串流URL的ittag為22就會有不同的影音串流.

(PS.我試了很多次直接在 youtube url裏頭設定fmt=22, fmt=45似乎已經不能設定影音格式了?)

星期四, 6月 28, 2012

[VIM] Vim hacks slide and cheat sheet

在Slide Share上的Vim Hacks,我是靠這篇開始學Vim的.

Vim Hacks

以及vgod的cheat sheet.
我這種菜鳥就需要直接印出來放在工作牆XD. vgod Vim cheat sheet.

星期二, 6月 26, 2012

[JavaScript] Bubble and capture event sample and YUI manipulation

  JavaScript當中有所謂的 addEventListener : addEventListener(event, function, capture / bubble);
  是 W3C所制定的 addEventListener, (true為 capture, false為 bubble).不過 Windows IE並沒有 capture跟 bubble的差別. 於是自己有一套增加事件的方式:  window.attachEvent("submit",myFunction()); - 而始終使用 bubble 方式.

  以一個動作對於一個物件總共會經過三個階段(stage). capture, target,以及bubble.

Check out this Pen!
  以上面例子來說明, 當我點下span裡面的字樣後:

Capture Stage: html-> body-> div->span
Target   Stage :  span
Bubble  Stage: span->div->body->html

  所以一個物件會被經過兩次, 但是只會觸發一次事件, 於是就是仰賴canCapture參數決定在何時觸發事件. 以上方例子為 click事件, 而且都是設定為 bubble階段, 所以執行順序會在bubble stage從最小到最上層元素執行.

  以第二個案例為例子, 因為 div設定在 capture stage執行, 所以他的 click會先被執行.

  順帶一提, 當我們觸發一個物件的事件後, 若不想要在往上觸發事件, 可以使用event.stopPropagation(); 停止往上傳播.

  當然也可以不用那麼複雜, 很多框架都有指派或是新增事件的方式.

  如下方例子YUI3.0的 delegate方式.其他還有很常用的 obj.on("click", function );
YUI會將物件包裝為他們的物件, 並且多出不少好用功能如果我們要再繼續擴充下去, 可以使用Y.extend() 繼續擴充.

  所謂的extends , don't hack.
Check out this Pen!

星期四, 6月 21, 2012

[CSS] clear:both sample

  之前在跟同事討論到一個CSS的屬性clear,他有所謂的clear:left, clear:right,跟最常使用的clear:bith.不過其概念是真的蠻模糊的,根據W3C School的說明是


  Elements after the floating element will flow around it. To avoid this, use the clear property.

  The clear property specifies which sides of an element other floating elements are not allowed.
  Add a text line into the image gallery, using the clear property.

  恩~有看沒有懂, 不如拿code當範例說明最快了.

  Float會把所指定的 DOM物件浮出它原來的位置, 所以當一個父 DOM物件下面的物件都設定了 float, 會造成此裡面父物件的認為裡面沒有物件撐開,進而高度縮起來

Check out this Pen!

  此解法有相當多種解法,如多加一個 p tag
  .clear {zoom:1; clear:both;}
  .clear:after {content:''; display:block; clear:both; visibility:hidden; height:0;}

(修正 CSS 對於 float 區塊, 使用 clear:both 無效的解法,有更詳細完整的解法)

  所以clear就是清除掉此物件的左或是右,或是兩邊的Float.直接看sample code會更能了解呈現效果.

Check out this Pen!

星期一, 6月 11, 2012

求職大作戰


  小弟今年年初剛從國防役退下來,當時就抱持著一股志願想往外衝出去.當然前公司也是慰留我,不過資訊業很大,想去外頭試看看的心情是擋不下來的.這半年老實說,我學到很多東西,也要感謝非常多非常多朋友,前輩,學弟的支持.

  首先是 ILinkE的蛋李前輩,跟 Felix前輩.此外還有 Booker前輩也給我很多意見. Rayer幫我介紹了 Job Hunter - Alvin Huang,指點出我這些面試的不足,跟 Lettuce前輩.也謝謝花旗銀行資訊部給我這個機會嘗試,雖然後來並不是很適應金融業,但是這段時間真的很謝謝Eddie,Jimmy,Melony跟米歇爾你們的幫助.

  老實說,我這段時間真的學到很多東西,我自己的不足,以及自己真的有興趣的方向.

  還有我女朋友Laura,在這段無論是精神上,或是身體上都很忙碌困苦的時候,陪在我身旁支持我,給我信心.沒有你,我是沒辦法堅持下去的.

  也很懷念前公司各位英丰寶寶,我真的也在各位學到很多東西.Willie 跟小Kent ,Here 跟宗平,David 莊,Kevin 金, Leili姊和Benny各位前輩的指導,以及同期的順利,Alvin,跟阿彰阿Ken.Andy ,Charles ,Angus ,Kelly 以及後來的夥伴Derek ,Jason ,Lewis ,Lee,Cindy ,Marco ,Hank Study, Kirin 跟Frank 還有一些相處時間不長的學弟以及設計師阿喬,Faye,阿甘,Angie,Eller,英丰寶可以學到很多東西,我真的很榮幸能夠跟你們共事過.

  我運氣也真的很好,去 miiiCasa遇到了前 Yahoo!工程師啊嗚-josephj,也願意給我機會加入他們團隊.自己本身也對 Front-End Engineer很有興趣.就秉持著一份熱情進去 miiiCasa了.各位如果不太清楚啥是 F2E工程師,下面有一篇影片是 Yahoo資深前端工程師 Nate Koechley: Professional Frontend Engineering,介紹啥是前端工程師.


  簡單來說,我們在寫 View Source的東西,技術上來說從 HTML,CSS到 Javascript,然後要考慮瀏覽器的相容問題到使用者用的舒不舒服,如果難度在更高深一點,無障礙的網頁的實現.跟 Producer,Visual Designer以及 Back-End 工程師的橋樑.It does ALL matters.畢竟一套系統,一個軟體到最後就是要給使用者使用.也因此,前端工程師就是大家都會來盯你的工作內容的工程師.

  我的設計師好友 Arzon幫我就職做了一張圖,我把它貼在我的工作牆上.上面的意思是
I am doing what I love.我也會繼續在資訊的領域繼續往上攀爬.