2013年9月8日 星期日

Aug. 25th, 2013: ed2k javascript, TextMate, and batch href to “target = "_blank"”

ed2k javascript version: Jul. 30th, 2014

本篇文章原文已經消失過一次。這次是重打的,所以會比較簡潔一點。

幸好我有用 Xmarks 來備份書籤。不然我當時找到的那些書籤全都沒辦法找回來,這篇的資料來源也只能流產了。


因為有在一個咳咳論壇看到他們網站用的程式碼,所以我把它抓回來改成我要的樣子。除了那個 “Download selected item(s)” 按鈕我真的改不了,其他的部分都跟那論壇用的程式碼不一樣。改不了的原因在下面解釋。

不過我後來找資料的時候發現他用的程式碼,跟很多論壇用的都一樣。似乎只要是 Discuz! 模版的論壇就可以用。

使用前提及已知 Bugs:
  1. 檔案名稱必須要自行對過。一旦發生問題會導致整段程式碼出不來。
    最常發生問題的地方就是下方紅字的檔案名稱處。
    ed2k://|file|FileName.FileType|FileSize|Hash|h=RootHash|/

    原本還有一個檔名中有 ' (single quotation) 會導致程式碼印失敗的問題。不過我查了一下發現微軟不支援 " (double quotation) 出現在檔名。所以我改了一下我在 Javascript 用來包參數的符號,這樣就不會有這個問題了。

    但是 Mac 支援 ' 與 " 出現在檔名,它連 / 與 \ 都支援咧。反正目前以 Windodws 為主。
  2. 目前確定知道的問題中,只要未被轉碼過的檔名中有 % ,會導致程式碼會無法出來。 (fix)
  3. 將選項取消勾選後並重新整理網頁,那些選項不會重新自動勾選。 (fix)



參考資料:
因為有下面那個特別標出的來源,所以我才可以做出這種不用管輸入參數個數問題的程式碼。 “arguments” 是好東西啊!

  1. W3Schools
  2. JavaScript 初階教學
  3. JavaScript 中階教學
  4. 那些年,我們應該瞭解的 JavaScript 小知識 - 物件, 數字, 字串, 陣列, 迴圈
  5. Javascript Tutorial
  6. HTML 4.0 Special Entities
  7. eD2k連結(官網)
  8. eD2k連結(維基)

我是先看「JavaScript 初階教學」及「JavaScript 中階教學」這兩篇之後才開始看我抓到的 ed2k script 的程式碼。因為有了基礎之後才看得懂他寫啥呀 XDDDD

會把 W3Schools 放在第一個是因為我之前在用 CSS 的時候也經常到這個網站找參數定義。



程式碼及使用方法:
“Download selected item(s)” 的執行概念是用 window.location 將 ed2k 連結送給瀏覽器,再由瀏覽器按照註冊的連結種類,轉送給 ed2k 連結所註冊的程式。

如果讓所有的連結連續狂送進 ed2k 程式會導致程式直接死當的這種情況在舊版作業系統(如: Windows 2000)經常發生。或是 ed2k 程式中已經有上百個下載項目的情形下更容易發生程式當掉。只是在新作業系統中比較不會全系統當掉,只會是那個 ed2k 程式當掉。所以有個延遲時間是非常重要的。

按照我抓到的來源,它是用 window.setTimeout 來制作延遲的效果。他這個程式的缺點是每次都需要去把全部的連結抓過一次才知道他這次要送誰出去。我原本想要把它改成只用一個參數傳入來寫。可是寫出來的對於延遲時間處理都一直失敗,少數有成功的(alert 成功, window.location 失敗)也不合我意。

我不想要一個程式用兩個函式,當時用了 for 迴圈將 setTimeout 包起來。因為 for 迴圈的關係,會導致 setTimeout 一次全部跑完。而我有想過把延遲時間一直加上去,讓他跑完 for 迴圈的時候就把所有需要執行的程式都按照間隔給設定好。可是 setTimeout 加上 window.location 會導致莫名的問題。我上網找了資料,可是也沒有看到答案。這個方法最後只能「暫時」宣告失敗。當時已經是星期天凌晨了,所以先去睡覺,醒來後就直接用抓到的程式碼來做了。我也是有想過不要用延遲時間直接一次全送出去,可是後來想到過去的經驗,覺得還是做一下延遲會比較保險一點。

按照那個程式的設計想法,除了送第一個連結後可能需要等 ed2k 程式啓動所以等了六秒後才送第二個連結過去,其他都是等五百毫秒就送一個。

就是因為「延遲」做出不我自己想要的樣子,所以那個按鈕改不了的原因就是這樣了。

後來補充的(Jul. 27th, 2014):

快要一年後,因為克林姆跑回台中,原本要繼續寫去年九月故事的我不知道為啥一直去戳 emule 的那篇文章,所以就變成改這份程式碼了。

這次主要參考的都是跟字串有關的網站,還有為了把那個全域變數換掉而特地去查的 getTime 用法。再來就是為了 delay 而做的 for (var delay = 0; delay < 0xBADBF0; delay++) {}。

學校的 ind 雖然可以連,但是 blogger 抓不下來。所以我就去跟改版過的 Google Code 交手了一下,發現他現在有 subversion 耶!!!感覺上還蠻不錯 XDDD。

這次用到了正規表示式(Regular Expression)來把 /%[0-9a-fA-F]{2}/g 給過濾掉。我其實原本是用 /%../ 來做的,後來才知道最後要加一個 g 才會繼續判斷。那時是直接找十六進位的判斷法,稍微改幾個字就修成我可以用的。

.split .replace .indexOf 都還蠻常用到的,比較起來 .match 沒那麼好用。主要是錯誤判斷的時候很麻煩。我這次豬爬格(debug)的時候都是用 document.write (); 來看結果。比起之前用的 alert (); 真的是方便許多。不過有錯誤的話也是整篇程式碼不出來。


我遇到比較難的問題有兩個,但目的都是要做同一件事。就是判斷檔名發生問題後的取代措施。之前發現的問題就是檔案名稱中有單獨的 % 會導致 decodeURIComponent 掛點導致整段程式碼自殺。

我想了兩種方法,第一種比較簡單的是發現檔名有問題,直接把檔案名稱換成 FileNameError + Hash 值 + .filetype。優點就是大部分檔名有問題的都可以套用同樣的公式,缺點就是不知道原本的檔名大概長怎樣。這個方法的難題是不知道附檔名要怎麼從字串中拆出來。(必須保留附檔名的原因就不用提了)

第二種方法是把多出的那個 % 從字串中拆掉。這個就是比較難的方法了。


我遇到的字串就長得像下面這樣。
File Name:
Company - Someone & Anotherone %-- BTS.mp4

ed2k Name:
Company%20-%20Someone%20&%20Anotherone%20%--%20BTS.mp4

遇到的難題就別提了,直接寫解法。我懶得打字了(日記在追殺我)。下面有些寫的有點簡略(「要宣告兩個變數卻只用一個」等等),自己看程式碼吧。

第一種要取得附檔名,就是用 variable.split('.') 把字給分開,再用 variable[variable.length - 1] 來取得最後一個「.」後面的內容(也就是附檔名了)。

第二種困難的原因就是 javascript 沒有取代特定位置字元的方法,想要一個 .replace + .indexOf 的函式就要自己寫啦。我後來睡覺醒來想到的方法是先用 .split() 跟 .match() 把他們分開,還有把分開的東西存起來,再把 split 出來的東西判斷裡面有沒有不該存在的 % 後,之後將他們用黏的加在一起。目前程式碼裡是維持這種的寫法。

不過第二種寫法會遇到一個問題,如果該檔名完全沒有 %xx 的話,用 .match 加上 document.write 後(或是其他種組合),程式就會死給你看。判斷式真的不好寫啊。

備註一個東西,就是想要 if (judgement == 'undefined') 的話,可以改成 if (judgement) 來寫。不然的話,「聽說」是要用 if (judgement === 'undefined') 來寫,而結果也不一定會成功。我自己是用 if (judgement) 來做。

我的第二種方案原本想要做的是算出要取代的 % 是在第幾個字元,再用算式移除掉它之後再把原本的還原回去。我到現在還沒想出這個鬼方法要怎麼寫。相黏法真的實在是太好了。



參考資料:
  1. JavaScript Regex 的 字串比對(Match) 與 取代(Replace)
  2. Regular Expression (RegExp) in JavaScript
  3. [入門][Regex] Regular Expression 詳論
  4. How do I replace a character at a particular index in JavaScript?
  5. How to determine if variable is 'undefined' or 'null'
其他的我大多是用關鍵字在遇到的時候下去找的。就是 replace 與 indexOf 是我在網路上找不到解法的,現在用的這個是我自己想出來的。不過在對字元處理的時候,找個網站有整理 String Object Methods 的來參考有什麼指令可以用的話還蠻不錯的。


最後再提一個東西,我用 javascript 寫出批次取代 emule 給的 ed2k 連結的程式碼了。就是網頁右邊的方塊其中一組。也因為寫出那東西的關係,還順帶寫出製造 textarea 的程式碼。

已移除(繼續往下)

上面這東西的程式碼:
已移除(繼續往下)

後來補充的(Jul. 28th, 2014):

花了點時間把 ed2kscript 的跟 textarea 的程式碼合併在一起。

新版:
textarea replacement:


Result:



ed2kscript:


Result:


兩者在一起的程式碼:



下面這邊才是這次新加的內容。又是一個把側邊欄的工具程式碼做成真正的工具啦。



這次是按了按鈕之後會將按鈕隱藏掉並顯示出隱藏文字的程式碼。就是上面那個按鈕。




程式碼:


參考的資料:
  1. HTML - input value kept after Refresh
  2. HTML/CSS Making a textbox with text that is grayed out, and disappears when I click to enter info, how?

後來補充的(Jul. 30th, 2014):

剛剛在吃洋芋片的時候想著來看一下 Blogger 長怎樣好了。就看到上面那段話。

「將選項取消勾選後並重新整理網頁,那些選項不會重新自動勾選。」

剛好想到在做隱藏按鈕那個工具的時候,好像也有遇到同樣的問題,而且答案似乎就是很簡單的 autocomplete="off"。所以就右手拿著洋芋片,左手單隻手來做測試。

Bug 就這麼解了 XDDD

以下就是目前 v1.2 版。


使用方法就是在 html 的 body 下加上 javascript 的語法,裡面塞 XPCed2kMain ("ed2k_link","ed2k_link"); 如下:



工欲善其事,必先利其器。

我原本是用 Blogger 直接改 Javascript。可是後來真的受不了。測試的時候經常會遇到要把某幾段程式碼暫時註解掉,換個寫法試試看。沒有工具來做這件事真的會大大降低工作效率。所以我上網找了一下 Mac 可用的程式編輯器,找到了這個 TextMate。用起來目前覺得還不錯,雖然好像是需要註冊的,不過還沒看到逼註冊的視窗,就先這樣用了。

我當時找到的排名第一位的 Coding Tool 都是 Komodo Edit 這款奪冠。我試用了一下,我發現他有即時預覽的功能,感覺上真的頗強大啊!不過我後來還是因為 TextMate 的版面看起來比較簡潔一點所以就沒去用看起來有點複雜的 Komodo Edit。

這篇會有這段,當然不是廢話一堆只是要說我用 TextMate 來當寫程式工具。要提的是他的快速鍵啊!來源參考了以下兩篇。不過某一篇快要死了(無名小站要關了)。看在他可憐的份上還是先放著好了。

這個程式預設的縮排是用 tab,要改的話在下方 soft tabs,將 Indent Using 改成 spaces,而 Indent Size 改成 2。這樣就是「用空格以兩格為單位來作縮排」了。

  1. TextMate tips
  2. TextMate 操作

我下面只留我覺得有用的或是有趣的快捷鍵。

常用:
  1. cmd + /:註解所選行/註解所選區塊
    cmd + alt + /:新增區塊註解或註解區塊程式
  2. alt + [:減少縮排
    alt + ]:增加縮排
    cmd + alt + [:按規則縮排
  3. ctrl + cmd + up/down/left/right:將選擇的文字區塊上、下、左、右移動
  4. cmd + e:將目前選擇文字變成尋找目標
    cmd + (shift) + g:下(上)一個符合尋找目標
  5. cmd + alt + left/right:切換開啓的檔案
    cmd + `:切換視窗

有趣:
  1. cmd + alt + 1/2/3:按層收合/展開程式區塊(1 - function; 2 - 'for' or 'if' in function; 3 - and so on)
  2. 'todo' + tab:加入代辦事項
  3. ctrl + shift + t:顯示 todo 列表
  4. ctrl + shift + c:計算選擇文字中的數字(含 Hex 與 Decimal 互轉)




下面的這些程式碼,是我自己直接憑記憶打出來的了。我也找不到當時參考的那個來源了。

功能就是把目前網頁的連結在點選之後以新分頁開啓。裡面以 Start 及 End 包著的那部分是可以放在文章後面,讓網頁讀取到該程式碼以前的連結變成在新分頁開啓。之後讀取到的程式碼仍是維持原本設定值。而整段程式碼是改在整個網頁讀取完成後,以 window.onload 來執行轉換的程式。所以會變成網頁上所有的連結全都變成在新分頁開啓。



會需要這個東西跟網頁的跳出率有關係。像是很多網頁大家都是找到了之後就跳掉,如: Google Search。所以這樣改的話可以改善如 Google Analytics 統計數據上的表現。以上是我猜的啦~

1 則留言:

  1. = = 那個論壇判斷 ed2k 連結的語法全都是用 PHP 寫的啊!!!

    function emu($code) {
    $code = htmlspecialchars(str_replace('\\"', '"', preg_replace("/^[\n\r]*(.+?)[\n\r]*$/is", "\\1", $code)));
    $view = '';$total = 0;
    $searcharray = explode("\n",$code);
    $view = "<div class=\"emulejuse\"><center><h5>eMule专用下载链接,您必须安装电驴、迅雷、快车、旋风等下载软件才能点击下载</h5></center><table align=center id=\"emuletable\">";
    foreach($searcharray as $emule) {
    if($emule!='' && eregi("^ed2k:\/\/",$emule)){
    $emule = dhtmlspecialchars(trim($emule));
    $emule_array = explode("|",$emule);
    $total += $emule_array[3];
    $totalper = esizecount($emule_array[3]);
    $view.="<tr><td width=\"80%\"><input type=\"checkbox\"name=\"em$codecount\"value=\"$emule\"onclick=\"em_size('em$codecount');\" checked=\"checked\"><span class=\"smalltextjuse\"><a href=\"$emule\"><script language=\"javascript\">document.write(unescape(decodeURIComponent(\"$emule_array[2]\")));</script></a></span></td><td align=\"right\"><span class=\"smalltextjuse\">$totalper</span></td></tr>";
    } else {
    $view.="<tr><td colspan=\"2\" class=\"smalltxt\" align=\"center\">下载地址连接错误</td></tr>";
    }
    }
    $total=esizecount($total);
    $view.="<tr><td align=\"left\" width=\"80%\"><input type=\"checkbox\"id=\"checkall_em$codecount\"onclick=\"echeckAll('em$codecount',this.checked)\" checked=\"checked\"/><label for=\"checkall_em$codecount\">全选</label><input type=\"button\" value=\"下载选中的文件\" onclick=\"download('em$codecount',0,1)\"><input type=\"button\" value=\"复制选中的链接\" onclick=\"ed2kcopy('em$codecount')\"><div id=\"ed2kcopy_em$codecount\" style=\"position:absolute;height:0px;width:0px;overflow:hidden;\"></div></td><td class=\"smalltxt\" align=\"right\" id=\"size_em$codecount\"><font color=\"red\"><b>$total</b></font></td></tr></table></div><script language=\"javascript\" type=\"text/javascript\" src=\"static/js/emule.js\"></script>";
    return $view;
    }

    回覆刪除