Skip to content

Commit

Permalink
init implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
woxcab committed Dec 6, 2016
1 parent 2a5c5e8 commit e973a0e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 33 deletions.
96 changes: 67 additions & 29 deletions Vk2rss.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class Vk2rss
protected $proxy = null;

public function __construct($id, $count = 20, $include = null, $exclude = null, $disable_html=false,
$owner_only = false, $access_token = null,
$owner_only = false, $access_token = null, $phone = null,
$proxy = null, $proxy_type = null, $proxy_login = null, $proxy_password = null)
{
if (empty($id)) {
Expand Down Expand Up @@ -127,6 +127,7 @@ public function __construct($id, $count = 20, $include = null, $exclude = null,
$this->disable_html = $disable_html;
$this->owner_only = $owner_only;
$this->access_token = $access_token;
$this->phone = isset($phone) ? preg_replace('/\D+/u', '', $phone) : null;
if (isset($proxy)) {
try {
$this->proxy = new ProxyDescriptor($proxy, $proxy_type, $proxy_login, $proxy_password);
Expand All @@ -151,32 +152,32 @@ public function generateRSS()
$connector = new ConnectionWrapper($this->proxy);

if (!empty($this->domain) || (!empty($this->owner_id) && $this->owner_id < 0)) {
$group_response = $this->getContent($connector, "groups.getById");
if (property_exists($group_response, 'error') && $group_response->error->error_code != 100) {
throw new APIError($group_response, $connector->getLastUrl());
try {
$group_response = $this->getContent($connector, "groups.getById");
} catch (APIError $exc) {
if ($exc->getApiErrorCode() != 100) {
throw $exc;
}
}
}
if (isset($group_response) && !property_exists($group_response, 'error') && !empty($group_response->response)) {
if (isset($group_response) && !empty($group_response->response)) {
$group = $group_response->response[0];
$title = $group->name;
$feed_description = self::GROUP_FEED_DESCRIPTION_PREFIX . $group->name;
} else {
sleep(1);
try {
$user_response = $this->getContent($connector, "users.get");
if (property_exists($user_response, 'error')) {
throw new APIError($user_response, $connector->getLastUrl());
}
} catch (APIError $exc) {
throw $exc->getApiErrorCode() == 113 ?
new Exception("Invalid user or group identifier", 400) : $exc;
}
if (!empty($user_response->response)) {
$profile = $user_response->response[0];
$title = $profile->first_name . ' ' . $profile->last_name;
$feed_description = self::USER_FEED_DESCRIPTION_PREFIX . $profile->first_name . ' ' . $profile->last_name;
} else {
if (empty($user_response->response)) {
throw new Exception("Invalid user or group identifier", 400);
}
$profile = $user_response->response[0];
$title = $profile->first_name . ' ' . $profile->last_name;
$feed_description = self::USER_FEED_DESCRIPTION_PREFIX . $profile->first_name . ' ' . $profile->last_name;
}

$feed = new FeedWriter(RSS2);
Expand All @@ -194,9 +195,6 @@ public function generateRSS()
for ($offset = 0; $offset < $this->count; $offset += 100) {
sleep(1);
$wall_response = $this->getContent($connector, "wall.get", $offset);
if (property_exists($wall_response, 'error')) {
throw new APIError($wall_response, $connector->getLastUrl());
}

if (empty($wall_response->response->items)) {
break;
Expand Down Expand Up @@ -421,20 +419,60 @@ protected function getContent($connector, $api_method, $offset = null)
}
$connector->openConnection();
$content = null;
try {
$content = $connector->getContent($url, null, true);
$connector->closeConnection();
} catch (Exception $exc) {
$connector->closeConnection();
throw new Exception("Failed to get content of URL ${url}: " . $exc->getMessage(), $exc->getCode());
}
if (!$this->disable_html) {
$content = strtr($content, array('<' => '&lt;',
'>' => '&gt;',
'\"' => '&quot;',
'\'' => '&apos;'));
for ($attempt = 0; $attempt < 2; $attempt++) {
try {
error_log("Attempt {$attempt}. URL {$url}");
$content = $connector->getContent($url, null, true);
} catch (Exception $exc) {
$connector->closeConnection();
throw new Exception("Failed to get content of URL ${url}: " . $exc->getMessage(), $exc->getCode());
}
if (!$this->disable_html) {
$content = strtr($content, array('<' => '&lt;',
'>' => '&gt;',
'\"' => '&quot;',
'\'' => '&apos;'));
}
$response = json_decode($content);
if (is_null($response)) {
throw new Exception("Failed to decode content of URL ${url}", 500);
}
if (!property_exists($response, 'error')) {
break;
}
$error = new APIError($response, $url);
if ($error->getApiErrorCode() != 17) {
throw $error;
}
$valid_resp = $connector->getContent($response->error->redirect_uri, null, true);
file_put_contents('/var/www/dev/vkrss/responses.log',
"Got API Error 17. Opened redirect_uri {$response->error->redirect_uri}. "
. "FIRST RESPONSE: " . PHP_EOL. PHP_EOL . $valid_resp. PHP_EOL. PHP_EOL. PHP_EOL,
FILE_APPEND);
if (mb_strlen($valid_resp) > 300) {
if (!isset($this->phone) || $attempt > 0) {
throw $error;
}
// parse_str(parse_url($response->error->redirect_uri, PHP_URL_QUERY), $redirect_params);
preg_match('/form method="post" action="([^"]+)"/u', $valid_resp, $match);
$valid_url = 'https://vk.com' . $match[1];
preg_match_all('/"field_prefix">\D*(\d+)/u', $valid_resp, $match);
if (mb_substr($this->phone, 0, mb_strlen($match[1][0])) !== $match[1][0]
|| mb_substr($this->phone, -mb_strlen($match[1][1])) !== $match[1][1]) {
throw new Exception("Invalid phone number {$this->phone}. "
. "The phone must starts with {$match[1][0]} and ends with {$match[1][1]}",
400);
}
$post_params = array('code' => mb_substr($this->phone, mb_strlen($match[1][0]), -mb_strlen($match[1][1])));
$valid_resp = $connector->getContent($valid_url, null, true, true, $post_params);
file_put_contents('/var/www/dev/vkrss/responses.log',
"SENT POST request with phone. SECOND RESPONSE: " . PHP_EOL. PHP_EOL. $valid_resp. PHP_EOL. PHP_EOL. PHP_EOL,
FILE_APPEND);
}
sleep(1);
}
return json_decode($content);
$connector->closeConnection();
return $response;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
header("Content-type: text/xml; charset=utf-8");

$supported_parameters = array('id', 'domain', 'owner_id', 'count', 'include', 'exclude',
'disable_html', 'owner_only', 'access_token',
'disable_html', 'owner_only', 'access_token', 'phone',
'proxy', 'proxy_type', 'proxy_login', 'proxy_password');

try {
Expand All @@ -23,6 +23,7 @@
isset($_GET['disable_html']),
isset($_GET['owner_only']),
isset($_GET['access_token']) ? $_GET['access_token'] : null,
isset($_GET['phone']) ? $_GET['phone'] : null,
isset($_GET['proxy']) ? $_GET['proxy'] : null,
isset($_GET['proxy_type']) ? mb_strtolower($_GET['proxy_type']) : null,
isset($_GET['proxy_login']) ? $_GET['proxy_login'] : null,
Expand Down
27 changes: 24 additions & 3 deletions utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ public function __construct($proxy = null)
case self::BUILTIN_DOWNLOADER:
$opts = array();
$opts['http']['timeout'] = self::CONNECT_TIMEOUT;
$opts['http']['user_agent'] = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0';
if (isset($proxy)) {
$this->proxyType = $proxy->getType();
$address = $proxy->getAddress();
Expand All @@ -237,7 +238,9 @@ public function __construct($proxy = null)
case self::CURL_DOWNLOADER:
$this->curlOpts = array(CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_CONNECTTIMEOUT => self::CONNECT_TIMEOUT);
CURLOPT_CONNECTTIMEOUT => self::CONNECT_TIMEOUT,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0');
if (isset($proxy)) {
$this->curlOpts[CURLOPT_PROXY] = $proxy->getAddress();
$this->proxyType = $proxy->getType();
Expand Down Expand Up @@ -300,10 +303,12 @@ public function closeConnection()
* @param string|null $url URL
* @param string|null $https_url URL with HTTPS protocol. If it's null then it's equal to $url where HTTP is replaced with HTTPS
* @param bool $http_to_https Whether to use HTTP URL with replacing its HTTP protocol on HTTPS protocol
* @param bool $use_http_post Whether to use HTTP POST method
* @param array $post_params Request parameters for POST method
* @return mixed Response body or FALSE on failure
* @throws Exception If HTTPS url is passed and PHP or its extension does not support OpenSSL
*/
public function getContent($url, $https_url = null, $http_to_https = false)
public function getContent($url, $https_url = null, $http_to_https = false, $use_http_post=false, $post_params=array())
{
if ($this->httpsAllowed && (!empty($https_url) || $http_to_https)) {
$request_url = empty($https_url) ? preg_replace('/^http:/ui', 'https:', $url) : $https_url;
Expand All @@ -316,6 +321,12 @@ public function getContent($url, $https_url = null, $http_to_https = false)
$this->lastUrl = $request_url;
switch ($this->downloader) {
case self::BUILTIN_DOWNLOADER:
if ($use_http_post) {
$this->context['http']['method'] = 'POST';
$this->context['http']['content'] = http_build_query($post_params);
} else {
$this->context['http']['method'] = 'GET';
}
$body = @file_get_contents($request_url, false, $this->context);
$response_code = isset($http_response_header) ? (int)substr($http_response_header[0], 9, 3) : null;
if (empty($body)) {
Expand All @@ -329,7 +340,16 @@ public function getContent($url, $https_url = null, $http_to_https = false)
break;
case self::CURL_DOWNLOADER:
curl_setopt($this->curlHandler, CURLOPT_URL, $request_url);
curl_setopt($this->curlHandler, CURLOPT_POST, $use_http_post);
if ($use_http_post) {
curl_setopt($this->curlHandler, CURLOPT_POSTFIELDS, http_build_query($post_params));
}
$response = curl_exec($this->curlHandler);
if ($use_http_post) {
file_put_contents('/var/www/dev/vkrss/responses.log',
'INTERMEDIATE RESPONSE: ' . PHP_EOL. PHP_EOL. $response. PHP_EOL. PHP_EOL. PHP_EOL,
FILE_APPEND);
}
if (empty($response)) {
throw new Exception("Cannot retrieve data from URL '${request_url}': " . curl_error($this->curlHandler));
}
Expand All @@ -343,7 +363,8 @@ public function getContent($url, $https_url = null, $http_to_https = false)
}
list($header, ) = explode("\r\n", $header, 2);
$response_code = (int)substr($header, 9, 3);
if ($response_code != 200) {
error_log($response_code);
if ($response_code != 200 && $response_code != 302) {
throw new Exception("Cannot retrieve data from URL '${request_url}': " . substr($header, 13), $response_code);
}
break;
Expand Down

0 comments on commit e973a0e

Please sign in to comment.