2014年8月21日 星期四

[Linux] 找尋 PHP 檔案內,用到 mysql_* 函數的檔案清單 @ Ubuntu 14.04

三個月前用過又忘了 Orz  還是筆記一下:

$ find /path/target -name "*.php" -exec sh -c 'cnt=`grep -c "mysql_" {}` && test $cnt -gt 0 && echo {}' \;

2014年8月19日 星期二

iOS 開發筆記 - 使用 NSURLConnection 取得 HTTP Content-type / MIME type Only

原先 NSURLConnection 本身就可以在 connection: didReceiveResponse: 時,從 NSURLResponse 中取得 MIMEType 了,但如果就只是需要 MIMEType 的話,不仿對 NSURLRequest 中,多設定 [req setHTTPMethod:@"HEAD"]; 資訊,如此一來,就只抓 Header 資訊而已。

- (void)checkMIMEType:(NSURL *)url
{
NSMutableURLRequest *req  = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"HEAD"];
[[NSURLConnection connectionWithRequest:req delegate:self] start];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(@"didReceiveResponse: %@, URL: %@", [response MIMEType], connection.currentRequest.URL);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"didReceiveData: %lu", [data length]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"didReceiveLoading");
}


以上述的例子中,當 [req setHTTPMethod:@"HEAD"]; 時,不會跑進 connection: didReceiveData: 裡。

[Linux] 安裝與使用 influxDB @ Ubuntu 14.04

最近想搞系統監控圖表,雖然已經有一些常見做法,不過,還是先試一下新東西吧,用用最近很夯的 Grafana 圖表神器,但還是得搭配一套儲存系統,就先試試 influxDB 了。

首先,先裝 influxDB,用它記錄時間屬性的資料流:

$ wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb
$ sudo dpkg -i influxdb_latest_amd64.deb
$ sudo service influxdb start
Starting the process influxdb [ OK ]
influxdb process was started [ OK ]


安裝後,就可以從 http://localhost:8083 登入,預設帳密 root/root。登入後,記得更改一下帳密,以下仍以 root/root 為例。



先建立一個 Database : server



若要新增資料,可以透過 POST API 進行,且 API 預設採用 8086 port:

例如建立一個 table 名為 http ,並有 id, val 兩個欄位,依序傳入 3 筆資料 ["server1", 23] , ["server1", 80], ["server1", 36], ["server2",70]

$ curl -X POST -d '[{"name":"http","columns":["id","val"],"points":[["server1",23]]}]' 'http://localhost:8086/db/server/series?u=root&p=root'

...


瀏覽時,使用 SELECT * FROM http WHERE id = 'server1' 即可:



未來就可以開放 API 提供 Grafana 撈資料出來。

[Linux] 初次使用 Docker 筆記 @ Ubuntu 14.04

最近找尋系統監控的方式時,無意間看到 Docker 的消息,雖然以前用過 LXC 一陣子,久了沒用又都忘光光,這次 Docker 還滿紅的,就順手學一下吧!若安裝前,想體驗一下,可以試看看官網推的教學模式:https://www.docker.com/tryit/

在使用前,想說找一下 Docker 的商業模式,找了很久都沒看到 XD 直到使用 Docker hub 時才發現,商業模式就像 github/bitbucket 一樣,想要建立 private repo 的則需要付費,此例就是可以打包自己的開發環境送到 Docker hub 上使用,免費方案有提供 1 個 private 單位哦。


回到筆記,根據官網介紹 https://docs.docker.com/installation/ubuntulinux/,依序幾個動作就完成安裝了:

$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io


開始使用:

$ sudo docker run ubuntu:12.04 echo "hello world"
Unable to find image 'ubuntu:12.04' locally
Pulling repository ubuntu
822a01ae9a15: Download complete
511136ea3c5a: Download complete
93c381d2c255: Download complete
a5208e800234: Download complete
9fccf650672f: Download complete
1186c90e2e28: Download complete
f6a1afb93adb: Download complete
hello world


此命令是說要跑一個 ubuntu 12.04 環境,在其環境執行 echo "hello world" 的意思,整個過程就是包含初始化(下載image)後,最後在執行 echo "hello world",有興趣可以再執行一次,這次就不會再去下載 image 了。

然而,上述的動作只是一次性的,舉例來說,初始環境執行 apt-get install curl 是會出錯的:

$ sudo docker run ubuntu:12.04 apt-get install curl
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package curl


但只要 apt-get update 後就會正常,但不能分開執行:

$ sudo docker run ubuntu:12.04 apt-get update
Get:1 http://archive.ubuntu.com precise Release.gpg [198 B]
Get:2 http://archive.ubuntu.com precise-updates Release.gpg [198 B]
Get:3 http://archive.ubuntu.com precise-security Release.gpg [198 B]
...
Reading package lists...
$ sudo docker run ubuntu:12.04 apt-get install curl
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package curl


因此,正式的使用其實是開個 terminal 進去連續動作:

$ sudo docker run -t -i ubuntu:12.04
root@431bb00c701d:/#


其中 431bb00c701d 則是此 container ID,

root@431bb00c701d:/# apt-get install wget
Reading package lists... Done
Building dependency tree    
Reading state information... Done
E: Unable to locate package wget
root@431bb00c701d:/# apt-get update
...
root@431bb00c701d:/# apt-get install wget
Reading package lists... Done
Building dependency tree      
Reading state information... Done
The following extra packages will be installed:
  libidn11
The following NEW packages will be installed:
  libidn11 wget
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 391 kB of archives.
After this operation, 966 kB of additional disk space will be used.
Do you want to continue [Y/n]?


接著按 exit 離開後,其實就跟上述單行指令操作一樣,什麼都沒留下,因此在離開之前,想要保存環境則是要進行 commit。

此時,必須額外再開一個 terminal 用 docker ps 查看目前已執行的 image 環境:

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5db62a9bf492        ubuntu:14.04        /bin/bash           11 seconds ago      Up 10 seconds                           goofy_curie      
431bb00c701d        ubuntu:12.04        /bin/bash           35 seconds ago      Up 34 seconds                           agitated_thompson


此例代表有2個 container 在運行,此例目標是 ubuntu:12.04 的 431bb00c701d ,想要儲存環境變化,就來個 commit 吧

$ sudo docker commit -m 'ubuntu 12.04 with wget' 431bb00c701d
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
<none>              <none>              aac0f5ce2936        9 minutes ago       137.7 MB
ubuntu              14.04               c4ff7513909d        7 days ago          213 MB
ubuntu              12.04               431bb00c701d        7 days ago          108 MB


想要有更佳的描述,就在 docker commit  時,多加一點資訊 REPOSITORY[:TAG] 吧:

$ sudo docker commit -m 'ubuntu 12.04 with wget' e7e35769932d MyUbuntu:12.04
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
MyUbuntu            12.04               d3466dce0e51        About a minute ago   108 MB
<none>              <none>              aac0f5ce2936        10 minutes ago       137.7 MB
ubuntu              14.04               c4ff7513909d        7 days ago           213 MB
ubuntu              12.04               431bb00c701d        7 days ago           108 MB


下次要用時:

$ sudo docker run -i -t MyUbuntu:12.04
root@600d3fee924d:/# wget
wget: missing URL
Usage: wget [OPTION]... [URL]...

Try `wget --help' for more options.


@ 2014-10-24 加映場:[Linux] Docker 使用筆記 - 常用指令 @ Ubuntu 14.04

2014年8月18日 星期一

iOS 開發教學 - 邀請使用者評論、評分 iOS app (Review/Rate your iOS app)

原理就是第一次使用時,埋一個時間進去,等下次使用者使用 iOS app 時,判斷時間是否夠長,達到時間間距時,使用 UIAleterView 詢問使用者是否願意 Rate your app。

假設 iOS app 預設啟用時,停留在某個 ViewController:

@interface ViewController () <UIAlertViewDelegate>
// ...
@end


@implementation ViewController

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    switch (alertView.tag) {
        case YOUR_APP_ID:
        {
            //NSLog(@"buttonIndex: %d", buttonIndex);
            NSDate * now = [[NSDate alloc] init];
            switch (buttonIndex) {
                case 1: // YES
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/id%d", alertView.tag]]];
                    [[NSUserDefaults standardUserDefaults] setObject:now forKey:@"rateDone"];
                    break;
                case 2: // Remind me later
                    [[NSUserDefaults standardUserDefaults] setObject:now forKey:@"rateDate"];
                    break;
                default:
                    [[NSUserDefaults standardUserDefaults] setObject:now forKey:@"rateDone"];
                    break;
            }
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
            break;
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    @try {
        //[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"rateDone"];
        //[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"rateDate"];
        //[[NSUserDefaults standardUserDefaults] synchronize];
     
        if (![[NSUserDefaults standardUserDefaults] objectForKey:@"rateDone"]) {
            NSDate * now = [[NSDate alloc] init];
            if (![[NSUserDefaults standardUserDefaults] objectForKey:@"rateDate"]) {
                [[NSUserDefaults standardUserDefaults] setObject:now forKey:@"rateDate"];
                [[NSUserDefaults standardUserDefaults] synchronize];
            } else {
                NSDate *prevDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"rateDate"];
                if ([now timeIntervalSinceDate:prevDate] > 60 * 60 * 10) {
                    UIAlertView *alterView = [[UIAlertView alloc] initWithTitle:@"Rate this app" message:@"If you enjoy using this app, would you mind taking a moment to rate it?" delegate:self cancelButtonTitle:@"NO, Thanks" otherButtonTitles:@"YES", @"Remind me later", nil];
                    alterView.tag = YOUR_APP_ID;
                    [alterView show];
                }
            }
        }
    }
    @catch (NSException *exception) {
    }
    @finally {
    }
}

@end