10年08月29日 Sunday , 31 次点击 , 2 条评论

花了兩天時間讀完了《WordPress Plug-in Development》,通過實例講解,很細致,適合用來入門,當然,深度和廣度都有限。

分类 : 青梅煮酒
Top
10年08月28日 Saturday , 23 次点击 , 评论

兩周前為了批量下載某視頻網站中的電視劇,寫了個BASH腳本。將電視劇列表頁面的URL地址作為唯一參數傳給腳本,然後就會把所有視頻下載到當前目錄下,并自動重命名,同時生成一個M3U格式的播放列表。

由于在線視頻不支持斷點續傳,所以對于單個視頻來說無法實現。但對于整個批量下載任務來說,實現了宏觀上的斷點續傳,已經下載的視頻不會被重復下載。由于有些視頻網站會在午夜更改視頻地址,所以這一點很有用。

主流視頻網站應該是都支持的,我只測試了我下載電視劇的網站,不支持的都是非主流的!

唯一可能需要注意的依賴是PHP,必須安裝後才能使用。

BASH:
  1. #!/bin/bash
  2.  
  3. print_help_msg () {
  4.     echo "You see, I'm nothing ."
  5.     exit 0
  6. }
  7.  
  8. check_param () {
  9.     if [ $# -ne 1 ]; then
  10.         print_help_msg
  11.     fi
  12. }
  13.  
  14. check_m3u () {
  15.     if ! [ -a p.m3u ] || [ `wc -l p.m3u|awk '{ print $1 }'` -eq 0 ]; then
  16.         echo '#EXTM3U'> p.m3u
  17.     fi
  18. }
  19.  
  20. check_param $*
  21. check_m3u
  22.  
  23. export LC_ALL=en_US.UTF-8
  24.  
  25. ue=$(php -r "echo urlencode('$1');")
  26. parser="http://www.flvcd.com/parse.php?flag=&format=&kw=$ue&sbt=%BF%AA%CA%BCGO%21"
  27. if ! wget $parser -U mozilla -O meta.html ; then
  28.     echo "Unable to touch the parser, check network status for the cause ."
  29.     exit 0
  30. fi
  31.  
  32. grep "<N>" meta.html> title.lst
  33. grep "<U>" meta.html> url.lst
  34. iconv -f gbk -t utf-8 title.lst -o title.lst
  35. sed -i 's/<N>//g' title.lst
  36. sed -i 's/ //g' title.lst
  37. sed -i 's/<U>//g' url.lst
  38.  
  39. l1=`wc -l title.lst|awk '{ print $1 }'`
  40. l2=`wc -l url.lst|awk '{ print $1 }'`
  41. if [ "$l1" != "$l2" ]; then
  42.     echo "Title.lst has $l1 lines, but url.lst got $l2."
  43.     exit 0
  44. fi
  45. if [ $l1 -eq 0 ]; then
  46.     echo "Nothing got from the parser, check meta.html for detail info."
  47.     exit 0
  48. fi
  49.  
  50. arrTitle=(`cat title.lst`)
  51. arrURL=(`cat url.lst`)
  52.  
  53. idx=$((`wc -l p.m3u|awk '{ print $1 }'`-1))
  54. while [ $idx -lt $l1 ]; do
  55.     title=${arrTitle[$idx]}
  56.     url=${arrURL[$idx]}
  57.     idx=$((idx+1))
  58.     if ! wget $url -U mozilla -O "${title}.flv" ; then
  59.         echo "Failed fetching ${title}.flv, maybe its URL has been changed !"
  60.         exit 0
  61.     fi
  62.     cmd="sed -i '\$a\\${title}.flv' p.m3u"
  63.     eval $cmd
  64. done
  65.  
  66. echo 'done !'
  67. exit 0

另外,使用VLC執行播放列表效果灰常不錯,視頻之間銜接平滑流暢。

分类 : 编程
Top
10年08月25日 Wednesday , 52 次点击 , 评论

根据帮助文档,gvim在windows下的最大化是通过模拟打开窗口菜单并点击最大化菜单项实现的,而在Linux下的方法较为灵活。

下面的方法是在vim中通过调用wmctrl实现最大化的方法:

VIM:
  1. if has('win32')
  2.     au GUIEnter * simalt ~x
  3. else
  4.     au GUIEnter * call MaximizeWindow()
  5. endif
  6.  
  7. function! MaximizeWindow()
  8.     silent !wmctrl -r :ACTIVE: -b add,maximized_vert,maximized_horz
  9. endfunction

当然也可以通过配置窗口管理器规则实现自动最大化,但上面的方法更灵活。

分类 : 计算机
Top
10年08月24日 Tuesday , 28 次点击 , 评论

简述

InstallShield已经内建了对MySQL和Oracle的支持。但是这个功能是通过ODBC实现的,它对SQL脚本的格式要求非常严格,因此已经通过官方客户端测试的脚本在IS中执行时往往就会报错。

一般来说,数据库脚本只保证通过官方客户端测试即可,同时维护一份供IS执行的脚本费时费力。因此,考虑安装程序对两数据库的支持通过官方客户端实现。

MySQL

INNO:
  1. function InstallMySQLComponent(szComponent)
  2.     NUMBER nResult;
  3.     STRING szServer,szDB,szUser,szPassword,sCMD,sOPT,sResult1,sResult2,svLine,sMsg,sPath;
  4.     NUMBER nvFileHandle,nvCount;
  5.     LIST listStatus;
  6. begin
  7.     sMsg = '安装'+szComponent+' ...';
  8.     SdShowMsg(sMsg, TRUE);
  9.     // source命令不认识windows路径中的反斜杠,故将SRCDIR中的反斜杠替换成斜杠
  10.     sPath = SRCDIR;
  11.     StrReplace(sPath, '\\', '/', 0);
  12.     // Fetch database connection information
  13.     SQLRTGetConnectionInfo( 'mysql', szServer, szDB, szUser, szPassword );
  14.     sCMD = WINSYSDIR^'cmd.exe';
  15.     sOPT = ' /c '+SRCDIR^'mysql.exe -h'+szServer+' -u'+szUser+' -p'+szPassword+' -D'+szDB;
  16.     sOPT = sOPT+' -e "source '+sPath^szComponent+'.sql"> '+SRCDIR^'dbstatus.txt 2>&1';
  17.     // Execute the script associated with the given component in database
  18.     nResult=LaunchAppAndWait(sCMD, sOPT, WAIT|LAAW_OPTION_HIDDEN);
  19.     if (nResult <0) then
  20.         MessageBox('Failed installing '+szComponent+' !', SEVERE);
  21.         abort;
  22.     endif;
  23.     // 关闭安装提示
  24.     SdShowMsg('', FALSE);
  25.     // Read dbstatus.txt
  26.     OpenFileMode(FILE_MODE_NORMAL);
  27.     if (OpenFile(nvFileHandle, SRCDIR, 'dbstatus.txt')<0) then
  28.         MessageBox('Failed checking the status of installing '+szComponent+' !', SEVERE);
  29.         abort;
  30.     endif;
  31.     listStatus = ListCreate(STRINGLIST);
  32.     while GetLine(nvFileHandle, svLine) = 0
  33.         ListAddString(listStatus, svLine, AFTER);
  34.     endwhile;
  35.     CloseFile(nvFileHandle);
  36.     // Count how many lines fetched from dbstatus.txt
  37.     nvCount = ListCount(listStatus);
  38.     if nvCount> 0 then
  39.         sMsg = "更新数据库出错,点“是”打开日志文件并退出安装,点“否”直接退出安装。\n";
  40.         sMsg = sMsg+"若错误可忽略,可选择数据库类型“none”以跳过数据库更新并直接更新程序,\n";
  41.         sMsg = sMsg+"然后在数据库中手工执行SQL脚本(安装后保存在script目录下)";
  42.         nResult = AskYesNo(sMsg, YES);
  43.         if (nResult = YES) then
  44.             LaunchApp(WINSYSDIR^'notepad.exe', SRCDIR^'dbstatus.txt');
  45.     endif;                  
  46.         abort;
  47.     endif;
  48. end;

Oracle

INNO:
  1. function InstallOracleComponent(szComponent)  
  2.     NUMBER nResult,nvFileHandle,nIndex,nvCount;
  3.     STRING sMsg,szServer,szDB,szUser,szPassword,sCMD,sOPT,sInstance,sTmp,svLine;
  4.     LIST listStatus;
  5. begin
  6.     sMsg = '安装'+szComponent+' ...';
  7.     SdShowMsg(sMsg, TRUE);
  8.     // Fetch database connection information
  9.     SQLRTGetConnectionInfo( 'oracle', szServer, szDB, szUser, szPassword );
  10.     nIndex = StrFind(szServer, ':');
  11.     nIndex = StrFindEx(szServer, '/', nIndex);
  12.     StrSub(sInstance, szServer, nIndex+1, 100);
  13.     sCMD = WINSYSDIR^'cmd.exe';
  14.     sOPT = ' /c '+'sqlplus.exe -L -S '+szUser+'/'+szPassword+'@'+sInstance;
  15.     sOPT = sOPT+' @'+SRCDIR^szComponent+'.sql> '+SRCDIR^'dbstatus.txt 2>&1';
  16.     // Execute the script associated with the given component in database
  17.     nResult=LaunchAppAndWait(sCMD, sOPT, WAIT|LAAW_OPTION_HIDDEN);
  18.     if (nResult <0) then
  19.         MessageBox('Failed installing '+szComponent+' !', SEVERE);
  20.         abort;
  21.     endif;              
  22.     // 关闭安装提示
  23.     SdShowMsg('', FALSE);
  24.     // 在dbstatus.txt中查询字符串holytail,如果存在,说明脚本已执行完
  25.     if (FileGrep(SRCDIR^'dbstatus.txt', 'holytail', svLine, nIndex, RESTART) = 0) then
  26.         // 在dbstatus.txt中查询字符串ORA-,如果存在,说明脚本执行出现错误
  27.         if (FileGrep(SRCDIR^'dbstatus.txt', 'ORA-', svLine, nIndex, RESTART) = 0) then
  28.             sMsg = "更新数据库出错,点“是”打开日志文件并退出安装,点“否”直接退出安装。\n";
  29.             sMsg = sMsg+"若错误可忽略,可选择数据库类型“none”以跳过数据库更新并直接更新程序,\n";
  30.             sMsg = sMsg+"然后在数据库中手工执行SQL脚本(安装后保存在script目录下)";
  31.             nResult = AskYesNo(sMsg, YES);
  32.             if (nResult = YES) then
  33.                 LaunchApp(WINSYSDIR^'notepad.exe', SRCDIR^'dbstatus.txt');
  34.             endif;                  
  35.             abort;
  36.         endif;
  37.     else
  38.         sMsg = "更新数据库出错,点“是”打开日志文件并退出安装,点“否”直接退出安装。\n";
  39.         sMsg = sMsg+"若错误可忽略,可选择数据库类型“none”以跳过数据库更新并直接更新程序,\n";
  40.         sMsg = sMsg+"然后在数据库中手工执行SQL脚本(安装后保存在script目录下)";
  41.         nResult = AskYesNo(sMsg, YES);
  42.         if (nResult = YES) then
  43.             LaunchApp(WINSYSDIR^'notepad.exe', SRCDIR^'dbstatus.txt');
  44.         endif;                  
  45.         abort;
  46.     endif;
  47. end;

总结

  1. 为便于获取脚本在数据库中的执行结果,故通过官方客户端执行脚本时通过符号“>”将客户端的输出信息重定向到dbstatus.txt中;同时,使用“2>&1”将标准错误输出重定向到标准输出设备上,当然,会进一步重定向到dbstatus.txt文件中,否则,无法获取出错信息。
  2. sqlplus执行SQL脚本后不会自动退出,故应在Oracle的脚本后加上语句“exit;”。
  3. 重载OnSQLComponentInstalled()函数,并在其中禁止MySQL和Oracle的SQL脚本对应的Component被执行安装,然后通过以上两个函数更新数据库。
分类 : 编程
Top
10年08月09日 Monday , 62 次点击 , 评论

我的型号是X200,问题表现为在GNOME或XFCE下静音按钮无效,使用xev也捕获不到输入信号,而音量增加和减小按钮可以正常使用且有OSD。

解决办法是在grub的启动菜单中,给内核加上参数acpi_osi=“Linux”,如:

BASH:
  1. # (0) Arch Linux
  2. title  Arch Linux
  3. root   (hd0,2)
  4. kernel /boot/vmlinuz26 root=/dev/sda3 resume=/dev/sda4 ro acpi_osi="Linux"
  5. initrd /boot/kernel26.img

从查到的资料看,acpi_osi参数是用来指定操作系统接口的,据说有些硬件都只针对Windows做了测试或优化,对于这些硬件,如果将内核的操作系统接口指定为Linux,则有可能会出问题。所以内核从2.6.23版本开始,此参数的默认值被改成了“!Linux”,以保证更广泛的兼容性和稳定性。

而根据这里的说法,thinkpad一直以来在对Linux的兼容程度上有很好的口碑,故可以放心添加这个参数。

另外,xfce下使用OSD需要安装xfce4-volumed。

分类 : 计算机
Top