Category: php

[php] plurk bot 跨年撲

先前看到 皮樂的撲. 有人傳說會加業障100. 所以來玩看看吧

材料 :
Linux base機器一台(mac也許可以), at, php 還有 php plurk api,

烹煮方式 :
1. 先確認你的 linux 環境有沒有 at 和 php 指令.
2. 下載 php plurk api , 放到你想執行的目錄.
3. 到 Get an API key 申請 plurk api key.
4. 撰寫簡單的撲機器人, 該檔案放在與 php plurk api 同目錄. 下面是簡單的撲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/php
<?php
 
$api_key = 'YOUR_PLURK_API_KEY';
$username = 'YOUR_PLURK_ID';
$password = 'YOUR_PLURK_PASSWORD';
 
require('plurk_api.php');
 
$plurk = new plurk_api();
$plurk->login($api_key, $username, $password);
 
$output = "新年快樂..林北現在正在拍煙火...";
echo $output;
echo "\n\n ----- add plurk ----- \n";
$plurk->add_plurk('en', 'says', $output);
?>

5. 存檔後用 php 指令去執行它. 理論上它就可以幫你自動撲到你的 plurk. 如下 :

/usr/bin/php /home/sam/plurk/newyear.php

可以把這個指令存到文字檔內. 我命名它為 plurk_newyear

6. 再搭配 at 指令讓他在凌晨的時候撲.

# at 00:00 < plurk_newyear

7. 檢查一下看看它是不是在排程當中.

# at -l
1 2011-01-01 00:00 a sam

順利的話..就會有跨年撲. XD

HOWTO Delete Non-primary Google Calendar Event?

When you created google calendar event, you will get google event id. something like below :

http://www.google.com/calendar/feeds/default/private/full/yyyyy

After you created non-primary google calendar event, you will get event id similar with following :

http://www.google.com/calendar/feeds/liho.tw_xxxxx%40group.calendar.google.com/

private/full/yyyyy

Following is part of Calendar.php which only supports the google default event :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function deleteEventById ($client, $eventId)
{
  $event = getEvent($client, $eventId);
  $event->delete();
}
 
function getEvent($client, $eventId)
{
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $query->setUser('default');
  $query->setVisibility('private');
  $query->setProjection('full');
  $query->setEvent($eventId);
 
  try {
    $eventEntry = $gdataCal->getCalendarEventEntry($query);
    return $eventEntry;
  } catch (Zend_Gdata_App_Exception $e) {
    var_dump($e);
    return null;
  }
}

You need to un-commet the following :

$query->setUser(‘default’);

And add your calendar id to similar below :

$query->setUser(‘liho.tw_xxxxx%40group.calendar.google.com’);

After you modified, you are able to delete non-primary google calendar event. However, above example is not smart enough. You should rewrite the getEvent function to add non-primary google calendar id. like below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function deleteEventById ($client, $eventId, $calendarid = "default")
{
  $event = getEvent($client, $eventId, $calendarid);
  $event->delete();
}
 
function getEvent($client, $eventId, $calendarid)
{
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $query->setUser($calendarid);
  $query->setVisibility('private');
  $query->setProjection('full');
  $query->setEvent($eventId);
 
  try {
    $eventEntry = $gdataCal->getCalendarEventEntry($query);
    return $eventEntry;
  } catch (Zend_Gdata_App_Exception $e) {
    var_dump($e);
    return null;
  }
}

php dateDiff 顯示兩個時間差多少天?多少分鐘?

差幾天 function

1
2
3
4
5
6
7
8
function dateDiff($startDate, $endDate) {
    $startArry = getdate(strtotime($startDate));
    $endArry = getdate(strtotime($endDate));
    $start_date = gregoriantojd($startArry["mon"], $startArry["mday"], $startArry["year"]);
    $end_date = gregoriantojd($endArry["mon"], $endArry["mday"], $endArry["year"]);
 
    return round(($end_date - $start_date), 0);
}

差幾分鐘 function

1
2
3
4
5
6
function minDiff($startTime, $endTime) {
    $start = strtotime($startTime);
    $end = strtotime($endTime);
    $timeDiff = $end - $start;
    return floor($timeDiff / 60);
}

差幾天也可以這樣寫 :

1
2
3
4
5
6
function dateDiff($startTime, $endTime) {
    $start = strtotime($startTime);
    $end = strtotime($endTime);
    $timeDiff = $end - $start;
    return floor($timeDiff / (60 * 60 * 24));
}

HOWTO Insert Non-primary Google Calendar Event?

If you do not specify Google Calendar URI, the event will be added to the primary calendar. So, you need to figure out which URI of calendar is the right URI you want to update.

In “Calendar Settings” -> “Calendars”, Select the calendar which you want to update. You will see the link of XML. The XML link will like below :

http://www.google.com/calendar/feeds/#KEY#%40group.calendar.google.com/public/basic

#KEY# is your secret.

Replacing the “public/basic” part with “private/full“. It will become the Google Calendar URI.

http://www.google.com/calendar/feeds/#KEY#%40group.calendar.google.com/private/full

Add the URI as the second parameter in the insertEvent function. Like below :

1
2
// $createdEntry = $gc->insertEvent($newEntry);
$createdEntry = $gc->insertEvent($newEntry, "http://www.google.com/calendar/feeds/#KEY#%40group.calendar.google.com/private/full");

Using php to add an all days event in Google Calendar

Following example is “Creating single-occurrence events” from Google web site.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function createEvent ($client, $title = 'Tennis with Beth',
    $desc='Meet for a quick lesson', $where = 'On the courts',
    $startDate = '2008-01-20', $startTime = '10:00',
    $endDate = '2008-01-20', $endTime = '11:00', $tzOffset = '-08')
{
  $gdataCal = new Zend_Gdata_Calendar($client);
  $newEvent = $gdataCal->newEventEntry();
 
  $newEvent->title = $gdataCal->newTitle($title);
  $newEvent->where = array($gdataCal->newWhere($where));
  $newEvent->content = $gdataCal->newContent("$desc");
 
  $when = $gdataCal->newWhen();
  $when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
  $when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
  $newEvent->when = array($when);
 
  // Upload the event to the calendar server
  // A copy of the event as it is recorded on the server is returned
  $createdEvent = $gdataCal->insertEvent($newEvent);
  return $createdEvent->id->text;
}
 
createEvent($client, 'New Years Party',
    'Ring in the new year with Kim and I',
    'Our house', 
    '2006-12-31', '22:00', '2007-01-01', '03:00', '-08' );

How about an all day event? From above example, I can’t simply change start time and end time fields to empty string. It will fail.

So, just modified few lines of createEvent function. Like below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function createEvent ($client, $title = 'Tennis with Beth',
    $desc='Meet for a quick lesson', $where = 'On the courts',
    $startDate = '2008-01-20', $startTime = '10:00',
    $endDate = '2008-01-20', $endTime = '11:00', $tzOffset = '-08')
{
  $gdataCal = new Zend_Gdata_Calendar($client);
  $newEvent = $gdataCal->newEventEntry();
 
  $newEvent->title = $gdataCal->newTitle($title);
  $newEvent->where = array($gdataCal->newWhere($where));
  $newEvent->content = $gdataCal->newContent("$desc");
 
  $when = $gdataCal->newWhen();
 
  if ($startTime != "") {
    $when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
  } else {
    $when->startTime = "{$startDate}";
  }
  if ($endTime != "") {
    $when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
  } else {
    list($yy, $mm, $dd) = explode('-', $endDate);
    $newdate = mktime(0, 0, 0, $mm, $dd + 1, $yy);
    $endDate = date('Y-m-d', $newdate);
    $when->endTime = "{$endDate}";
  }
  $newEntry->when = array($when);
 
  // Upload the event to the calendar server
  // A copy of the event as it is recorded on the server is returned
  $createdEvent = $gdataCal->insertEvent($newEvent);
  return $createdEvent->id->text;
}
 
createEvent($client, 'New Years Party',
    'Ring in the new year with Kim and I',
    'Our house', 
    '2006-12-31', '', '2007-01-01', '', '' );

After run it, that event will be updated on 12/31/2006 and 1/1/2007.

Using php to generate pdf file preview – (使用php產生pdf預覽)

I’m going to use the Google Mini pdf file as this demonstration. Please download that file to the same directory of your php script in advance. Check it out here. You can see how GOOD Google did the document preview function is. Of course, I’m not as well as Google’s experts. But, I just knew a small trick.

我將使用Google Mini pdf 檔案進行這個範例解說. 請先將這個檔案下載到你的php程式相同目錄. 按這裡. , 你可以先看看 Google 的 document preview 的功能已經相當完善. 當然, 我不像 Google 的專業人士那麼厲害. 但是, 我知道一點小技巧.

Before you start to generate pdf file preview, you need to make sure your system is installed the GhostScript and the ImageMagick.

在開始產生pdf預覽前, 你先在你的系統安裝 GhostScriptImageMagick程式.

Following php script to generate thumbnails pdf files:
下列php程式碼會產生縮圖:

1
exec('/usr/bin/convert "googlemini_datasheet.pdf" -geometry 200 "googlemini_thumbnails.png"');

Output :

file name : googlemini_thumbnails-0.png


file name : googlemini_thumbnails-1.png

Following php script to generate large pdf files:
下列php程式碼會產生大圖:

1
exec('/usr/bin/convert "googlemini_datasheet.p22df" -density 1200x1200 -geometry 1024 -quality 100 "googlemini_large.png"');

Output :

file name : googlemini_large-0.png


file name : googlemini_large-1.png

From above php scripts, you can see the convert command generated two png files. Because, the Google Mini pdf file has two pages. If there are many pages in pdf file, It will be generated some file name with “-0″, “-1″, “-2″, “-3″ and so on.

從上列php程式碼, 你可以了解 convert 指令幫你產生了兩張 png 圖. 因為那個 Google Mini pdf 檔案有兩頁. 如果pdf檔案有很多頁面, 那會產生”-0″, “-1″, “-2″, “-3″…等.

If you would like to generate the first page, you can use following php script:
如果你只想產生第一頁, 你可以使用下列php程式.

1
exec('/usr/bin/convert "googlemini_datasheet.pdf[0]" -geometry 200 "googlemini_page1.png"');

Just add the [0] after the pdf file name. How about the second page? Just change inside number of [ ] from 0 to 1.

只要在pdf檔案後面加入[0]就可以了. 那如果要只輸出第二頁? 只要改變 [ ] 裡面的數子. 從 0 到 1.

References :

使用 php rrdtool 工具畫機房溫度圖

建立 rrd 檔案. 然後更新溫度資訊到 rrd 檔案內 :
initial rrd file and update temperature into rrd file :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// update.php
$rrd_file = "r733.rrd";
 
function init_rrd() {
    global $rrd_file;
 
    $opts = array("--step", "300", "--start", 0,
                 "DS:Battery:GAUGE:600:1:100",
                 "DS:EMU:GAUGE:600:1:100",
                 "RRA:AVERAGE:0.5:1:600",
                 "RRA:AVERAGE:0.5:6:700",
                 "RRA:AVERAGE:0.5:24:775",
                 "RRA:AVERAGE:0.5:288:797",
                 "RRA:MAX:0.5:1:600",
                 "RRA:MAX:0.5:6:700",
                 "RRA:MAX:0.5:24:775",
                 "RRA:MAX:0.5:288:797");
    $rtn = rrd_create($rrd_file, $opts, count($opts));
 
    if ($rtn == 0) {
        $err = rrd_error();
        exit("ERROR : $err\n");
    }
 
} // end function init_rrd()
 
function update_rrd() {
    global $rrd_file;
    $battery_cmd = "/usr/bin/snmpwalk -v 1 -c tiara_pub 192.168.170.250 1.3.6.1.4.1.318.1.1.1.2.2.2.0";
    $emu_cmd = "/usr/bin/snmpwalk -v 1 -c tiara_pub 192.168.170.250 1.3.6.1.4.1.318.1.1.10.2.3.2.1.4.1";
    $flag = true;
 
    while($flag) {
        $battery_temperature = "";
        $emu_temperature = "";
        while($battery_temperature == "") {
            $output = shell_exec($battery_cmd);
            $battery_temperature = trim(str_replace("SNMPv2-SMI::enterprises.318.1.1.1.2.2.2.0 = Gauge32:", "", $output));
            if ($battery_temperature == "") sleep(5);
        }
 
        while($emu_temperature == "") {
            $output = shell_exec($emu_cmd);
            $emu_temperature = trim(str_replace("SNMPv2-SMI::enterprises.318.1.1.10.2.3.2.1.4.1 = INTEGER:", "", $output));
            if ($emu_temperature == "") sleep(5);
        }
        $battery_temperature = (int)$battery_temperature;
        $emu_temperature = (int)$emu_temperature;
        $rtn = rrd_update($rrd_file, "N:$battery_temperature:$emu_temperature");
        if ($rtn == 0) {
            $err = rrd_error();
            exit("ERROR : $err\n");
        }
 
        if (isset($_GET["t"])) {
            sleep(300);
        } else {
            $flag = false;
        }
    } // end while(true)
 
} // end function update_rrd()
 
if (file_exists($rrd_file)) {
    update_rrd();
} else {
    init_rrd();
    update_rrd();
}

畫 rrd 圖 :
draw rrd graphs :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// index.php
$rrd_file = "r733.rrd";
 
include_once "update_r733.php";
 
function draw_rrd() {
    global $rrd_file;
 
    $opts = array( "--start", "-1h", "--vertical-label=deg C", "--title=R733 Temperature last hour",
                   "DEF:battery=".$rrd_file.":Battery:AVERAGE",
                   "DEF:emu=".$rrd_file.":EMU:AVERAGE",
                   "COMMENT:                                           Max    Average    Last\\n",
                   "AREA:battery#99CC00:Battery \:",
                   "GPRINT:battery:MAX:%2.0lfdeg C",
                   "GPRINT:battery:AVERAGE:%2.0lfdeg C",
                   "GPRINT:battery:LAST:%2.0lfdeg C\\r",
                   "LINE2:emu#6699CC:EMU \:",
                   "GPRINT:emu:MAX:%2.0lfdeg C",
                   "GPRINT:emu:AVERAGE:%2.0lfdeg C",
                   "GPRINT:emu:LAST:%2.0lfdeg C\\r"
               );
 
    $ret = rrd_graph("r733_1h.gif", $opts, count($opts));
 
    if(!is_array($ret)) {
        $err = rrd_error();
        exit("draw_rrd() ERROR: $err\n");
    }
 
    $opts = array( "--start", "-1d", "--vertical-label=deg C", "--title=R733 Temperature last day",
                   "DEF:battery=".$rrd_file.":Battery:AVERAGE",
                   "DEF:emu=".$rrd_file.":EMU:AVERAGE",
                   "COMMENT:                                           Max    Average    Last\\n",
                   "AREA:battery#99CC00:Battery \:",
                   "GPRINT:battery:MAX:%2.0lfdeg C",
                   "GPRINT:battery:AVERAGE:%2.0lfdeg C",
                   "GPRINT:battery:LAST:%2.0lfdeg C\\r",
                   "LINE2:emu#6699CC:EMU \:",
                   "GPRINT:emu:MAX:%2.0lfdeg C",
                   "GPRINT:emu:AVERAGE:%2.0lfdeg C",
                   "GPRINT:emu:LAST:%2.0lfdeg C\\r"
               );
 
    $ret = rrd_graph("r733_1d.gif", $opts, count($opts));
 
    if(!is_array($ret)) {
        $err = rrd_error();
        exit("draw_rrd() ERROR: $err\n");
    }
 
    $opts = array( "--start", "-1w", "--vertical-label=deg C", "--title=R733 Temperature last week",
                   "DEF:battery=".$rrd_file.":Battery:AVERAGE",
                   "DEF:emu=".$rrd_file.":EMU:AVERAGE",
                   "COMMENT:                                           Max    Average    Last\\n",
                   "AREA:battery#99CC00:Battery \:",
                   "GPRINT:battery:MAX:%2.0lfdeg C",
                   "GPRINT:battery:AVERAGE:%2.0lfdeg C",
                   "GPRINT:battery:LAST:%2.0lfdeg C\\r",
                   "LINE2:emu#6699CC:EMU \:",
                   "GPRINT:emu:MAX:%2.0lfdeg C",
                   "GPRINT:emu:AVERAGE:%2.0lfdeg C",
                   "GPRINT:emu:LAST:%2.0lfdeg C\\r"
               );
 
    $ret = rrd_graph("r733_1w.gif", $opts, count($opts));
 
    if(!is_array($ret)) {
        $err = rrd_error();
        exit("draw_rrd() ERROR: $err\n");
    }
 
    $opts = array( "--start", "-1m", "--vertical-label=deg C", "--title=R733 Temperature last month",
                   "DEF:battery=".$rrd_file.":Battery:AVERAGE",
                   "DEF:emu=".$rrd_file.":EMU:AVERAGE",
                   "COMMENT:                                           Max    Average    Last\\n",
                   "AREA:battery#99CC00:Battery \:",
                   "GPRINT:battery:MAX:%2.0lfdeg C",
                   "GPRINT:battery:AVERAGE:%2.0lfdeg C",
                   "GPRINT:battery:LAST:%2.0lfdeg C\\r",
                   "LINE2:emu#6699CC:EMU \:",
                   "GPRINT:emu:MAX:%2.0lfdeg C",
                   "GPRINT:emu:AVERAGE:%2.0lfdeg C",
                   "GPRINT:emu:LAST:%2.0lfdeg C\\r"
               );
 
    $ret = rrd_graph("r733_1m.gif", $opts, count($opts));
 
    if(!is_array($ret)) {
        $err = rrd_error();
        exit("draw_rrd() ERROR: $err\n");
    }
 
    $opts = array( "--start", "-1y", "--vertical-label=deg C", "--title=R733 Temperature last year",
                   "DEF:battery=".$rrd_file.":Battery:AVERAGE",
                   "DEF:emu=".$rrd_file.":EMU:AVERAGE",
                   "COMMENT:                                           Max    Average    Last\\n",
                   "AREA:battery#99CC00:Battery \:",
                   "GPRINT:battery:MAX:%2.0lfdeg C",
                   "GPRINT:battery:AVERAGE:%2.0lfdeg C",
                   "GPRINT:battery:LAST:%2.0lfdeg C\\r",
                   "LINE2:emu#6699CC:EMU \:",
                   "GPRINT:emu:MAX:%2.0lfdeg C",
                   "GPRINT:emu:AVERAGE:%2.0lfdeg C",
                   "GPRINT:emu:LAST:%2.0lfdeg C\\r"
               );
 
    $ret = rrd_graph("r733_1y.gif", $opts, count($opts));
 
    if(!is_array($ret)) {
        $err = rrd_error();
        exit("draw_rrd() ERROR: $err\n");
    }
} // end function draw_rrd()
 
draw_rrd();
 
?>
<img src="r733_1h.gif"><br>
<img src="r733_1d.gif"><br>
<img src="r733_1w.gif"><br>
<img src="r733_1m.gif"><br>
<img src="r733_1y.gif">

在 linux 內執行 curl http://xxx.liho.tw/temperature/update.php & 這樣就可以每 300 秒回報一次溫度.

展示畫一天的溫度的rrd圖 :