Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- if ($_SERVER['argc'] < 3)
- {
- error_log(sprintf("syntax: %s <username> <password>\n", $_SERVER['argv'][0]));
- exit(1);
- }
- define('PAGE_TIMEOUT', 30);
- define('DOWNLOAD_TIMEOUT', 1800);
- $mru = new MailRuBoxGrabber();
- if (!$mru->login($_SERVER['argv'][1], $_SERVER['argv'][2], ''))
- {
- error_log('login failed');
- exit(1);
- }
- $mru->grab_all();
- class MailRuBoxGrabber
- {
- const BASE_URL = 'https://e.mail.ru/';
- const API_MESSAGES_LIMIT = 50;
- private $curl, $username;
- function __construct()
- {
- if (($this->curl = curl_init()) === FALSE)
- die('curl_init() failed');
- curl_setopt($this->curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
- curl_setopt($this->curl, CURLOPT_PROXY, '127.0.0.1:9050');
- curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, 10);
- curl_setopt($this->curl, CURLOPT_TIMEOUT, PAGE_TIMEOUT);
- curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, TRUE);
- curl_setopt($this->curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0');
- curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, TRUE);
- curl_setopt($this->curl, CURLOPT_MAXREDIRS, 3);
- curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
- $cookie_file = pathinfo($_SERVER['argv'][0])['filename'] . '.cookies';
- curl_setopt($this->curl, CURLOPT_COOKIEFILE, $cookie_file);
- curl_setopt($this->curl, CURLOPT_COOKIEJAR, $cookie_file);
- // curl_setopt($this->curl, CURLOPT_COOKIESESSION, TRUE);
- // curl_setopt($this->curl, CURLOPT_VERBOSE, TRUE);
- }
- function __destruct()
- {
- curl_close($this->curl);
- }
- private function http_request($url)
- {
- curl_setopt($this->curl, CURLOPT_URL, $url);
- $result = curl_exec($this->curl);
- if ($result === FALSE)
- {
- error_log('request error: ' . curl_error($this->curl));
- return NULL;
- }
- else
- return $result;
- }
- public function login($username, $password, $redirect)
- {
- curl_setopt($this->curl, CURLOPT_POST, TRUE);
- curl_setopt($this->curl, CURLOPT_POSTFIELDS, sprintf('page=%s&Domain=mail.ru&Login=%s&Password=%s&new_auth_form=1', urlencode($redirect), urlencode($username), urlencode($password)));
- if (($response = $this->http_request('https://auth.mail.ru/cgi-bin/auth?lang=ru_RU')) === NULL)
- return FALSE;
- if (curl_getinfo($this->curl, CURLINFO_HTTP_CODE) != '200')
- return FALSE;
- if (!preg_match('|<meta http-equiv="refresh" content="0;url=(\S+?)">|', $response, $sp))
- {
- error_log('unable to match <meta http-equiv="refresh" ...>');
- return FALSE;
- }
- if ($redirect != '' && html_entity_decode($sp[1]) != $redirect && strpos($sp[1], 'https://e.mail.ru/settings/security?changepass') === FALSE)
- {
- error_log('unexpected redirect URL: ' . $sp[1]);
- return FALSE;
- }
- $this->username = $username;
- return TRUE;
- }
- public function grab_all()
- {
- curl_setopt($this->curl, CURLOPT_HTTPGET, TRUE);
- curl_setopt($this->curl, CURLOPT_TIMEOUT, PAGE_TIMEOUT);
- curl_setopt($this->curl, CURLOPT_FILE, STDOUT);
- curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
- if (($response = $this->http_request(sprintf(self::BASE_URL . 'messages/inbox/?back=1'))) === NULL)
- return FALSE;
- if (!preg_match('|patron\.updateToken\("(\S+?)"\);|', $response, $sp))
- {
- error_log('unable to get API token');
- return FALSE;
- }
- $token = $sp[1];
- $folders = array(0 => array());
- while (list($folder_id, $folder_data) = each($folders))
- {
- $folder_message = 0;
- for ($offset = 0; ; $offset += self::API_MESSAGES_LIMIT)
- {
- curl_setopt($this->curl, CURLOPT_HTTPGET, TRUE);
- curl_setopt($this->curl, CURLOPT_TIMEOUT, PAGE_TIMEOUT);
- curl_setopt($this->curl, CURLOPT_FILE, STDOUT);
- curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
- if (($response = $this->http_request(self::BASE_URL . sprintf('api/v1/messages/status?ajax_call=1&email=%s&nolog=0&cts=1&force=1&folder=%s&offset=%u&limit=%u&api=1&token=%s', urlencode($this->username), $folder_id, $offset, self::API_MESSAGES_LIMIT, urlencode($token)))) === NULL)
- return FALSE;
- if (($api_response = json_decode($response, TRUE)) === NULL)
- {
- error_log("API request - unable to decode JSON data:\n" . $response);
- return FALSE;
- }
- if (count($folders) <= 1) // if not filled yet
- {
- echo "parsing folders list\n";
- foreach ($api_response['body']['folders'] as $item)
- {
- $dir = sprintf("#%s - %s", $item['id'], self::sanitize_filename($item['name']));
- if (!is_dir($dir) && !mkdir($dir))
- {
- error_log("can't create a directory: " . $dir);
- return FALSE;
- }
- $folders[$item['id']] = array(
- 'name' => $item['name'],
- 'messages' => $item['messages_total'],
- 'dir' => $dir
- );
- }
- print_r($folders);
- }
- if (empty($api_response['body']['messages']))
- break 1;
- foreach ($api_response['body']['messages'] as $message)
- {
- ++$folder_message;
- printf("[%u/%u] %s - %s - %s\n", $folder_message, $folders[$message['folder']]['messages'],
- $message['id'], date('Y-m-d H:i:s', $message['date']), $message['subject']);
- if (!$this->retrieve_message($message['id'], $folders[$message['folder']]['dir']))
- return FALSE;
- }
- }
- }
- }
- public function retrieve_message($id, $dir)
- {
- if (!is_dir($dir) && !mkdir($dir))
- {
- error_log("can't create a directory");
- return FALSE;
- }
- $filename = sprintf("%s/%s.eml", $dir, $id);
- if (($fOutput = fopen($filename, 'w')) === FALSE)
- {
- echo "unable to create a file: $filename\n";
- return FALSE;
- }
- curl_setopt($this->curl, CURLOPT_URL, self::BASE_URL . 'cgi-bin/getmsg?id=' . $id);
- curl_setopt($this->curl, CURLOPT_TIMEOUT, DOWNLOAD_TIMEOUT);
- curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 0);
- curl_setopt($this->curl, CURLOPT_FILE, $fOutput);
- $result = curl_exec($this->curl);
- fclose($fOutput);
- $http_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
- if ($result === FALSE || $http_code != 200)
- {
- printf("unable to fetch message #%s (HTTP status code = %u)\n", $id, $http_code);
- return FALSE;
- }
- return TRUE;
- }
- protected static function sanitize_filename($filename)
- {
- return preg_replace("|[/\\\?\*\|:\"<>]|", '_', $filename);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement