2014/12/04

在瀏覽器上隱藏select option



由於部分瀏覽器(IE sucks)不支援option.style='display:none';的樣式

導致有時候想要動態隱藏/顯示某些下拉式選單的時候就要另想辦法處理

stackoverflow上有人提出了用一個隱藏span包住該option

這個方法的確可以達到隱藏/顯示option

可是我發現了一些bug

Bug 1:
在chrome上如果一開始就加上span則該node會永遠消失

```html
<select>
<option value="1">1</option>
<span class="toggleOption" style="display: none;"><option value="2">2</option></span>
<option value="3" selected>3</option>
</select>
```

Bug :2
在chrome39上,執行以下隱藏option[value=2],則$('select').val()有機會不會是3

```html
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
</select>
```
$('select>option[value=2]').toggleOption(false);


這兩個是很嚴重的bug

那不如我自己寫一個jquery的plugin吧

傳送門

例子放在jsfiddle

只要使用$('#myselect').selectOption();初始化你的select

之後就可以用
```js
$('#myselect').hideAllOption();
$('#myselect').showAllOption();
$('#myselect').hideOption(':gt(1)');
$('#myselect').showOption(':gt(1)');
$('#myselect').showOption('[value=1]');
```
等的api去顯示或隱藏option囉!

2014/11/13

在reverse proxy後取得原始客戶端ip


首先文章以以下代稱
Nginx代表的是Reverse proxy server
Apache代表的是Backend server

透過Nginx反向代理Apache

通常在Apache拿到的Client IP會是這個Nginx的IP


為了將Client IP(Remote IP)傳送到Apache

我們必須在Nginx與Apache做點設定

Nginx端的設定:

proxy.conf
```
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
```

此設定是為了將Client IP放到往Apache送的Request header中

但是單單做這樣的這定Apache的log還是不會紀錄Nginx的IP

以下重要的來了

Apache端必須安裝mod_rpaf這個套件

```
sudo apt-get install libapache2-mod-rpaf
```

接著編輯rpaf.conf

```
<ifmodule mod_rpaf-2.0.c>
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 ::1 #這邊加上Nginx的IP
RPAFheader X-Forwarded-For
</IfModule>
```

將Nginx與Apache重啟後
Apache的log就會記錄真正的Client IP了

2014/11/05

無法使用key登入ssh的問題



網路上有一堆教學文章

像是
"使用 SSH key 登入"
"兩行指令搞定 Linux SSH登入免密碼"
等等

我試了一下果然照這樣設定就可以免密碼登入

但是偶而還是遇到了一些問題

以下為我整理後與解決問題的方法


產生rsa公私密鑰
-f為指定產生的檔案位置
-P代表產出來的密碼passphrase為空(這邊採用簡單方法以避免登入時還是需要輸入passphrase 見註1)


ssh-keygen -t rsa -f ~/.ssh/sshkey -P ''

將公鑰加入到server的authorized_keys中

scp sshkey.pub user@your.server.com:~/.ssh/
ssh your.server.com
cat ~/.ssh/sshkey.pub >> ~/.ssh/authorized_keys

或者

ssh-copy-id -i ~/.ssh/sshkey.pub your.server.com

寫入config設定

cat ~/.ssh/config
Host your.server.com
HostName your.server.com
User user
Port 22
identityFile ~/.ssh/sshkey

設完之後卻可以免密碼登入ssh了
所以我又設了第二台
結果卻又一值提示我要輸入密碼

研究了很久發現是authorized_keys的權限不對

請修改成600或640

chmod 600 ~/.ssh/authorized_keys

這樣就完成囉




註1:
由於指定passphrase後 在login時還是需要輸入這個passphrase
若是必須指定passphrase的話請用ssh-agent去自動輸入passphrase
可參考 http://josephj.com/article/understand-ssh-key/

2014/11/03

送交(commit) git log 到svn repository



最近迷上了git,所以基本上只要修改或建立新的專案我都是建立git的repository

不過公司還是使用svn當作repository

那如果我想要把我在git上的commit log保留並且commit到svn那該怎麼辦呢?

當初從svn轉到git有用到一個套件"git-svn"

這次也是利用它來達成我的目標:

將git的log commit到svn上

首先 安裝它

環境:CentOS 5.9

```
yum install git-svn
```

利用git-svn 抓取svn source tree下來

```
git svn clone svn://moa.tw/my/svn/repository/more/folder/is/working ./svn2git
```

將原先存在的git repository新增為svn2git底下名為source的remote

```
cd svn2git/
git remote add -f source /moa/tw/git/repo/project
```

重新間接基準點到git-svn

```
git rebase --onto remotes/git-svn --root source/master
```

途中也許有衝突發生

```
Auto-merging view/base2.tmpl.html
CONFLICT (content): Merge conflict in view/base2.tmpl.html
Auto-merging view/base.tmpl.html
CONFLICT (content): Merge conflict in view/base.tmpl.html
Failed to merge in the changes.
```

修正後繼續即可

```
git add view/base2.tmpl.html
git add view/base.tmpl.html
git rebase --continue
```

之後就會看到一堆類似下面的訊息,也就是正在一筆一筆轉換

```
Applying: xxxxxxxxxxxxxxxxx
Applying: yyyyyyyyyyyyyyyyy
```

跑完之後執行

```
git svn dcommit
```

就會把log一併commit到svn repository了

接下來該探討的就是:

我是否可以繼續用git commit/push到git的repo,但是我想要commit回svn時,隨時都可以commit,而不怕source衝突




參考連結:
http://goodliffe.blogspot.tw/2011/08/pushing-git-repository-into-existing.html

2014/10/03

如何產生ssh key供git登入


以下如果要產生給github用的 ssh key

我習慣命名為github

```
ssh-keygen -t rsa -P '' -f ~/.ssh/github -C 'your@email5566.com'
```

這樣會在你的~/.ssh下建立兩個檔案
~/.ssh/github 與 ~/.ssh/github.pub

~/.ssh/github是私鑰要好好保存
~/.ssh/github.pub可以丟到github上

接著建立~/.ssh/config檔案,內容為

```
Host github.com
Hostname github.com
User git
Port 22
identityfile ~/.ssh/github
```

這樣在使用ssh連到github.com時他就會自己做認證了

如何做 “git export” (像 “svn export”)?



完成一個版本後想要發行

如果用git clone的話又會產生.git資料夾

以下提供如何做到像svn export一樣的功能

利用git archive
```
$ git archive -h
usage: git archive [options] <tree-ish> [<path>...]
or: git archive --list
or: git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]
or: git archive --remote <repo> [--exec <cmd>] --list

--format <fmt> archive format
--prefix <prefix> prepend prefix to each pathname in the archive
-o, --output <file> write the archive to this file
--worktree-attributes
read .gitattributes in working directory
-v, --verbose report archived files on stderr
-0 store only
-1 compress faster
-9 compress better

-l, --list list supported archive formats

--remote <repo> retrieve the archive from remote repository <repo>
--exec <cmd> path to the remote git-upload-archive command
```

使用方法1:
倒出master到某個資料夾

```
git archive master | tar -x -C /somewhere/else
```


使用方法2:
倒出master時加入參數直接打包壓縮
```
git archive --format tar.gz --output /full/path/to/zipfile.tgz master
```

2014/10/01

轉移 svn 到 git



最近公司開始導入 git

我也開始學了一下~ 覺得 git 實在很好用

所以要把自己的 svn server 改成 git

以下教學如何把 svn 移植到git

首先先將 svn 中原有使用者資訊給列出

```shell
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > ~/authors-transform.txt
```

再來用灌 git-svn 並執行:
```shell
git svn clone "你的 svn repo" --no-metadata -A ~/authors-transform.txt --no-minimize-url ~/temp
```

這樣~/temp就會是你的 repo 了,如果原先 repo 很雜亂,多個專案都使用同一個的話也沒問題。

再來把git專案push到git server上

```shell
git remote add origin git@bitbucket.org:yours.git
git push -u origin --all
```

完成

2015/02/03 補充

在轉換的 svn 中,空的資料夾會遺失
必須加上 --preserve-empty-dirs

```shell
git svn clone "你的 svn repo" --no-metadata --preserve-empty-dirs -A ~/authors-transform.txt --no-minimize-url ~/temp
```
官網說明:
--preserve-empty-dirs
Create a placeholder file in the local Git repository for each empty directory fetched from Subversion. This includes directories that become empty by removing all entries in the Subversion repository (but not the directory itself). The placeholder files are also tracked and removed when no longer necessary.

--placeholder-filename=<filename>
Set the name of placeholder files created by --preserve-empty-dirs. Default: ".gitignore"


2016/01/07 補充

若只想 clone 部分範圍的 commit 可已加上 -r "開始版號":"結束版號"

```shell
git svn clone -r 100:200 "你的 svn repo" --no-metadata --preserve-empty-dirs -A ~/authors-transform.txt --no-minimize-url ~/temp
```

2014/06/16

SVN 備份與還原

備份:

```
svnadmin dump /your/repo > repo.dump
```

搭配gz壓縮
```
svnadmin dump /your/repo | gz -9 repo.dump.gz
```

還原:
```
svnadmin load /your/repo/dest < repo.dump
```

2014/03/20

[HTML5]利用ajax做檔案下載



同事說不可能用1個ajax去下載檔案

於是乎我就研究了一下
程式碼如下:

js code:
<script>
$(function(){
 $.ajax('/ajax/getFile', {dataType:'json', success:function(data){
   var bb = new Blob([data.content], {type: 'application/octet-binary'});
   $('#link')
   .attr({download:'file.bin',href:window.URL.createObjectURL(bb)})
 }});
});
</script>
其實這是利用<a>的download屬性(Working Draft:w3schools)
加上Blob這物件將檔案內容轉為blob格式使得瀏覽器可以下載

html:
<div id="main">
 <a id="link">Download File</a>
</div>

backend: (use nodejs express)

exports.getFile = function(req, res){
 fs.readFile('file', function (err, data) {
  res.json({status:'ok',content:data.toString()});
 });
};


reference:
http://caniuse.com/download
http://html5-demos.appspot.com/static/a.download.html

2014/01/27

[網站]好用的css icon網站



1. [http://findicons.com](http://findicons.com)

2. [http://www.webhostinghub.com](http://www.webhostinghub.com)

在linux下利用iptables做nat




由於最近有一個環境

guestA(external IP: 1.1.1.1, internal IP: 192.168.56.2)
guestB(internal IP: 192.168.56.3)

在同一個host下有兩台virtualbox guest中,只有一台有外部ip(1.1.1.1)