2008年1月29日

將aMule的ed2k關聯到Firefox~遠距版

這標題下的不好,但我想不大出來有什麼比較適合的標題。

要解決的情況是這樣:
A電腦(Debian)-執行aMule
B電腦(Ubuntu)-執行Firefox,點選ed2k連結

B電腦上透過Firefox點選ed2k連結後,要下載的檔案會直接加入到A電腦上的aMule列表當中。

這樣的情況為什麼會出現?
BT、eMule不管怎麼說,就是會不斷的操作磁碟和網路讀寫,不論網路如何爭論,我個人的使用情況是,他會讓電腦變慢,尤其是2個一起開的時候,因此衍生出了把BT、eMule放到獨立電腦的想法,也就是現在大家俗稱的「寵物機」。

「寵物機」方便歸方便,可是對於遠端操作一直有些便利性的問題,我一直以來都是用VNC(現在用NX)這類遠端桌面程式在操作Linux,管理BT和aMule。
現在桌機(B電腦)換成Ubuntu了,有沒有什麼方法可以把ed2k的連結直接關聯到桌機(B電腦)的Firefox,卻可以直接加入到(A電腦)的aMule列表中呢?

隨便搜尋都可以找到有許多人在教如何讓Firefox能關聯aMule的ed2k,方法簡單說就是加入下面2行到about:config當中:

network.protocol-handler.external.ed2k 設為正負值(Boolean)true
network.protocol-handler.app.ed2k 設為字串(String)/usr/bin/ed2k


因此可以發現,只需要執行
ed2k ed2k://ooxxooxxooxxooxx/

這樣的語法,就能夠把ed2k連結加入到aMule列表中了~

可是因為aMule不是執行在桌機(B電腦),因此會執行無效,他會說找不到aMule的設定檔,接著我們進一步看看ed2k的說明:
aMule ED2k link parser v1.4.0

Usage:
--help, -h Prints this help.
--config-dir, -c Specifies the aMule configuration directory.
--version, -v Displays version info.

magnet:? Causes the file to be queued for download.
ed2k://|file| Causes the file to be queued for download.
ed2k://|server| Causes the server to be listed or updated.
ed2k://|serverlist| Causes aMule to update the current serverlist.

--emulecollection, -e Loads all links of an emulecollection

*** NOTE: Option order is important! ***


原來ed2k需要aMule的設定檔才能動作,因此我們簡單的把A電腦的HOME目錄連線過來,連線的方式可以是NFS或Samba,只要能讓ed2k知道aMule設定檔目錄在那即可~

以我來說,我把A電腦的/home/ycfu分享出來,桌機(B電腦)則連上並mount到/media/ycfu,因此前面的ed2k指令改輸入為:
ed2k -c /media/ycfu/.aMule ed2k://ooxxooxxooxxooxx/

就能夠成功加入下載了~
(另一個方法是使用ssh遠端執行,方法簡單說一下帶過去,執行如下即可:
ssh A電腦IP /usr/local/amule/bin/ed2k ed2k://ooxxooxxooxxooxx/

這種作法需搭配公私鑰的設定,不然會詢問密碼,不提的原因是,無法整合到Firefox的關聯中)

雖然前面提到用
ed2k -c /media/ycfu/.aMule ed2k://ooxxooxxooxxooxx/

可以成功,但是卻無法整合到Firefox的關聯,Firefox的關聯設定中,似乎只接受執行檔,不接受參數的設定,因此,我們需要簡單的修改ed2k的Source Code,來依需要修改。

下載和電腦相同版本的amule source code,然後用
grep -R "Specifies the aMule configuration directory." *

直接找出ed2k的程式碼所在位置,找到程式碼是
amule-cvs/src/ED2KLinkParser.cpp

直接進入後,找到
.....
if ( arg.substr( 0, 8 ) == "ed2k://|" ) {
// Ensure the URI is valid
if ( arg.at( arg.length() - 1 ) != '/' ) {
arg += '/';
}

string type = arg.substr( 8, arg.find( '|', 9 ) - 8 );

if ( (type == "file") && checkFileLink( arg ) ) {
writeLink( arg, config_path );
} else if ( (type == "server") && checkServerLink( arg ) ) {
writeLink( arg, config_path );
} else if ( (type == "serverlist") && checkServerListLink( arg ) ) {
writeLink( arg, config_path );
} else {
std::cout << "Unknown or invalid link-type:\n\t" << arg << std::endl;
errors = true;
}
} else if (arg == "-c" || arg == "--config-dir") {
if (i < argc - 1) {
config_path = argv[++i];
} else {
std::cerr << "Missing mandatory argument for " << arg << std::endl;
errors = true;
}
} else if (arg.substr(0, 2) == "-c") {
config_path = arg.substr(2);

} else if (arg.substr(0, 13) == "--config-dir=") {
config_path = arg.substr(13);
} else if (arg == "-h" || arg == "--help") {
std::cout << getVersion()
<< "\n\n"
<< "Usage:\n"
<< " --help, -h Prints this help.\n"
<< " --config-dir, -c Specifies the aMule configuration directory.\n"
<< " --version, -v Displays version info.\n\n"
<< " magnet:?Causes the file to be queued for download.\n"
<< " ed2k://|file| Causes the file to be queued for download.\n"
<< " ed2k://|server| Causes the server to be listed or updated.\n"
<< " ed2k://|serverlist| Causes aMule to update the current serverlist.\n\n"
<< " --emulecollection, -e Loads all links of an emulecollection\n\n"
<< "*** NOTE: Option order is important! ***\n"
<< std::endl;
.....


注意看紅字,原來aMule設定檔路徑是用變數config_path來設定的,接下來就簡單啦~

在整段IF的最前面加上
config_path="/media/ycfu/.aMule";

如下:
.....
config_path="/media/ycfu/.aMule";
if ( arg.substr( 0, 8 ) == "ed2k://|" ) {
// Ensure the URI is valid
if ( arg.at( arg.length() - 1 ) != '/' ) {
arg += '/';
}

string type = arg.substr( 8, arg.find( '|', 9 ) - 8 );

if ( (type == "file") && checkFileLink( arg ) ) {
writeLink( arg, config_path );
} else if ( (type == "server") && checkServerLink( arg ) ) {
writeLink( arg, config_path );
} else if ( (type == "serverlist") && checkServerListLink( arg ) ) {
writeLink( arg, config_path );
} else {
std::cout << "Unknown or invalid link-type:\n\t" << arg << std::endl;
errors = true;
}
} else if (arg == "-c" || arg == "--config-dir") {
if (i < argc - 1) {
config_path = argv[++i];
} else {
std::cerr << "Missing mandatory argument for " << arg << std::endl;
errors = true;
}
} else if (arg.substr(0, 2) == "-c") {
config_path = arg.substr(2);
} else if (arg.substr(0, 13) == "--config-dir=") {
config_path = arg.substr(13);
} else if (arg == "-h" || arg == "--help") {
std::cout << getVersion()
<< "\n\n"
<< "Usage:\n"
<< " --help, -h Prints this help.\n"
<< " --config-dir, -c Specifies the aMule configuration directory.\n"
<< " --version, -v Displays version info.\n\n"
<< " magnet:?Causes the file to be queued for download.\n"
<< " ed2k://|file| Causes the file to be queued for download.\n"
<< " ed2k://|server| Causes the server to be listed or updated.\n"
<< " ed2k://|serverlist| Causes aMule to update the current serverlist.\n\n"
<< " --emulecollection, -e Loads all links of an emulecollection\n\n"
<< "*** NOTE: Option order is important! ***\n"
<< std::endl;
.....


之後執行
./configure && make

然後把amule-cvs/src/ed2k複製出來,放到桌機(B電腦)上,以我前面的設定來說,儲存成/usr/bin/ed2k即可~

2 則留言:

匿名 提到...

太麻烦了
直接写一个shell ed2k.sh
firefox的ed2k handler关联到ed2k.sh即可
这个ed2k.sh调用amulecmd来加链接即可

Cody 提到...

沒錯~
您提的方法的確比較好,重點是方便快速又不用改code。
我沒想到這方法。