SHOW:
|
|
- or go back to the newest paste.
1 | <?php | |
2 | ||
3 | /* globals */ | |
4 | $flaggedForDelete = 0; | |
5 | $imap = null; | |
6 | $user = ''; | |
7 | $pass = ''; | |
8 | ||
9 | /* entry point */ | |
10 | function main() { | |
11 | global $user, $pass; | |
12 | ||
13 | /* display errors only */ | |
14 | error_reporting(E_ALL ^ (E_NOTICE | E_WARNING)); | |
15 | ||
16 | /* read configuration file (don't want to store login info in script)*/ | |
17 | $ini = script_init(); | |
18 | $user = $ini[0]; | |
19 | $pass = $ini[1]; | |
20 | ||
21 | /* set signal handlers and time execution of the core routines */ | |
22 | $timeBegin = script_microtime(); | |
23 | signal_handler_set('signal_handler'); | |
24 | script_core($ini[2]); | |
25 | script_cleanup(); | |
26 | $timeEnd = script_microtime(); | |
27 | echo 'Executed in: '.round($timeEnd - $timeStart,3)." seconds\n"; | |
28 | ||
29 | exit(0); | |
30 | } main(); | |
31 | ||
32 | /* set signal handler if we can */ | |
33 | function signal_handler_set($handler = SIG_DFL) { | |
34 | if(function_exists('pcntl_signal')) { | |
35 | if(function_exists('pcntl_signal_dispatch')) | |
36 | pcntl_signal_dispatch(); | |
37 | else | |
38 | declare(ticks = 1); | |
39 | pcntl_signal(SIGTERM, $handler); | |
40 | pcntl_signal(SIGINT, $handler); | |
41 | pcntl_signal(SIGKILL, $handler); | |
42 | } | |
43 | } | |
44 | ||
45 | /* handle signals that can terminate the script; we want to die gracefully */ | |
46 | function signal_handler($signal) { | |
47 | if($signal == SIGTERM || $signal == SIGINT || $signal = SIGKILL) { | |
48 | echo "\nScript interrupted! Cleaning up...\n"; | |
49 | script_cleanup(); | |
50 | exit(0); | |
51 | } | |
52 | } | |
53 | ||
54 | /* return a float for microtime() in order to time the script */ | |
55 | function script_microtime() { | |
56 | list($msec,$sec) = explode(' ', microtime()); | |
57 | return ((float)$msec + (float)$sec); | |
58 | } | |
59 | ||
60 | /* read our INI file which defines 'user', 'pass' and 'year' keys | |
61 | * ini file name is always the same as the script except w/ 'ini' extension instead of 'php' | |
62 | */ | |
63 | function script_init() { | |
64 | $inifile = preg_replace('/php$/', 'ini', basename(__FILE__)); | |
65 | if(file_exists($inifile)) { | |
66 | $ini = parse_ini_file($inifile); | |
67 | if(strlen(trim($ini['user'])) == 0) { | |
68 | echo "blank user in ini? i don't think so.\n"; | |
69 | exit(1); | |
70 | } | |
71 | if(strlen(trim($ini['pass'])) == 0) { | |
72 | echo "blank pass in ini? i don't think so.\n"; | |
73 | exit(1); | |
74 | } | |
75 | if(strlen(trim($ini['year'])) == 0) { | |
76 | echo "blank year? well let's use this year...\n"; | |
77 | $ini['year'] = date('Y'); | |
78 | } | |
79 | } else { | |
80 | echo "$inifile not found. please enter data manually.\n\n"; | |
81 | fwrite(STDOUT, "gmail user: "); $ini['user'] = trim(fgets(STDIN)); | |
82 | fwrite(STDOUT, "password: "); $ini['pass'] = trim(fgets(STDIN)); | |
83 | fwrite(STDOUT, "min year: "); $ini['year'] = trim(fgets(STDIN)); | |
84 | } | |
85 | return array($ini['user'], $ini['pass'], $ini['year']); | |
86 | } | |
87 | ||
88 | /* connect to gmail via IMAP and mark old messages to be moved to the trash. | |
89 | * gmail won't let you delete messages in the '[Gmail]/All Mail' folder. | |
90 | */ | |
91 | function script_core($minYear) { | |
92 | global $imap, $flaggedForDelete, $user, $pass; | |
93 | ||
94 | echo "Connecting as {$user}...\n"; | |
95 | $imap = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}[Gmail]/All Mail", $user, $pass) or die("Cannot connect: " . imap_last_error() . "\n"); | |
96 | ||
97 | echo "Checking current mailbox...\n"; | |
98 | $mbox = imap_check($imap); | |
99 | ||
100 | $bar = new Console_ProgressBar('- Processing %fraction% [%bar%] %percent% ETA: %estimate%', '=>', '-', 74, $mbox->Nmsgs); | |
101 | for($n = 1; $n < $mbox->Nmsgs; $n++) { | |
102 | //echo "Processing {$n} of {$mbox->Nmsgs} ({$flaggedForDelete} flagged so far)...\r"; | |
103 | $bar->update($n); | |
104 | $hdr = imap_fetchheader($imap, $n); | |
105 | preg_match('/Date: .*? (2\d{3}).*?$/m', $hdr, $matches); | |
106 | $year = $matches[1]; | |
107 | if($year < $minYear) { | |
108 | if(!imap_mail_move($imap, $n, '[Gmail]/Trash')) { | |
109 | preg_match('/Message-ID: \<(.*?)\>/', $hdr, $matches); | |
110 | $msgid = $matches[1]; | |
111 | echo("\nimap_mail_move ({$msgid}/{$n}): " . imap_last_error() . "\n"); | |
112 | } | |
113 | $flaggedForDelete++; | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | /* access the '[Gmail]/Trash' folder and delete all messages */ | |
119 | function script_empty_trash() { | |
120 | global $user, $pass; | |
121 | ||
122 | signal_handler_set(SIG_DFL); | |
123 | ||
124 | $imap = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}[Gmail]/Trash", $user, $pass) or die("can't connect: " . imap_last_error() . "\n"); | |
125 | $mbox = imap_check($imap); | |
126 | $bar = new Console_ProgressBar('- Deleting %fraction% [%bar%] %percent% ETA: %estimate%', '=>', '-', 74, $mbox->Nmsgs); | |
127 | for($n = 1; $n < $mbox->Nmsgs; $n++) { | |
128 | //echo "Deleting message {$n} of {$mbox->Nmsgs} in trash...\r"; | |
129 | $bar->update($n); | |
130 | imap_delete($imap, $n); | |
131 | } | |
132 | imap_close($imap, CL_EXPUNGE); | |
133 | } | |
134 | ||
135 | /* script_core() can be time consuming; user may interrupt | |
136 | * if so, expunge and close the connection (moving flagged messages to trash) | |
137 | * next, try to empty the trash -- may be time consuming, however, | |
138 | * script_empty_trash() will die w/o any hold-ups if the user tries killing again | |
139 | */ | |
140 | function script_cleanup() { | |
141 | global $imap, $flaggedForDelete; | |
142 | ||
143 | echo "Expunging mailbox ({$flaggedForDelete} messages flagged)...\n"; | |
144 | imap_close($imap, CL_EXPUNGE); | |
145 | ||
146 | echo "Emptying trash...\n"; | |
147 | script_empty_trash(); | |
148 | ||
149 | echo "\n"; | |
150 | } | |
151 | ||
152 | /* list all mail boxes on the gmail imap server | |
153 | * used for development, but not needed in the final version | |
154 | */ | |
155 | function script_list_boxes() { | |
156 | global $user, $pass; | |
157 | ||
158 | $imap = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}", $user, $pass) or die("Cannot connect: " . imap_last_error() . "\n"); | |
159 | $boxes = imap_list($imap, '{imap.gmail.com}', '*'); | |
160 | print_r($boxes); | |
161 | imap_close($imap); | |
162 | } | |
163 | ||
164 | ||
165 | /* Console/ProgressBar 0.5.2 Copyright (c) 2007 Stefan Walk <et@php.net>; released under MIT license; downloded from PEAR */ | |
166 | class Console_ProgressBar {var $_skeleton;var $_bar;var $_blen;var $_tlen;var $_target_num;var $_options = array();var $_rlen = 0;var $_start_time = null;var $_rate_datapoints = array();var $_last_update_time = 0.0;function Console_ProgressBar($formatstring, $bar, $prefill, $width,$target_num, $options = array()){$this->reset($formatstring, $bar, $prefill, $width, $target_num,$options);}function reset($formatstring, $bar, $prefill, $width, $target_num,$options = array()){if ($target_num == 0) {trigger_error("PEAR::Console_ProgressBar: Using a target number equal to 0 is invalid, setting to 1 instead");$this->_target_num = 1;} else {$this->_target_num = $target_num;}$default_options = array('percent_precision' => 2,'fraction_precision' => 0,'percent_pad' => ' ','fraction_pad' => ' ','width_absolute' => true,'ansi_terminal' => false,'ansi_clear' => false,'num_datapoints' => 5,'min_draw_interval' => 0.0,);$intopts = array();foreach ($default_options as $key => $value) {if (!isset($options[$key])) {$intopts[$key] = $value;} else {settype($options[$key], gettype($value));$intopts[$key] = $options[$key];}}$this->_options = $options = $intopts;$cur = '%2$\''.$options['fraction_pad']{0}.strlen((int)$target_num).'.'.$options['fraction_precision'].'f';$max = $cur; $max{1} = 3;if (version_compare(PHP_VERSION, '4.3.7', 'ge')) {$padding = 4 + $options['percent_precision'];} else {$padding = 3;}$perc = '%4$\''.$options['percent_pad']{0}.$padding.'.'.$options['percent_precision'].'f';$transitions = array('%%' => '%%','%fraction%' => $cur.'/'.$max,'%current%' => $cur,'%max%' => $max,'%percent%' => $perc.'%%','%bar%' => '%1$s','%elapsed%' => '%5$s','%estimate%' => '%6$s',);$this->_skeleton = strtr($formatstring, $transitions);$slen = strlen(sprintf($this->_skeleton, '', 0, 0, 0, '00:00:00','00:00:00'));if ($options['width_absolute']) {$blen = $width - $slen;$tlen = $width;} else {$tlen = $width + $slen;$blen = $width;}$lbar = str_pad($bar, $blen, $bar{0}, STR_PAD_LEFT);$rbar = str_pad($prefill, $blen, substr($prefill, -1, 1));$this->_bar = substr($lbar,-$blen).substr($rbar,0,$blen);$this->_blen = $blen;$this->_tlen = $tlen;$this->_first = true;return true;}function update($current){$time = $this->_fetchTime();$this->_addDatapoint($current, $time);if ($this->_first) {if ($this->_options['ansi_terminal']) {echo "\x1b[s"; }$this->_first = false;$this->_start_time = $this->_fetchTime();$this->display($current);return;}if ($time - $this->_last_update_time <$this->_options['min_draw_interval'] and $current != $this->_target_num) {return;}$this->erase();$this->display($current);$this->_last_update_time = $time;}function display($current){$percent = $current / $this->_target_num;$filled = round($percent * $this->_blen);$visbar = substr($this->_bar, $this->_blen - $filled, $this->_blen);$elapsed = $this->_formatSeconds($this->_fetchTime() - $this->_start_time);$estimate = $this->_formatSeconds($this->_generateEstimate());$this->_rlen = printf($this->_skeleton,$visbar, $current, $this->_target_num, $percent * 100, $elapsed,$estimate);if (is_null($this->_rlen)) {$this->_rlen = $this->_tlen;} elseif ($this->_rlen < $this->_tlen) {echo str_repeat(' ', $this->_tlen - $this->_rlen);$this->_rlen = $this->_tlen;}return true;}function erase($clear = false){if ($this->_options['ansi_terminal'] and !$clear) {if ($this->_options['ansi_clear']) {echo "\x1b[2K\x1b[u"; } else {echo "\x1b[u"; }} elseif (!$clear) {echo str_repeat(chr(0x08), $this->_rlen);} else {echo str_repeat(chr(0x08), $this->_rlen),str_repeat(chr(0x20), $this->_rlen),str_repeat(chr(0x08), $this->_rlen);}}function _formatSeconds($seconds){$hou = floor($seconds/3600);$min = floor(($seconds - $hou * 3600) / 60);$sec = $seconds - $hou * 3600 - $min * 60;if ($hou == 0) {if (version_compare(PHP_VERSION, '4.3.7', 'ge')) {$format = '%2$02d:%3$05.2f';} else {$format = '%2$02d:%3$02.2f';}} elseif ($hou < 100) {$format = '%02d:%02d:%02d';} else {$format = '%05d:%02d';}return sprintf($format, $hou, $min, $sec);}function _fetchTime() {if (!function_exists('microtime')) {return time();}if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {return microtime(true);}return array_sum(explode(' ', microtime()));}function _addDatapoint($val, $time) {if (count($this->_rate_datapoints)== $this->_options['num_datapoints']) {array_shift($this->_rate_datapoints);}$this->_rate_datapoints[] = array('time' => $time,'value' => $val,);}function _generateEstimate() {if (count($this->_rate_datapoints) < 2) {return 0.0;}$first = $this->_rate_datapoints[0];$last = end($this->_rate_datapoints);return ($this->_target_num - $last['value'])/($last['value'] - $first['value']) * ($last['time'] - $first['time']);}} | |
167 | ?> |