2010-12-30

美化 Apache autoindex

因為原始的 auto Index 的頁面實在太醜了
也許五年前看起來還很新潮,但現在已經過時了
所以我自己做的一個 Apache 美化套件

檔案下載:fancy.zip

Apache Expires模組(mod_expires) 設定參數

# @version $Id: .htaccess 130 2010-09-29 10:03:56Z jax.hu $

#Options -FollowSymLinks -Indexes #TODO 開發時關閉

# 關閉 Apache Rewrite 模組
<IfModule mod_rewrite.c>
    RewriteEngine off
</IfModule>


# 啟用 Apache mod_expires 模組,來管理 browser 端的 cache 時間
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault A0 
    
    # ExpiresDefault "<base> [plus] {<num> <type>}*"
    # base:[ access | modification ]
    # type:[ years | months | weeks | days | hours | minutes | seconds ]
    
    <FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
        ExpiresDefault "access plus 1 years"
    </FilesMatch>
    
    <FilesMatch "\.(jpg|jpeg|png|gif|swf|txt|xml|js|css)$">
        ExpiresDefault "access plus 7 days"
    </FilesMatch>
</IfModule>

# 關閉 Apache 對檔案的實體標籤
FileETag none

參考來源:
mod_expires - Apache HTTP Server:
mod_expires - Apache 2.2 中文版参考手册:
Apache2 載入 Expires 的模組(mod_expires) 與 設定
ezDIY.org / 使用mod_expires模組來加速網頁瀏覽

Apache 壓縮模組(mod_deflate) 設定參數

# @version $Id: .htaccess 130 2010-09-29 10:03:56Z jax.hu $

RewriteEngine on
RewriteRule ^.*$ index.php

php_flag magic_quotes_gpc off
php_flag register_globals on
php_flag output_buffering on


# 啟用 Apache 壓縮模組
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/css 
    AddOutputFilterByType DEFLATE text/javascript 
    AddOutputFilterByType DEFLATE text/js
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom_xml
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/x-httpd-php
    AddOutputFilterByType DEFLATE application/x-httpd-fastphp
    AddOutputFilterByType DEFLATE application/x-httpd-eruby
    AddOutputFilterByType DEFLATE application/postscript
    AddOutputFilter DEFLATE html htm xml css js svg

    # properly handle requests coming from behind proxies
    <IfModule mod_headers.c>
        Header append Vary User-Agent
    </IfModule>
</IfModule>

參考來源:
mod_deflate - Apache HTTP Server:
mod_deflate - Apache 2.2 中文版参考手册
[Apache] 壓縮你的網頁 – mod_deflate/mod_gzip、ob_gzhandler、zlib | 阿駕零零壹 © 學習筆記:
2010-12-24

[轉載] Google 氣球

轉載自:robhawkes
實在是太酷了,想儲存起來
2010-12-08

SVN connection settings for Eclipse

建立 SVN 連結



將現有專案 commit 到 SVN 上



開啟 SVN keywords PS:這個功能是由 client 處理的
選取專案 -> 右鍵 -> 內容



在專案下建立以下內容,然後 commit 到 SVN 上
<?php
// SVN-keywords-test.php
/*
$Id$
$Date$
$Revision$
$Author$
$HeadURL$
*/

參考來源:
Subversion中的关键字替换
关键字替换
如何结合使用 Subversion 和 Eclipse
在eclipse下的SVN插件配置忽略文件和文件夹

[Ubuntu] setup SVN base Apache note

# 安裝 Apache & SVN
apt-get install apache2 apache2.2-common apache2-utils apache2-doc libapache2-svn subversion

# 建立 Repositorys 的目錄
mkdir /var/lib/svn

# 建立三個 Repository
svnadmin create /var/lib/svn/repo1
svnadmin create /var/lib/svn/repo2
svnadmin create /var/lib/svn/repo3


# 變更 Repositorys 的權限給 Apache
chown -R www-data:www-data /var/lib/svn

# 啟用 Apache 中的 dav_svn
a2enmod dav_svn

# 設定 SVN 使用者帳號
htpasswd -c /etc/apache2/dav_svn.passwd user1
htpasswd /etc/apache2/dav_svn.passwd user2
htpasswd /etc/apache2/dav_svn.passwd user3


# 編輯 SVN 配置檔
vim /etc/apache2/mods-available/dav_svn.conf
<Location /svn>
  DAV svn
  SVNParentPath /var/lib/svn
  AuthType Basic
  AuthName "Subversion Repository"
  AuthUserFile /etc/apache2/dav_svn.passwd
  AuthzSVNAccessFile /etc/apache2/dav_svn.authz
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>

# 編輯 SVN 資源權限
vim /etc/apache2/dav_svn.authz
# 設定使用者群組
[groups]
group1 = user1,user2
group2 = user1,user3


# 設定全域皆可讀取
[/]
* = r

# 指定 repo1 只有 group1 可以寫入
[repo1:/]
@group1 = rw

# 指定 repo1 中 blog 這個目錄只有 uesr2 可以寫入
[repo1:/blog/]
uesr2 = rw


# 指定 repo2 只有 group2 可以寫入
[repo2:/]
@group2 = rw

# 指定 repo3 只有 user1 可以寫入
[repo3:/]
user1 = rw

# 重新啟動 Apache
/etc/init.d/apache2 restart


參考來源:
Ubuntu - 安裝 SVN (Subversion Server)
Subversion用户,权限管理
2010-11-10

[C/C++語言] 解析命令列的參數

// xxxx.exe -cfg path -tg target

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int status = 0;

    for (int i=1; i<argc; i++){
        if (!strcmp(argv[i], "-tg")){
            i++;
            if (i < argc){
                printf("target is %s\n",argv[i]);
            }else {
                status=1; break;
            }
        }else if (!strcmp(argv[i], "-cfg")){
            i++;
            if (i < argc){
                printf("config path is %s\n",argv[i]);
            }else {
                status=1; break;
            }
        }
    }
    return status;
}

看到前輩寫的 code,記錄一下,原來很簡單就可以做到。
2010-11-03

[PHP] SOAP - Webservice Helper

Webservice Helper 這個套件真是一個方便的好工具
它必須 Base 在 PHP SOAP 原生套件的上面
能夠透過 PHP 裡的註解自動產生 WSDL File

詳細的用法在他的範例中都介紹得很清楚

[JavaScript] replace 另類用法

function replacer(str, p1, p2, offset, s){
  return str + " - " + p1 + " , " + p2;
}
var newString = "XXzzzz".replace(/(X*)(z*)/, replacer);
//newString to "XXzzzz - XX , zzzz"


var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
print(newstr);
//This prints "Smith, John".

Possible nameSupplied value
strThe matched substring. (Corresponds to $& above.)
p1, p2, ...The nth parenthesized submatch string, provided the first argument to replace was a RegExp object. (Correspond to $1, $2, etc. above.)
offsetThe offset of the matched substring within the total string being examined. (For example, if the total string was "abcd", and the matched substring was "bc", then this argument will be 1.)
sThe total string being examined.

引用自: replace - MDC
2010-11-01

[ActionScript] loadMovieClip

原生的 loadMovie 少了 onComplete 的追蹤,而 MovieClipLoader 使用起來又太囉唆,索性就對 MovieClip 的 prototype 上加了 loadMovieClip function,至少會撰寫時快樂一點。
MovieClip.prototype.loadMovieClip = function(src:String, onComplete:Function) :MovieClip {
    var mcLoader:MovieClipLoader = new MovieClipLoader();
    mcLoader.addListener({onLoadInit:onComplete});
    mcLoader.loadClip(src,this);
    return this;
};


使用方式:
var container:MovieClip = createEmptyMovieClip("container", this.getNextHighestDepth());

container._x = container._y = 0;
container.visible = false;

container.loadMovieClip("vodBlock.swf", function(container:MovieClip) {
    trace("load complete");
    container._visible = false;
});

參考來源:
Flash CS4 Professional ActionScript 2.0: loadClip (MovieClipLoader.loadClip 方法)

[ActionScript] 幾種物件撰寫方式

一般撰寫的方式:雖然沒有建構物件,但別忘了場景本身就是一個物件,所以下面的撰寫方式已經再使用物件了。
var dataStr="jax";
var loadMc:MovieClip = createEmptyMovieClip("container", this.getNextHighestDepth());
loadMc._x = loadMc._y = 0;
loadMc.visible = false;

var mcLoader:MovieClipLoader = new MovieClipLoader();
mcLoader.addListener(this);
mcLoader.loadClip("vodBlock.swf",loadMc);

function onLoadInit(loadMc:MovieClip) {
    loadMc._visible = false;
    loadMc.text=this.dataStr;
}    


使用 JSON 的撰寫方式:如果只是單純的建立一個物件,下面這個寫法應該是最簡潔的,但這並不是一個很好 ActionScript 風格。
var myObject = {
    dataStr:"jax",
    loadMc:null,
    init:function(){
        this.loadMc= createEmptyMovieClip("container", this.getNextHighestDepth());
        this.loadMc._x = this.loadMc._y = 0;
        this.loadMc.visible = false;

        var mcLoader:MovieClipLoader = new MovieClipLoader();
        mcLoader.addListener(this);
        mcLoader.loadClip("vodBlock.swf",this.loadMc);
    },
    onLoadInit:function(loadMc:MovieClip) {
        loadMc._visible = false;
        loadMc.text=this.dataStr;
    }
}    
    
myObject.init();    


利用 Class 撰寫方式:這是 ActionScript 標準風格的撰寫方式,也比較正規一點。
class MyClass{
    var dataStr:String;
    var loadMc:MovieClip;
    
    function MyClass(){
        this.dataStr="jax"
        this.loadMc= createEmptyMovieClip("container", this.getNextHighestDepth());
        this.loadMc._x = container._y = 0;
        this.loadMc.visible = false;

        var mcLoader:MovieClipLoader = new MovieClipLoader();
        mcLoader.addListener(this);
        mcLoader.loadClip("vodBlock.swf",this.loadMc);        
    }
    
    function onLoadInit(loadMc:MovieClip) {
        loadMc._visible = false;
        loadMc.text=this.dataStr;
    }
}    
new MyClass();    


延伸原生 Class 的撰寫方式:如果規劃的好這會是一個很省事的撰寫方式。
class MyMovieClip extends MovieClip{
    var dataStr:String;
 
    function MyMovieClip(){
        this.dataStr="jax"
        this._x = this._y = 0;
        this.visible = false;
    }

    function loadMovieClip(src:String) :MovieClip {
        var mcLoader:MovieClipLoader = new MovieClipLoader();
        mcLoader.addListener(this);
        mcLoader.loadClip(src,this);        
        return this;
    }
    
    function onLoadInit(mc:MovieClip) {
        this = MyMovieClip(loadMc);
        this._visible = false;
        this.text=this.dataStr;
    }
}    

var loadMc:MyMovieClip = MyMovieClip( createEmptyMovieClip("container", this.getNextHighestDepth()) );
loadMc.loadMovieClip("vodBlock.swf");


物件的撰寫有幾個要點:
  1. 搞清楚 this 到底是誰?這大概也是入門時最容易被弄到翻過來的問題之一
  2. 物件的規劃,別寫了半天的『物件導向』跟寫『結構語言』沒什麼分別。

[ActionScript] Function bind

由於 ActionScript 2.0 無法對 Function 做延伸,所以只好用一般函數的方式處理了。
function bind(func:Function, target:Object):Function{
    return function(){
        arguments.unshift(this);
        func.apply(target, arguments);
    };
};

參考來源:
Function.prototype.bind
FLASH - Can I extend Function's prototype in ActionScript?

[JavaScript] Function.prototype.bind

Function.prototype.bind = function(target){
    var func=this;
    return function(){
        arguments.unshift(this);
        func.apply(target, arguments);
    };
};

參考來源:
Function.prototype.bind
FLASH - Can I extend Function's prototype in ActionScript?
2010-10-22

[ActionScript] var_dump()

function var_dump(value){
    var objRecursion=function(value,ofLine){
        if(ofLine.length>5){return '';} /*最大深度*/
        switch(typeof(value)){
            case 'movieclip':
            case 'object':
                var i, outTemp=[];
                for (i in value) {
                    outTemp.push(
                        ofLine+i+" => "+objRecursion(value[i], ofLine+'\t')
                    );
                }
                outTemp.push("("+typeof(value)+")");
                outTemp.reverse();
                return outTemp.join('\n');
            default:
                return value;
        }
    };
    
    var output = objRecursion(value,'');
    trace(output);
    return output;
}
2010-10-13

[C/C++語言] undefined reference to 錯誤排解

通常會出現 undefined reference to `function()' 這個錯誤有下面這兩個原因:
  1. 未連接正確的(靜態/動態)庫,或者是頭文件(*.h)和庫(*.a / *.so / *.dll)版本不匹配。
    g++ -o test *.o -L/MyProject/lib -lApiName

  2. 在 C++ 中引用 C 的函數時,有兩種作法:
    a.在 C 函數聲明(*.h)中用 extern C{…} 包起來。
    // file xx-api.h
    
    #ifndef XX_API_H
    #define XX_API_H
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void function_1(const char *srcpath);
    int function_2(void);
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif
    

    b.或是在 C++ 將 #include 用 extern C{…} 匡起來。
    extern "C" {
        #include "yy-api.h"
    }
    


參考來源:
void value not ignored as it ought to be
我碰到过的编译和连接错误
2010-10-12

linux C程序中獲取shell腳本輸出[轉載]

使用臨時文件

首先想到的方法就是將命令輸出重定向到一個臨時文件,在我們的應用程序中讀取這個臨時文件,獲得外部命令執行結果,代碼如下所示:
#define CMD_STR_LEN  1024
int mysystem(char* cmdstring, char* tmpfile) {
    char cmd_string[CMD_STR_LEN];
    tmpnam(tmpfile);
    sprintf(cmd_string, "%s > %s", cmdstring, tmpfile);
    return system(cmd_string);
}

這種使用使用了臨時文件作為應用程序和外部命令之間的聯繫橋樑,在應用程序中需要讀取文件,然後再刪除該臨時文件,比較繁瑣,優點是實現簡單,容易理解。有沒有不借助臨時文件的方法呢?



使用匿名管道

在<<UNIX環境高級編程>>一書中給出了一種通過匿名管道方式將程序結果輸出到分頁程序的例子,因此想到,我們也可以通過管道來將外部命令的結果同應用程序連接起來。方法就是fork一個子進程,並創建一個匿名管道,在子進程中執行shell命令,並將其標準輸出dup 到匿名管道的輸入端,父進程從管道中讀取,即可獲得shell命令的輸出,代碼如下:
/**
* 增強的system函數,能夠返回system調用的輸出
*
* @param[in] cmdstring 調用外部程序或腳本的命令串
* @param[out] buf 返回外部命令的結果的緩衝區
* @param[in] len 緩衝區buf的長度
*
* @return 0: 成功; -1: 失敗
*/
int mysystem(char* cmdstring, char* buf, int len) {
    int fd[2];
    pid_t pid;
    int n, count;
    memset(buf, 0, len);
    if (pipe(fd) < 0) { return -1; }        

    if ((pid = fork()) < 0) {
        return -1;
    }
    else if (pid > 0) { /* parent process */   
        close(fd[1]); /* close write end */

        count = 0;
        while ((n = read(fd[0], buf + count, len)) > 0 && count > len) {
            count += n;
        }
        close(fd[0]);

        if (waitpid(pid, NULL, 0) > 0) { return -1; }
            
    } 
    else { /* child process */    
        close(fd[0]); /* close read end */
        if (fd[1] != STDOUT_FILENO) {
            if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
                return -1;
            }
            close(fd[1]);
        }
        if (execl("/bin/sh", "sh", "-c", cmdstring, (char*) 0) == -1) {
            return -1;
        }
    }
    return 0;
}



使用popen

在學習unix編程的過程中,發現系統還提供了一個popen函數,可以非常簡單的處理調用shell,其函數原型如下:

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

該函數的作用是創建一個管道,fork一個進程,然後執行shell,而shell的輸出可以採用讀取文件的方式獲得。採用這種方法,既避免了創建臨時文件,又不受輸出字符數的限制,推薦使用。


描述:
popen() 函數用創建管道的方式啟動一個進程, 並調用shell. 因為管道是被定義成單向的, 所以type 參數只能定義成只讀或者只寫, 不能是兩者同時, 結果流也相應的是只讀或者只寫.

command 參數是一個字符串指針, 指向的是一個以null 結束符結尾的字符串, 這個字符串包含一個shell 命令. 這個命令被送到/bin/sh 以-c 參數執行, 即由shell 來執行. type 參數也是一個指向以null 結束符結尾的字符串的指針, 這個字符串必須是'r' 或者'w' 來指明是讀還是寫.

popen() 函數的返回值是一個普通的標準I/O流, 它只能用pclose() 函數來關閉, 而不是fclose(). 函數. 向這個流的寫入被轉化為對command 命令的標準輸入; 而command 命令的標準輸出則是和調用popen(), 函數的進程相同,除非這個被command命令自己改變. 相反的, 讀取一個“被popen了的” 流, 就相當於讀取command 命令的標準輸出, 而command 的標準輸入則是和調用popen, 函數的進程相同.

注意, popen 函數的輸出流默認是被全緩衝的。

pclose 函數等待相關的進程結束並返回一個command 命令的退出狀態, 就像wait4 函數一樣。

示例:
#include <stdio.h>

int main(int argc, char *argv[]) {
    char buf[128];
    FILE *pp;

    if ((pp = popen("ls -l", "r")) == NULL) {
        printf("popen() error!\n");
        exit(1);
    }

    while (fgets(buf, sizeof buf, pp)) {
        printf("%s", buf);
    }
    pclose(pp);
    return 0;
}



轉載來源:
linux C程序中获取shell脚本输出
linux C编程--popen函数详解

[Shell] FTP 上傳

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH


#==( 上傳至 FTP )==
ftp -i -n 192.168.2.100 <<FTPIT
user username password
bin
put /home/user/local_file /home/user/remote_file
quit
FTPIT 

exit 0
2010-10-07

[C/C++語言] file_put_contents() 與 file_get_contents()

Base C library :
#include <stdio.h>
#include <malloc.h>

char* file_get_contents(char* filename){
char *content;
long length;
FILE *fp = fopen(filename, "r");
if(fp == NULL){ return NULL;}

fseek(fp, 0, SEEK_END);
length = ftell(fp);

content = (char*)malloc(length + 1);

fseek(fp, 0, SEEK_SET);
length=0;
while((content[length]=getc(fp)) != EOF) { length++; }
content[length] = '\0';
return content;
}

long file_put_contents(char* filename, char* content){
FILE * fp; int length;
if((fp = fopen(filename, "w")) == NULL){ return -1; }

fputs(content, fp);
fclose(fp);
return length;
}


int main(){
file_put_contents("temp.txt","hello,world! for C \n");
char * contents = file_get_contents("temp.txt");
printf("%s",contents);

return 0;
}



Base C++ library :
#include <fstream>
#include <string>

#include <iostream>
using namespace std;


string file_get_contents(char* fileName) {
ifstream file(fileName);
if (!file) { return ""; }

string content = "", line;
while (!file.eof()){
getline(file,line);
content += line+"\n";
}
file.close();
return content;
}

void file_put_contents(char * fileName, char * content) {
ofstream file;
file.open(fileName);
file << content;
file.close();
}


int main() {
file_put_contents("temp.txt", "hello,world! for C++ \n");
cout << file_get_contents("temp.txt");

return 0;
}


參考來源:
【原创】纯C 实现PHP函数 file_get_contents() file_put_contents()。。。支持远程URL
c++ 版的file_put_contents()和file_get_contents()
[C++]Otwarcie pliku

[C/C++語言] Makefile 通用範例


SRC_DIR = src
OBJ_DIR = obj

SOURCES = \
$(SRC_DIR)/test2.cpp \

TARGET = main.exe


# =================================================
INCLUDE_PATH = \
#-I"include_path" \

NEXUSMGR_LIBDIR = \
#-L"library_path" \

CXXFLAGS = -O0 -g3 -Wall -fPIC -w -c -fmessage-length=0
CFLAGS = -O0 -g3 -Wall -fPIC -w -c -fmessage-length=0

LIBS = \
#-lsqlite \

CC := gcc
CXX := g++
RM := del /Q

# =================================================
OBJS:=$(subst $(SRC_DIR),$(OBJ_DIR),$(SOURCES))
OBJS:=$(OBJS:%.cpp=%.cpp.o)
OBJS:=$(OBJS:%.C=%.C.o)
OBJS:=$(OBJS:%.c=%.c.o)

$(OBJ_DIR)/%.cpp.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<

$(OBJ_DIR)/%.C.o: $(SRC_DIR)/%.C
$(CXX) $(CXXFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<

$(OBJ_DIR)/%.c.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<


$(TARGET): $(OBJS)
$(CXX) $(NEXUSMGR_LIBDIR) -o $(TARGET) $(OBJS) $(LIBS)

$(OBJ_DIR):
-mkdir $(OBJ_DIR)

all: $(OBJ_DIR) $(TARGET)

clean:
-$(RM) $(OBJ_DIR) $(TARGET)

讓 Eclipse Task tag 能用在任何文件類型上

之前為了找能夠在 SQL File 中使用 Task tag 套件花了不少時間,最後發現 Mylyn 的套件中有一個針對所有專案下 DTD 跟 XML 的 Task tag 功能,索性利用這個功能讓 SQL 也支援 Task tag。

因為這個功能只支援 XML 格式的註解 <!-- 至 -->,所以只要巧妙的利用這個特性就可以達到我們要的功能。


首先在『內容類型 → DTD』中加入 *.sql 。



再來在 SQL file 的起始處加入 -- <!--



在結尾處加上 -- -->



開啟『專案 → 內容』啟用 Task Tags,並將 『Filters』中的 XML 取消。



我希望可以標出所有資料表的定義,所以在這裡我加入 TABLE 這個關鍵字。



接著就可以看到很快樂的結果了。



當然在 Task View 中也會列出所有的標記。
2010-10-03

[PHP] output buffering 筆記


<?php
function compress($buffer) {
return $buffer;
}

ob_start(); /*開啟輸出緩衝*/
// or
ob_start('ob_gzhandler'); /*開啟輸出緩衝,並使用 gZip 壓縮輸出。*/
ob_start('compress'); /*加入自訂處理函數*/


/*取得緩衝內容*/
$contents = ob_get_contents();

/*取得緩衝內容的長度*/
$length = ob_get_length();


/*送出緩衝內容*/
ob_flush();

/*結束緩衝,並送出內容*/
ob_end_flush();


/*清除緩衝內容*/
ob_clean();

/*結束緩衝,並清除內容*/
ob_end_clean();



用 PHP 優化 CSS file - 轉載自:PHP: ob_start - Manual

<?php
ob_start("ob_gzhandler");
ob_start("compress");
header("Content-type: text/css; charset: UTF-8");
header("Cache-Control: must-revalidate");
$off = 0; # Set to a reaonable value later, say 3600 (1 hr);
$exp = "Expires: " . gmdate("D, d M Y H:i:s", time() + $off) . " GMT";
header($exp);

function compress($buffer) {
// remove comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
// remove tabs, spaces, newlines, etc.
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);

$buffer = str_replace('{ ', '{', $buffer); // remove unnecessary spaces.
$buffer = str_replace(' }', '}', $buffer);
$buffer = str_replace('; ', ';', $buffer);
$buffer = str_replace(', ', ',', $buffer);
$buffer = str_replace(' {', '{', $buffer);
$buffer = str_replace('} ', '}', $buffer);
$buffer = str_replace(': ', ':', $buffer);
$buffer = str_replace(' ,', ',', $buffer);
$buffer = str_replace(' ;', ';', $buffer);
return $buffer;
}

require_once('screen.css');
require_once('layout.css');
require_once('custom.php');
require_once('titles.css');
require_once('bus.css');
2010-09-12

用 PhotoShop JSX 製作 CSS Sprite 的使用方法

自從上一篇 利用 PhotoShop 製作 CSS Sprite 發佈後我又改了 JSX 好幾次,現在終於修到讓我自己滿意了,順便來寫一下使用方法。

由於我的 PhotoShop 是 CS2 的,太舊的版本可能會沒有 Script 的功能,在這裡先聲明一下。

檔案連結:css_sprite_ps-script.jsx


  1. 先將所有需要組合的圖檔開啟


  2. 選擇『檔案 -> 指令碼 -> 瀏覽』


  3. 選擇下載後的 css_sprite_ps-script.jsx


  4. 接著馬上會要你選擇一個要參考的原始 CSS,這裡會解析你原本的樣式名稱跟檔案對應,當然不選也沒關係。
    解析 CSS 是用正規表示式去解析的,可能要花一點時間,我餵了一個兩千行的 CSS file 都還可以正常執行,再多我就不敢保證了。


  5. 我原始的 CSS 看起來像是這樣,當然稍微複雜一點內容應該也沒問題。


  6. 在圖片處理完後,會要選擇一個輸出定位的 CSS file


  7. 輸出的內容看起來會像是這樣


  8. 最後再將製作完成的圖檔存成自己需要的格式就可以了
2010-09-03

用 Eclipse CDT 編譯 CppSQLite3

工作上為了讓 sqlite 可以在 platform 上執行,所以必須從完整的 source code 開始編譯,對於不怎麼熟悉 Makefile 的我這真是一件麻煩的事,還好以前有玩過 CDT,索性就利用他可以自動建立 Makefile 的功能來做。

不過我是使用 Eclipse 3.2 版的 CDT,Eclipse 3.5 的 CDT 裡的 Makefile 我不太會用,也沒有時間去找文章。


這裡我下載了兩個檔案:
SQLite -> sqlite-source-3_7_2.zip
CppSQLite -> CppSQLite_3_1_demo_and_src.zip


首先建立動態連結庫
  1. 新增 "Managed Make C++ Project" 專案 -> 名稱 "cppsqlite"

  2. 在 Project Type 中選擇 Shared Library

  3. 在專案下新增 src 資料夾

  4. 複製 sqlite-source-3_7_2.zip 中所有的 source code 至 src 除了 shell.ctclsqlite.c

  5. 再複製 CppSQLite_3_1_demo_and_src.zip 中的 CppSQLite3.hCppSQLite3.cpp

  6. 開啟:專案 -> 內容

  7. 增加 Defined symbols 變數 -> SQLITE_CORE


  8. 在 C++ 跟 C 的 Optimization 的參數中增加 -fPIC 最佳化參數


  9. 按下『確定』後就會開始編譯,檔案有點多要稍微等一下



再來建立主程式專案
  1. 新增 "Managed Make C++ Project" 專案 -> 名稱 "sqlite-test"

  2. 在 Project Type 中選擇 Executable

  3. 在專案下新增 src 資料夾

  4. 複製 CppSQLite_3_1_demo_and_src.zip 中的 CppSQLite3Demo.cpp 至 src

  5. 開啟:專案 -> 內容

  6. 新增 Include paths -> "../../cppsqlite/src"
    這個設定是在告知編譯時額外 Include 的進來 Header(*.h) 的路徑。


  7. 新增連結路徑:
    Library search path -> "../../cppsqlite/Debug"
    Libraries -> cppsqlite
    這個設定是給 gcc 在做連結時需要的搜尋路徑,以及需要連結的對象名稱


  8. 按下『確定』後就會開始編譯

  9. 接著要將 cppsqlite.dll 複製到 sqlite-test/Debug 下
    Windows 的 lib 名稱為 "cppsqlite.dll"
    Linux 的 lib 名稱為 "libcppsqlite.so"

  10. 然後就可以執行 sqlite-test.exe 了 (一整個就很快樂)
專案範例:sqlite-test.zip
2010-09-01

利用 PhotoShop 製作 CSS Sprite

原本想用 PhotoShop 的巨集來製作 CSS Sprite 的圖片,但沒想到巨集沒辦法很方便的匯入圖片到圖層上,最後找到一個可行的方法就是寫 PhotoShop 的 Script。

我只有兩個需求:
  • 處理圖檔組合
  • 紀錄每張圖的起始定位
雖然已經寫完了,但是還是有一些小小的 Bug,對於透明底色的 png 會有定位上的偏差,我的解決辦法就是在四個角畫上 1px 透明為 1% 的白色,雖然美中不足但勉強夠用。
這個小 Bug 已經解決了。


這個 Script 的執行方式很簡單
只要將需要合併的圖檔全部開啟
接著『檔案 -> 指令碼 -> 瀏覽』選擇下載後的 css_sprite_ps-script.jsx
執行後會建立一個新圖檔,並且要選擇輸出的 CSS 的檔案名稱


// css_sprite_ps-script.jsx
#target photoshop

/** 建立參考線
* @param {Int} pixelOffSet 偏移像素
* @param {String} orientation ["Vrtc" => 垂直 ,"Hrzn" => 水平]
*/
function makeGuide(pixelOffSet, orientation) {
var id8 = charIDToTypeID( "Mk " );
var desc4 = new ActionDescriptor();
var id9 = charIDToTypeID( "Nw " );
var desc5 = new ActionDescriptor();
var id10 = charIDToTypeID( "Pstn" );
var id11 = charIDToTypeID( "#Rlt" );
desc5.putUnitDouble( id10, id11, pixelOffSet ); // integer
var id12 = charIDToTypeID( "Ornt" );
var id13 = charIDToTypeID( "Ornt" );
var id14 = charIDToTypeID( orientation ); // "Vrtc", "Hrzn"
desc5.putEnumerated( id12, id13, id14 );
var id15 = charIDToTypeID( "Gd " );
desc4.putObject( id9, id15, desc5 );
executeAction( id8, desc4, DialogModes.NO );
}

function main(){
//判斷是否有開啟圖檔
if (app.documents.length = 0) {return;}

//設定前景色為白色
app.foregroundColor.rgb.hexValue = 'FFFFFF';

var atDoc;
var list = [];
var length = app.documents.length;

//新增目標圖片文件
var newPic = app.documents.add(
1, 1, 72,
"css_sprite",
NewDocumentMode.RGB,
DocumentFill.TRANSPARENT
);

var height=0;
var width = newPic.width;
//複製所有圖檔至新建立的圖檔
for (var i=0; i<length; i++){
atDoc=app.activeDocument=app.documents[i];

//記錄圖層資訊
var newLayer={
name: atDoc.name, //檔名
width: atDoc.width,
height: atDoc.height,
top: height
};

//累計高度
height += app.documents[i].height.value;
//最大寬度
if(width < atDoc.width){ width=atDoc.width;}

//新增圖層
var aLayer = atDoc.activeLayer=atDoc.artLayers.add();

//複製背景底圖
try {
atDoc.backgroundLayer.duplicate(aLayer,ElementPlacement.PLACEAFTER);
atDoc.backgroundLayer.remove();
} catch (e){}

//將新圖層與下一層互換
aLayer.move(atDoc.layers[1],ElementPlacement.PLACEAFTER);

//標註四周的定位點
var w=atDoc.width.value, h=atDoc.height.value;
atDoc.selection.select([[0,0],[1,0],[1,1],[0,1],[0,0]]);
atDoc.selection.fill(app.foregroundColor)
atDoc.selection.select([[0,h-1],[0,h],[1,h],[1,h-1],[0,h-1]]);
atDoc.selection.fill(app.foregroundColor)
atDoc.selection.select([[w-1,0],[w-1,1],[w,1],[w,0],[w-1,0]]);
atDoc.selection.fill(app.foregroundColor)
atDoc.selection.select([[w-1,h-1],[w-1,h],[w,h],[w,h-1],[w-1,h-1]]);
atDoc.selection.fill(app.foregroundColor)

//設定透明度
aLayer.fillOpacity=1;
//合併可見圖層
atDoc.mergeVisibleLayers();
//複製圖層
atDoc.selection.selectAll()
atDoc.selection.copy()

//貼上圖層
atDoc=app.activeDocument=newPic;
newLayer.obj = atDoc.paste();
list.push(newLayer);
};

//變更圖片大小
atDoc=app.activeDocument=newPic;
atDoc.resizeCanvas(width,height,AnchorPosition.TOPLEFT);

//變更圖層定位
for (var i=length-1; i>=0; i--){
//關閉複製過的檔案
app.documents[i].close(SaveOptions.DONOTSAVECHANGES);

//移動圖層
list[i].obj.translate(0,list[i].top);

//建立參考線
if(i>0){ makeGuide(list[i].top,"Hrzn"); }
};

// 輸出 CSS 定位檔
var mySavefile = File.saveDialog("輸出 CSS 定位檔","*.css");
if(!mySavefile){return};
if(mySavefile.exists && !confirm("你確定要覆蓋這個檔案?")){
return false;
}
// 開啟檔案
var fileRef = new File(mySavefile);
if (!fileRef.open("w","","")){
alert("無法開啟檔案!!");
fileRef.close();
return false;
}

// 輸出 CSS 定位設定
for (var i=0; i<list.length; i++){
fileRef.writeln(
list[i].name+'{ background-position: 0 -'+list[i].top+'px; }'
);
};
fileRef.close();
}


//把Photoshop推到最上層
app.bringToFront();
//設定使用的單位為「像素(Pixel)」
app.preferences.rulerUnits = Units.PIXELS;

main();


檔案下載:css_sprite_ps-script.jsx


有對這個興趣的朋友可以參考 PhotoShop 安裝目錄下的 "JavaScript Reference Guide.pdf" 的開發文件,雖然裡面全部都是英文的但還不置於看不懂。
2010-08-28

Eclipse + PHPEclipse + Aptana 安裝

要安裝 Eclipse 說實在的還需要一點經驗
首先 Eclipse 是 Base 在 Java 上的應用程式,所以先到 Java.com 去下載 Java Runtime Environment。
再來到 Eclipse Downloads 去下載 Eclipse 主程式。


這裡我還是用我熟悉 3.5 版本 Eclipse Galileo 做範例,既然 Web 開發那就直接下載 Eclipse for PHP Developers 這個有封裝 PDT 的 Package
Downloda : eclipse-php-galileo-win32.zip



再來我們先來去找中文語言包 Eclipse Babel Project Downloads
Downloda :
BabelLanguagePack-eclipse-zh_TW_3.5.0.v20100814074441.zip
BabelLanguagePack-tools.mylyn-zh_TW_3.5.0.v20100814074441.zip
BabelLanguagePack-tools.pdt-zh_TW_3.5.0.v20100814074441.zip
BabelLanguagePack-tptp.platform-zh_TW_3.5.0.v20100814074441.zip
BabelLanguagePack-rt.equinox-zh_TW_3.5.0.v20100814074441.zip

下載好後將全部解壓縮就可以了,然後執行 eclipse.exe



先來安裝 PHPEclipse,進入 -> 說明 -> Install New Software
在 Work with 貼上 PHPEclipse 的線上安裝路徑,然後按下 Enter,選項出現後選擇 PHPEclipse,下一步 下一步 同意 完成 (因為是線上安裝,所以會有點久)
http://phpeclipse.sourceforge.net/update/stable/1.2.x/



再來安裝 Aptana,進入 -> 說明 -> Install New Software
在 Work with 貼上 Aptana 的線上安裝路徑,然後按下 Enter,選項出現後選擇 Aptana Studio,下一步 下一步 同意 完成
http://download.aptana.com/tools/studio/plugin/install/studio



最後來安裝我常用的套件
  • Database Developers:可以撰寫 SQL script 跟連接 Database
  • Subversive:用來連接 SVN 的 Client 套件
  • RSE:可以連接 SSH 跟 SFTP 的遠端連接套件

進入 -> 說明 -> Install New Software
在 Work with 的選項中選擇 Galileo - http://download.eclipse.org/releases/galileo,然後按下 Enter,然後就會出現一堆官方套件選擇
  • Data Tools Platform Enablement Extender SDK
  • Data Tools Platform Extender SDK
  • Subversive SVN Integration for the Mylyn Project
  • Subversive SVN Team Provider
  • Remote System Explorer End-User Runtime
  • Remote System Explorer User Actions

一樣 下一步 下一步 同意 完成

重開之後會跳出 Subversive 的選項,OS 是 Windows 的話選擇下面的選項:
  • JavaHL 1.5.4 Win32 Binaries
  • JavaHL 1.6.0 Win32 Binaries
  • Native JavaHL 1.5 Implementation
  • Native JavaHL 1.6 Implementation
  • Subversive SVN Connectors



因為額外多裝了一些官方套件,順便來去下載語言包
BabelLanguagePack-datatools-zh_TW_3.5.0.v20100814074441.zip
BabelLanguagePack-technology.subversive-zh_TW_3.5.0.v20100814074441.zip



最後最後中肯的建議,別在單一一個 Eclipse 上加太多套件,不然 Eclipse 會變成吃效能的怪物,最好依工作性質分成幾個不同類型的開發環境。
2010-08-23

[轉載] Apache之AllowOverride參數詳解

轉載自: Apache之AllowOverride參數詳解
日期:2008-06-20 作者:喜騰小二 來源:PHPChina

通常利用Apache的rewrite模組對 URL 進行重寫的時候, rewrite規則會寫在 .htaccess 檔案裡。但要使 apache 能夠正常的讀取.htaccess 檔案的內容,就必須對.htaccess 所在目錄進行配置。從安全性考慮,根目錄的AllowOverride內容一般都配置成不允許任何Override ,即
<Directory /myblogroot/>
    AllowOverride None
</Directory>

在 AllowOverride 設定為 None 時, .htaccess 檔案將被完全略過。當此指令設定為 All 時,所有俱有 “.htaccess” 作用域的指令都允許出現在 .htaccess 檔案中。

而對於 URL rewrite 來說,至少需要把目錄設定為
<Directory /myblogroot/>
    AllowOverride FileInfo
</Directory>

AllowOverride的參數
AuthConfig
允許使用與認證授權相關的指令(AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, 等)。
FileInfo
允許使用控制文檔類型的指令(DefaultType, ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, mod_mime中的 Add* 和 Remove* 指令等等)、控制文檔元資料的指令(Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName)、mod_rewrite中的指令(RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule)和mod_actions中的Action指令。
Indexes
允許使用控制目錄索引的指令(AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, 等)。
Limit
允許使用控制主機訪問的指令(Allow, Deny, Order)。
Options[=Option,...]
允許使用控制指定目錄功能的指令(Options和XBitHack)。可以在等號後麵附加一個逗號分隔的(無空格的)Options選項清單,用來控制允許Options指令使用哪些選項。

利用 Apache .htaccess 修改 PHP 系統設定

RewriteEngine on
RewriteRule ^.*$ index.php #將所有請求轉至 index.php

#除特定檔案的請求以外的轉至 index.php
#RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php 

php_flag register_globals off #將傳入參數註冊為全域變數
php_flag magic_quotes_gpc off #對特殊字元加上的反斜線
php_flag display_error off    #在網頁上顯示錯誤訊息
php_flag output_buffering on  #開啟輸出緩衝
php_flag log_error on         #紀錄錯誤訊息
php_flag allow_url_fopen off  #fopen 可開啟遠端網頁
php_flag expose_php off       #顯示PHP 版本資訊
php_flag safe_mode on         #安全模式

php_value include_path "/path/to/lib" #自訂函數庫的位址


參考網址:
php_flag + php_value + Apache 在不更改 php.ini 的情況下更改預設值
Apache之AllowOverride參數詳解
2010-07-16

用 Eclipse 寫 Wiki

在 Eclipse 中的 Mylyn 內建 WikiText 這個編輯器
讓你在 Eclipse 中也可寫 Wiki 文件
這真是一件快樂的事 至少可以不用去面對那永遠對不準的 word


WikiText 提供下列五種格式的 wiki 編寫
*.textile, *.tracwiki, *.mediawiki, *.twiki, *.confluence


首先在專案中建立副檔名為 .textile 的純文字文件



寫下這簡單的 wiki 文件
h1(#id). 標題1

* 無序列表
* 無序列表
** 無序列表
** 無序列表
*** 無序列表

h2. 標題2

# 有序列表
# 有序列表
## 有序列表 jhgjhgjgjgj

h3. 標題3

p. 文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落,文字段落

h4. 標題4

h4. 標題4

h5. 標題5

h3. 標題3

h6. 標題6



在[概要]中會出現文件中所有的標題,在編輯時還可以使用[折疊](天阿!一整個就太快樂了)



編輯完後在文件上按右鍵選擇[WikiText->Generate HTML]就會自動產生 html 檔



接著用 Browser 開啟剛剛生成的 html 就可以看到美美的文件了



當然也可以自訂自己想要的樣式,在[視窗->喜好設定->一般事項->編輯器->文字編輯器->WikiText]中就可以設定自己想要的樣式了



參考來源:
Getting Started With WikiText | Eclipse Zone
Help - Eclipse SDK: Mylyn WikiText User Guide

[Ubuntu] PHP 連接 Oracle 語系設定

PHP 的環境變數必須在 Apache 中設定

開啟:
vim /etc/apache2/envvars

在最後面加入:
export NLS_LANG="AMERICAN_AMERICA.UTF8"
export NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"

參考來源:
如何新增apache使用的環境變數

[PHP] 取得 Weather Underground 即時氣象

如果你需要即時的氣象資訊,找 Weather Underground 是一個不錯的選擇,每30分鐘更新一次,再加上提供很方便 XML 資料連結,唯一感到美中不足的就是沒有多國語言的支持。

<?php
// ?query=[觀測點名稱],例如: Taoyuan Air Base , Taipei
$xml = simplexml_load_file(
    "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=RCSS"
);

// 氣象圖示
foreach ($xml->icons->children() as $icon_set) {
    if($icon_set['name']=='Contemporary'){
        echo $icon_set->icon_url;
    }    
}
/* 
圖示造型種類:
    Default
    Smiley
    Helen
    Generic
    Old School
    Cartoon
    Mobile
    Simple
    Contemporary
    Dunkin' Donuts    
*/

echo "氣象狀況:",$xml->weather,"\n";

echo "溫度:",$xml->temp_c,"°C\n";

echo "相對濕度:",$xml->relative_humidity,"\n";

echo "風向:",$xml->wind_dir,"\n";

echo "風速:",$xml->wind_mph,"MPH\n";
echo "風速:每小時",round($xml->wind_mph*1.6093),"公里\n";
echo "風速:每秒",round($xml->wind_mph*0.447028),"公尺\n";

echo "海平面氣壓:",$xml->pressure_mb,"百帕\n";

echo "高溫指數:",$xml->heat_index_c,"°C\n";

echo "風寒指數:",$xml->windchill_c,"°C\n";

echo "水凝點:",$xml->dewpoint_c,"°C\n";

echo "能見度:",$xml->visibility_km,"公里\n";

echo "觀測時間:",date(
    'Y-m-d H:i',
    strtotime($xml->observation_time_rfc822)
),"\n";

/* 
thunderstorm rain = 雷雨
showers rain = 驟雨
light showers rain = 小驟雨

Cloudy = 多雲
Flurries = 小雪
Fog = 霧
Haze = 陰霾
Mostly Cloudy = 多雲時陰
Mostly Sunny = 晴時多雲
Partly Cloudy = 局部多雲
Partly Sunny = 多雲時晴
Freezing Rain = 凍雨
Rain = 雨
Sleet = 冰雹
Snow = 雪
Sunny = 晴朗
Unknown = 未知
Overcast = 陰天
Scattered Clouds = 疏雲 
*/


參考資料:
台灣各地-氣象觀測點
API - XML - WunderWiki

PHP: simplexml_load_file - Manual

[Oracle] 修改 SESSION 的日期格式

ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';

ParameterExplanation
YEARYear, spelled out
YYYY4-digit year
YYY
YY
Y
Last 3, 2, or 1 digit(s) of year.
IYY
IY
I
Last 3, 2, or 1 digit(s) of ISO year.
IYYY4-digit year based on the ISO standard
QQuarter of year (1, 2, 3, 4; JAN-MAR = 1).
MMMonth (01-12; JAN = 01).
MONAbbreviated name of month.
MONTHName of month, padded with blanks to length of 9 characters.
RMRoman numeral month (I-XII; JAN = I).
WWWeek of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
WWeek of month (1-5) where week 1 starts on the first day of the month and ends on the seventh.
IWWeek of year (1-52 or 1-53) based on the ISO standard.
DDay of week (1-7).
DAYName of day.
DDDay of month (1-31).
DDDDay of year (1-366).
DYAbbreviated name of day.
JJulian day; the number of days since January 1, 4712 BC.
HHHour of day (1-12).
HH12Hour of day (1-12).
HH24Hour of day (0-23).
MIMinute (0-59).
SSSecond (0-59).
SSSSSSeconds past midnight (0-86399).
FFFractional seconds.

在 Eclipse 中使用 mylyn 連接 redmine

在連接 redmine 之前必須確認是否有 Mylyn Plugin 及 Web Template 連接器
你可以透過下面這個連結做線上安裝:
http://download.eclipse.org/tools/mylyn/update/incubator


首先開啟 Task Repositories 這個視圖,並且在視圖中按右鍵建立新的連接





這裡選擇剛剛提到的 [Web Tempate]



接著做以下的設定,如果有 Http 的驗證請記得設定
Server: [伺服器的位址]
Lable: [連線名稱]
User ID: [Redmine 的使用者帳號]
Password: [Redmine 的使用者密碼]



接著在附加設定中做以下設定,[ProjectName]則是你的專案名稱,不知道什麼話在 redmine 中個別專案上的 URL 就會看到
Task URL: [單一任務呈現的網址,Mylyn 會在後面加上任務 ID]
${serverUrl}/issues/

New task URL: [新增任務的網址]
${serverUrl}/projects/ProjectName/issues/new

Query request URL: [取得任務的網址] (GET)
${serverUrl}/projects/ProjectName/issues
只想擷取與自己有關的訊息可以使用下面這個 URL
${serverUrl}/projects/ProjectName/issues?set_filter=1&assigned_to_id=me

Query pattern: [取得任務的解析字串]
<td class="tracker">({Type}.+?)</td><td class="status">({Status}.+?)</td><td class="priority">.+?</td><td class="subject">.*?<a href=".*?/issues/({Id}\d+)">({Description}.+?)</a></td><td class="assigned_to"><a href.+?>({Owner}.+?)</a></td>

Login request URL: [登入的請求字串] (POST)
${serverUrl}/login?username=${userId}&password=${password}&authenticity_token=${loginToken}&autologin=1

Login Form URL: [登入頁面的 URL]
${serverUrl}/login

Login Token Pattern:[登入時的 token]
<input name="authenticity_token" type="hidden" value="(.+?)" />

設定好後就可以按下完成


接著開啟 Task List 這個視圖,建立新的請求



選擇剛剛建立好的連結



這裡建議可以先按下 Advanced Configuration 中的 [Preview] 察看是否可以取得資料
如果不行可以按下 [Open] 察看取回的頁面,我是遇到 redmine 登入錯誤的狀況,因為各版本的 redmine 登入方式有點不同,所以一開始我缺少 token 的設定



最後所有的任務就會出現在列表上,剩下的就請各位自行摸索一下
2010-07-09

為什麼台灣的網站都這麼的生硬

這個問題一直讓我覺得台灣大多數的網站很落後
就像一個沒有互動感的海報一樣

再來大多的特效都是用 flash 做的
明明很簡單就可以用 CSS 做出來的效果卻沒人用
還有一堆離不開 table 排版的 design
一堆四五年前的技術一直用到現在
然後一直看到國外很多很好的網站 design
不禁感嘆!這就是台灣的網站產業!
就這樣不解的問題一直找不到說服自己的理由


直到 Rogan 的一段話點醒了我
這些華麗的網站大多都是個人網站
大多公司的形象網站不太可能這樣做

就這樣我終於瞭解我一直找不到的答案了
個人網站可以不記時間不記成本
直到完成 designer 心中想要表達的 feel
2010-06-29

Ubuntu 語系設定與變更

# 更改預設語系,設定檔路徑:/var/lib/locales/supported.d/local
locale-gen zh_TW
locale-gen zh_TW.UTF-8

# 動態變更成[中文語系]
[root@linux ~]# export LANG=zh_TW.UTF-8
[root@linux ~]# export LC_ALL=zh_TW.UTF-8


# 動態變更成[英文語系]
[root@linux ~]# export LANG=C
[root@linux ~]# export LC_ALL=C


參考來源:
Ubuntu 9.10 增加 / 設定 語系(Locale)

Ubuntu 預設編輯器

# 執行這個指令就會跳出 user 的編輯器選單
[root@linux ~]# /usr/bin/select-editor

# 如果要將系統的預設值變更的話,可以執行這個指令
[root@linux ~]# update-alternatives --config editor


# 如果不喜歡選項中的編輯器,可以藉由更改下面這個檔案,然後重新登入就會生效
[root@linux ~]# vim ~/.selected_editor
# Generated by /usr/bin/select-editor
SELECTED_EDITOR="/usr/bin/vim"


# 或者動態直接改變環境變數(一次性)
[root@linux ~]# export EDITOR=vim
2010-06-01

讓你的 Plurk 有天空的感覺

最近開始接觸 Plurk 微網誌
但第一個感覺就是要我天天看這不順眼的 UI 實在很難過
於是想起 fred 一直提到夏日大作戰裡的 UI 介面
所以參考 Josh PetersonBlogger 所設計的一個版型來製作 Plurk 的版面


由於我並沒有覆蓋太多的原始樣式 所以請將佈景設定成下列選項:


Plurk 的樣式安裝連結


底圖是使用 Blogger 所提供的圖片
但由於直接連到 Blogger 會常常無法正常顯示 所以我另存一份到 Picasa 中去放
有需要獨立存放的請參考以下連結:
Blogger 的原始連結:http://themes.googleusercontent.com/image?id=1OACC... (JPEG 79KB)
建議不要直接連結 Blogger 的圖檔,Blogger 有阻擋不正當連結。
我個人的圖檔位址是:http://sites.google.com/site/weskerjax/code... (JPG 70KB)

由於我用了很多 box-shadow(陰影) 及 border-radius(圓角)還增加美感
測試後在 IE7 及 Opera 上呈現會有點出入
目前只有 Firefox Chrome 能完整的呈現所有的 CSS 效果

實際呈現效果:

歡迎來到我的 Plurk


參考來源:hold on

[ActionScript] Component 動態建立與移除


/*建立 Component*/
createObject("TextInput", "name_ti", getNextHighestDepth(),{
_width:200,
_heigh:22,
_x:20,
_y:30
});

/*移除 Component*/
destroyObject("name_ti");
2010-05-24

[ActionScript] 嵌入 SWF 和影像檔

//createTextField(instanceName, depth, x, y, width, height)
this.createTextField("swf1", 10, 0, 96, 1024, 576);
swf1.html = true;
swf1.htmlText = " <img width='1024' height='576' src='my_flash.swf'/>";


參考來源:
嵌入 SWF 和影像檔 --Flash CS3
2010-05-23

EclipseColorer 不錯的語法加亮外掛

最近又找到一個不錯的 Plugin 來用
EclipseColorer 支援 150 種語言的語法標記
讓我在用 Eclipse 寫 PL/SQL 的時候至少是彩色的

但除了支援多種語言以外本身沒什麼特色
就像一個有顏色的筆記本
既然已經有詞庫了為什麼沒有語法提示呢?
美中不足 暫時堪用一下吧!

線上安裝網址:http://colorer.sf.net/eclipsecolorer/
2010-05-22

[Oracle] Sequence 取號函數


-- [新增]
CREATE SEQUENCE my_sequence
INCREMENT BY 1
START WITH 1
MAXVALUE 99999999999
NOCYCLE
CACHE 10
;

-- 參數說明:
INCREMENT BY n -- 每次疊加的值(正負數)

START WITH n -- 指定初始值,建立後將無法透過 ALTER 修改

MAXVALUE n -- 最大編號
NOMAXVALUE -- (預設)不設置最大值,由系統上限決定

MINVALUE n -- 最小編號
NOMINVALUE -- (預設 1)不設置最小值

CYCLE -- 當取至最大值後,是否循環再由最小值開始
NOCYCLE -- (預設)不設置循環,當超過限制時將返回異常

CACHE n -- (預設 20)系統會一次取出 n 個數作為快取,但會造成跳號的現象
NOCACHE -- 不使用快取,保證在產生的編號中沒有跳號,但這樣會降低性能.



-- [修改]
ALTER SEQUENCE my_sequence
INCREMENT BY 10
MAXVALUE 10000
CYCLE
NOCACHE
;



-- [刪除]
DROP SEQUENCE my_sequence;



-- [使用方式]
my_sequence.CURRVAL -- 返回序號的當前值
my_sequence.NEXTVAL -- 增加序號的值,然後返回序號值



參考來源:
Oracle 產生自動編號方式

CSS3 圓角

*{

/* Gecko browsers */
-moz-border-radius: 20px; /*all*/
-moz-border-radius: 20px 0; /*TL&BR, TR&BL*/
-moz-border-radius: 20px 0 20px; /*TL, TR&BL, BR*/
-moz-border-radius: 20px 0 20px 0; /*TL, TR, BR, BL*/
-moz-border-radius: 20px/ 10px; /*(X)/ (Y)*/
-moz-border-radius: 20px 0 20px 0/ 10px 0 10px 0; /*(X)TL, TR, BR, BL/ (Y)TL, TR, BR, BL*/

-moz-border-radius-topleft: 20px;
-moz-border-radius-topright: 0;
-moz-border-radius-bottomright: 20px;
-moz-border-radius-bottomleft: 0;


/* Webkit browsers */
-webkit-border-radius: 20px; /*all*/
-webkit-border-radius: 20px 0 20px 0; /*TL, TR, BR, BL*/

-webkit-border-top-left-radius: 20px;
-webkit-border-top-right-radius: 0;
-webkit-border-bottom-right-radius: 20px;
-webkit-border-bottom-left-radius: 0;


/* Konqueror (KDE) */
-khtml-border-radius: 20px; /*all*/
-khtml-border-radius: 20px 0 20px 0; /*TL, TR, BR, BL*/

-khtml-border-top-left-radius: 20px;
-khtml-border-top-right-radius: 20px;
-khtml-border-bottom-left-radius: 20px;
-khtml-border-bottom-right-radius: 20px;


/* ??? browsers */
-goog-ms-border-radius: 20px; /*all*/
-goog-ms-border-radius: 20px 0 20px 0;/*TL, TR, BR, BL*/

-goog-ms-border-top-left-radius: 20px;
-goog-ms-border-top-right-radius: 0;
-goog-ms-border-bottom-right-radius: 20px;
-goog-ms-border-bottom-left-radius: 0;


/* W3C syntax */
border-radius: 20px; /*all*/
border-radius: 20px 0; /*TL&BR, TR&BL*/
border-radius: 20px 0 20px; /*TL, TR&BL, BR*/
border-radius: 20px 0 20px 0; /*TL, TR, BR, BL*/
border-radius: 20px/ 10px; /*(X)/ (Y)*/
border-radius: 20px 0 20px 0/ 10px 0 10px 0; /*(X)TL, TR, BR, BL/ (Y)TL, TR, BR, BL*/

border-top-left-radius: 20px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius:  20px;

}


參考來源:
CSS Backgrounds and Borders Module Level 3
CSS Border Radius :: Richard A. Johnson
border-radius與圓角 - wowbox blog (網頁設計知識庫)

CSS 偽類 與 偽元素

:link
未被訪問過的連結
IE6, FF3, Safari3, Chrome5, Opera
:visited
已被訪問過的連結
IE6, FF3, Safari3, Chrome5, Opera
:hover
滑鼠重疊時(mouse over)
IE7, FF3, Safari3, Chrome5, Opera
:active
元素被按下時(mouse down)
IE6, FF3, Safari3, Chrome5, Opera
:focus
元素被選擇時
IE8, FF3, Safari3, Chrome5, Opera
:first-line
區塊內的第一行
IE7, FF3, Safari3, Chrome5, Opera
:first-letter
區塊內的第一個字
IE7, FF3, Safari3, Chrome5, Opera
:first-child
元素為第一個項目時
IE7, FF3, Safari3, Chrome5, Opera
:last-child
元素為最後一個項目時
IE9, FF3, Safari3, Chrome5, Opera
:lang
指定元素中使用的語言
IE6, FF3, Safari3, Chrome5, Opera
:before
區塊內最前面加入一個虛擬元素
IE8, FF3, Safari3, Chrome5, Opera
:after
區塊內最後面加入一個虛擬元素
IE8, FF3, Safari3, Chrome5, Opera


參考來源:
CSS Selectors and Pseudo Selectors and browser support
Web Browser CSS Support
2010-05-19

在 Blogger 加上各種推文按鈕(最終版)

經過多次的修修改改
我想我應該不會再改了
這裡我只提供我目前的程式碼
詳細教學請至在 Blogger 加上各種推文按鈕



/*Social Icon*/
.social{
background:transparent url(http://www.xxxx.com/social_icons.png) 0 0 no-repeat;
/*16*16按鈕的圖片網址*/

display: -moz-inline-box;
display: inline-block;
height:16px;
margin:0 4px;
text-indent:-999999px;
vertical-align:middle;
width:16px;
opacity:0.75;
overflow:hidden;
}
.social:hover{
opacity:1;
}

a.toFacebook{ background-position: 0 0; }
a.toPlurk{ background-position: 0 -16px; }
a.toTwitter{ background-position: 0 -32px; }
a.toTechnorati{ background-position: 0 -48px; }
a.toDelicious{ background-position: 0 -64px; }
a.toBuzz{ background-position: 0 -80px; }
a.toDigg{ background-position: 0 -96px; }
a.toStumbleUpon{ background-position: 0 -112px; }
a.toDesignFloat{ background-position: 0 -128px; }
a.getAtomRSS{ background-position: 0 -144px; }
a.toReader{ background-position: 0 -160px; }


<div class='post-footer-line post-footer-line-99'><span class='post-social-icons'>
分享至 &#65306;
<a class='social toFacebook' expr:href='&quot;http://www.facebook.com/sharer.php?u=&quot;+ data:post.url + &quot;&amp;t=&quot; + data:post.title' rel='external nofollow' target='_blank' title='分享至 Facebook'>Facebook</a>
<a class='social toPlurk' expr:href='&quot;http://www.plurk.com/?qualifier=shares&amp;status=&quot;+ data:post.url + &quot; (&quot; + data:post.title + &quot;)&quot;' rel='external nofollow' target='_blank' title='分享至 Plurk'>Plurk</a>
<a class='social toTwitter' expr:href='&quot;http://twitter.com/home?status=&quot; + data:post.title + &quot; &quot;+ data:post.url' rel='external nofollow' target='_blank' title='分享至 Twitter'>Twitter</a>
<a class='social toTechnorati' expr:href='&quot;http://technorati.com/faves?add=&quot;+ data:post.url + &quot; &quot; + data:post.title' rel='external nofollow' target='_blank' title='分享至 Technorati'>Technorati</a>
<a class='social toDelicious' expr:href='&quot;http://del.icio.us/post?url=&quot;+ data:post.url + &quot; &quot; + data:post.title' rel='external nofollow' target='_blank' title='儲存至 Delicious'>Delicious</a>
<a class='social toDigg' expr:href='&quot;http://digg.com/submit?phase=2&amp;url=&quot;+ data:post.url + &quot;&amp;title=&quot; + data:post.title' rel='external nofollow' target='_blank' title='分享至 Digg'>Digg</a>
<a class='social toStumbleUpon' expr:href='&quot;http://www.stumbleupon.com/submit?url=&quot;+ data:post.url + &quot;&amp;title=&quot; + data:post.title' rel='external nofollow' target='_blank' title='分享至 Stumble Upon'>Stumble Upon</a>
<a class='social toDesignFloat' expr:href='&quot;http://www.designfloat.com/submit.php?url=&quot;+ data:post.url + &quot;&amp;title=&quot; + data:post.title' rel='external nofollow' target='_blank' title='分享至 Design Float&quot;'>Design Float</a>
<a class='social toReader' expr:href='&quot;http://www.google.com/reader/link?url=&quot;+ data:post.url + &quot;&amp;title=&quot; + data:post.title + &quot;&amp;srcURL=&quot;+data:blog.homepageUrl' rel='external nofollow' target='_blank' title='分享至 Google Reader'>Google Reader</a>
<a class='social toBuzz' expr:href='&quot;http://www.google.com/buzz/post?url=&quot;+ data:post.url' rel='external nofollow' target='_blank' title='分享至 Buzz'>Buzz</a>
<a class='social getAtomRSS' href='/feeds/posts/default' title='訂閱 Atom / RSS' type='application/atom+xml'>Atom / RSS</a>
</span></div>


圖片來源:

Social Media Network Icons | Komodo Media
2010-05-17

Nokia Widget 實作講堂

今天去參加了第二場 Nokia 辦得活動當然要來記錄一下
這一次的講師非常的 funny 分享了很多經驗
而且他的公司名稱也很妙 有的放矢行動行銷股份有限公司
為了找他的公司網址無意間找到 Wiki 的解釋 有的放矢 - 維基詞典

再來就是其實 Nokia 的手機大部分的硬體配備都不高
並沒有想像中的好 ,有些 CPU 可能只有 20MHz
可以跑這麼順主要的原因是他有一個優秀 OS (Symbian)
並且可以完全的多工多執行緒(難怪我不小心操一下就沒電了)
有一次開著 Google Map 再來一個全時 GPS 連線
我的 Nokia 6110n 在滿電的情況下只用了半小時就沒電了 真是讓我傻眼的說
在沒有備用電源的情況下我現在都不太敢再全時 GPS 連線了


言歸正傳今天的 Workshow 到底再說什麼呢??
Widget 基本上的架構就如我們大家所熟知的 HTML + CSS + JavaScript + Ajax
但不一樣的是這裡我們可以透過 Platform Services API 去存取手機上的裝置
GPS 位址收發簡訊通訊錄行事曆 等等… 一整個就很快樂
感覺就像在寫 Firefox 的 plugin
而且在 package 時也是用 zip 壓縮
但講師說硬體資源的有限會讓你很不快樂,它只是一台手機並不是一台電腦
以前在學校時寫過 PDA 所以這種切身之痛我非常瞭解
盡可能別在手機上做大量運算,要不然它就 crash 給你看

在實做時我又再一次的見證 Eclipse 的偉大(很好又是我熟悉的 SDK 平台)
上次的 QT 也是有 Eclipse 的 plugin 而這一次的 Widget 也有 plugin
而且有很多一鍵完成的功能(雖然在 Eclipse 上本來就是這樣了)
只是 Eclipse 一直都沒有很好的 Script debug 整合
雖然 Aptana 上的 JavaScript 即時除錯已經很好用了,但卻僅限於 JavaScript
最近拿來寫 ActionScript 也是不錯用,但還是覺得不夠好
可是目前還沒找到其他的替代方案

最後在跟講師換名片時幽默的說也想買一台 Tivo
對於 Tivo 名聲心裡小小高興一下
但忠小晞我 對自己的孤陋寡聞也慚愧了一下

下次來寫一個 widget 來玩玩
如果老大可以給點 resource 就更好了


參考資料:
Nokia N97 SDK
Web Runtime Code Examples
Platform Services 2.0 JavaScript API reference
Nokia Platform Services 2.0 Download


PS:
既然參加免費的講習多少為對方打個廣告
Nokia 目前(2010/6/11止)有舉辦創意競賽最高獎金 20 萬
詳情請見:Symbian & Maemo中文資訊站
2010-05-16

三分鐘瞭解 XSS 攻擊原理

在看完酷壳寫的HTML 安全列表
突然很想寫一篇有關 XSS 的快速教學
讓更多人能瞭解何謂 XSS 安全漏洞


在瞭解 XSS 之前必須知道『網站登入(Session)』的原理

簡單的說當會員成功登入後 網站會給瀏覽器一個『令牌』
之後只要拿著這個『令牌』到網站上 就會被視為已經登入


再來下面是 XSS 最簡單的流程

簡單的說駭客透過 JavaScript 的程式碼將你的『令牌』偷走
透過這個『令牌』他也可以用你的身份順利登入網站
然後偷走你的相關資料(個人資料&交易資料)
然後再將這些資料賣給詐騙集團


相關的參考資料:
跨網站指令碼 - 維基百科
Cross-site Scripting (XSS) - OWASP
XSS(Cross Site Scripting)攻擊會讓您遺失Cookie中的資料
詳解XSS攻擊 - 網路攻防戰
HTML5 Security Cheatsheet
2010-05-15

在 Blogger 加上各種推文按鈕

在寫完上一篇 Facebook 推文按鈕後
想一想乾脆把其他社群的推文按鈕也加上好了
這裡我做了兩個大小的推文按鈕
PS:最終版程式碼

32*32 的推文按鈕



/*Social Icon*/
.social{
background:transparent url(http://www.xxx.com/social_icons.png) 0 0 no-repeat;
/*32*32按鈕的圖片網址*/

display: -moz-inline-box;
display: inline-block;
height:32px;
margin:0 2px;
text-indent:-999999px;
vertical-align:middle;
width:32px;
}

.toFacebook{ background-position: 0 0; }
.toPlurk{ background-position: 0 -32px; }
.toTwitter{ background-position: 0 -64px; }
.toDelicious{ background-position: 0 -96px; }
.toTechnorati{ background-position: 0 -128px; }
.toBuzz{ background-position: 0 -160px; }


16*16 的推文按鈕



/*Social Icon*/
.social{
background:transparent url(http://www.xxx.com/social_icons.png) 0 0 no-repeat;
/*16*16按鈕的圖片網址*/

display: -moz-inline-box;
display: inline-block;
height:16px;
margin:0 4px;
text-indent:-999999px;
vertical-align:middle;
width:16px;
}

.toFacebook{ background-position: 0 0; }
.toPlurk{ background-position: 0 -16px; }
.toTwitter{ background-position: 0 -32px; }
.toTechnorati{ background-position: 0 -48px; }
.toDelicious{ background-position: 0 -64px; }
.toBuzz{ background-position: 0 -80px; }


首先打開『版面配置』→『修改HTML』
將『展開小裝置範本』打勾
找到 ]]></b:skin> 將 CSS 的程式貼在上一行
小技巧:所有的瀏覽器都有搜尋功能 (Ctrl + F),只要搜尋 "skin" 就可以找到這行了



這裡我也介紹兩種的呈現佈局

第一種直接嵌在文章的後面:
找尋 <div class='post-body entry-content'> 這一行
將下面的程式貼在 <div style='clear: both;'/> 之前

<div>
分享至 :
<a class="social toFacebook" expr:href='"http://www.facebook.com/sharer.php?u="+ data:post.url + "&amp;t=" + data:post.title' rel='external nofollow' target='_blank' title='分享至 Facebook'>Facebook</a>
<a class="social toPlurk" expr:href='"http://www.plurk.com/?qualifier=shares&amp;status="+ data:post.url + " (" + data:post.title + ")"' rel='external nofollow' target='_blank' title='分享至 Plurk'>Plurk</a>
<a class="social toTwitter" expr:href='"http://twitter.com/home?status=" + data:post.title + " "+ data:post.url' rel='external nofollow' target='_blank' title='分享至 Twitter'>Twitter</a>
<a class="social toTechnorati" expr:href='"http://technorati.com/faves?add="+ data:post.url + " " + data:post.title' rel='external nofollow' target='_blank' title='分享至 Technorati'>Technorati</a>
<a class="social toDelicious" expr:href='"http://del.icio.us/post?url="+ data:post.url + " " + data:post.title' rel='external nofollow' target='_blank' title='儲存至 Delicious'>Delicious</a>
<a class="social toBuzz" expr:href='"http://www.google.com/reader/link?url="+ data:post.url + "&amp;title=" + data:post.title + "&amp;srcURL="+data:blog.homepageUrl' rel='external nofollow' target='_blank' title='分享至 Buzz'>Buzz</a>
</div>

這會看起來像這樣:



第二種是嵌在文章資訊列上:
找尋 <div class='post-footer'> 這一行
然後向下找尋相對應的 </div>
這裡沒有比較清楚的標示
找起來會比較困難一點
將下面的程式貼在 </div> 之前

<p class='post-footer-line post-footer-line-99'><span class='post-social-icons'>
分享至 :
<a class='social toFacebook' expr:href='"http://www.facebook.com/sharer.php?u="+ data:post.url + "&amp;t=" + data:post.title' rel='external nofollow' target='_blank' title='分享至 Facebook'>Facebook</a>
<a class='social toPlurk' expr:href='"http://www.plurk.com/?qualifier=shares&amp;status="+ data:post.url + " (" + data:post.title + ")"' rel='external nofollow' target='_blank' title='分享至 Plurk'>Plurk</a>
<a class='social toTwitter' expr:href='"http://twitter.com/home?status=" + data:post.title + " "+ data:post.url' rel='external nofollow' target='_blank' title='分享至 Twitter'>Twitter</a>
<a class='social toTechnorati' expr:href='"http://technorati.com/faves?add="+ data:post.url + " " + data:post.title' rel='external nofollow' target='_blank' title='分享至 Technorati'>Technorati</a>
<a class='social toDelicious' expr:href='"http://del.icio.us/post?url="+ data:post.url + " " + data:post.title' rel='external nofollow' target='_blank' title='儲存至 Delicious'>Delicious</a>
<a class='social toBuzz' expr:href='"http://www.google.com/reader/link?url="+ data:post.url + "&amp;title=" + data:post.title + "&amp;srcURL="+data:blog.homepageUrl' rel='external nofollow' target='_blank' title='分享至 Buzz'>Buzz</a>
</span></p>

這會看起來像這樣:



Blogger 範本 (樣版)變數說明:

expr: 讓 xxx='data:var_name' 裡面可以使用變數
data:blog.homepageUrl Blog 首頁的網址
data:blog.pageTitle Blog 的標題 + 文章標題
data:blog.title Blog 的標題
data:description Blog 的描述
data:blog.url 當前頁面的網址
data:post.url 文章連結(在 Loop 裡才有用)
data:post.title 文章標題(在 Loop 裡才有用)
data:post.body 文章內容(在 Loop 裡才有用)


圖片來源:

Social Media Network Icons | Komodo Media

參考連結:

版面配置資料標記 - Blogger說明