Merge pull request 'Tumblr: We can now import the remote timeline' (#1372) from heluecht/friendica-addons:tumblr-import into develop

Reviewed-on: https://git.friendi.ca/friendica/friendica-addons/pulls/1372
pull/1374/head
Hypolite Petovan 2023-04-24 01:38:19 +02:00
commit becf10cee6
4 changed files with 868 additions and 236 deletions

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n" "POT-Creation-Date: 2023-04-22 10:00+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,54 +17,58 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: tumblr.php:39 #: tumblr.php:60
msgid "Permission denied." msgid "Permission denied."
msgstr "" msgstr ""
#: tumblr.php:69 #: tumblr.php:111
msgid "Could not connect to Tumblr. Refresh the page or try again later."
msgstr ""
#: tumblr.php:159
msgid "Unable to authenticate"
msgstr ""
#: tumblr.php:174
msgid "Save Settings" msgid "Save Settings"
msgstr "" msgstr ""
#: tumblr.php:71 #: tumblr.php:176
msgid "Consumer Key" msgid "Consumer Key"
msgstr "" msgstr ""
#: tumblr.php:72 #: tumblr.php:177
msgid "Consumer Secret" msgid "Consumer Secret"
msgstr "" msgstr ""
#: tumblr.php:177 #: tumblr.php:212
msgid "You are now authenticated to tumblr."
msgstr ""
#: tumblr.php:178
msgid "return to the connector page"
msgstr ""
#: tumblr.php:194
msgid "Post to Tumblr"
msgstr ""
#: tumblr.php:225
msgid "Post to page:" msgid "Post to page:"
msgstr "" msgstr ""
#: tumblr.php:231 #: tumblr.php:218
msgid "(Re-)Authenticate your tumblr page" msgid "(Re-)Authenticate your tumblr page"
msgstr "" msgstr ""
#: tumblr.php:232 #: tumblr.php:219
msgid "You are not authenticated to tumblr" msgid "You are not authenticated to tumblr"
msgstr "" msgstr ""
#: tumblr.php:237 #: tumblr.php:224
msgid "Enable Tumblr Post Addon" msgid "Enable Tumblr Post Addon"
msgstr "" msgstr ""
#: tumblr.php:238 #: tumblr.php:225
msgid "Post to Tumblr by default" msgid "Post to Tumblr by default"
msgstr "" msgstr ""
#: tumblr.php:244 #: tumblr.php:226
msgid "Tumblr Export" msgid "Import the remote timeline"
msgstr ""
#: tumblr.php:232
msgid "Tumblr Import/Export"
msgstr ""
#: tumblr.php:250
msgid "Post to Tumblr"
msgstr "" msgstr ""

View File

@ -6,35 +6,62 @@
* The first PHP Library to support OAuth for Tumblr's REST API. (Originally for Twitter, modified for Tumblr by Lucas) * The first PHP Library to support OAuth for Tumblr's REST API. (Originally for Twitter, modified for Tumblr by Lucas)
*/ */
use Friendica\Core\Logger;
use Friendica\DI; use Friendica\DI;
use Friendica\Security\OAuth1\OAuthConsumer; use Friendica\Security\OAuth1\OAuthConsumer;
use Friendica\Security\OAuth1\OAuthRequest; use Friendica\Security\OAuth1\OAuthRequest;
use Friendica\Security\OAuth1\Signature\OAuthSignatureMethod_HMAC_SHA1; use Friendica\Security\OAuth1\Signature\OAuthSignatureMethod_HMAC_SHA1;
use Friendica\Security\OAuth1\OAuthToken; use Friendica\Security\OAuth1\OAuthToken;
use Friendica\Security\OAuth1\OAuthUtil; use Friendica\Security\OAuth1\OAuthUtil;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
use Psr\Http\Message\ResponseInterface;
/** /**
* Tumblr OAuth class * Tumblr OAuth class
*/ */
class TumblrOAuth class TumblrOAuth
{ {
/* Contains the last HTTP status code returned. */ private $consumer_key;
public $http_code; private $consumer_secret;
private $oauth_token;
private $oauth_token_secret;
/** @var OAuthConsumer */ /** @var GuzzleHttp\Client */
private $consumer; private $client;
/** @var \Friendica\Security\OAuth1\Signature\OAuthSignatureMethod_HMAC_SHA1 */
private $sha1_method;
// API URLs // API URLs
const accessTokenURL = 'https://www.tumblr.com/oauth/access_token'; const accessTokenURL = 'https://www.tumblr.com/oauth/access_token';
const authorizeURL = 'https://www.tumblr.com/oauth/authorize'; const authorizeURL = 'https://www.tumblr.com/oauth/authorize';
const requestTokenURL = 'https://www.tumblr.com/oauth/request_token'; const requestTokenURL = 'https://www.tumblr.com/oauth/request_token';
function __construct(string $consumer_key, string $consumer_secret) function __construct(string $consumer_key, string $consumer_secret, string $oauth_token = '', string $oauth_token_secret = '')
{ {
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); $this->consumer_key = $consumer_key;
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); $this->consumer_secret = $consumer_secret;
$this->oauth_token = $oauth_token;
$this->oauth_token_secret = $oauth_token_secret;
if (empty($this->oauth_token) || empty($this->oauth_token_secret)) {
return;
}
$stack = HandlerStack::create();
$middleware = new Oauth1([
'consumer_key' => $this->consumer_key,
'consumer_secret' => $this->consumer_secret,
'token' => $this->oauth_token,
'token_secret' => $this->oauth_token_secret
]);
$stack->push($middleware);
$this->client = new Client([
'base_uri' => 'https://api.tumblr.com/v2/',
'handler' => $stack
]);
} }
/** /**
@ -46,6 +73,9 @@ class TumblrOAuth
function getRequestToken(string $oauth_callback): array function getRequestToken(string $oauth_callback): array
{ {
$request = $this->oAuthRequest(self::requestTokenURL, ['oauth_callback' => $oauth_callback]); $request = $this->oAuthRequest(self::requestTokenURL, ['oauth_callback' => $oauth_callback]);
if (empty($request)) {
return [];
}
return OAuthUtil::parse_parameters($request); return OAuthUtil::parse_parameters($request);
} }
@ -82,6 +112,9 @@ class TumblrOAuth
} }
$request = $this->oAuthRequest(self::accessTokenURL, $parameters, $token); $request = $this->oAuthRequest(self::accessTokenURL, $parameters, $token);
if (empty($request)) {
return [];
}
return OAuthUtil::parse_parameters($request); return OAuthUtil::parse_parameters($request);
} }
@ -95,14 +128,84 @@ class TumblrOAuth
*/ */
private function oAuthRequest(string $url, array $parameters, OAuthToken $token = null): string private function oAuthRequest(string $url, array $parameters, OAuthToken $token = null): string
{ {
$request = OAuthRequest::from_consumer_and_token($this->consumer, 'GET', $url, $parameters, $token); $consumer = new OAuthConsumer($this->consumer_key, $this->consumer_secret);
$request->sign_request($this->sha1_method, $this->consumer, $token); $sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
$request = OAuthRequest::from_consumer_and_token($consumer, 'GET', $url, $parameters, $token);
$request->sign_request($sha1_method, $consumer, $token);
$curlResult = DI::httpClient()->get($request->to_url()); $curlResult = DI::httpClient()->get($request->to_url());
$this->http_code = $curlResult->getReturnCode();
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
return $curlResult->getBody(); return $curlResult->getBody();
} }
return ''; return '';
} }
/**
* OAuth get from a given url with given parameters
*
* @param string $url
* @param array $parameters
* @return stdClass
*/
public function get(string $url, array $parameters = []): stdClass
{
if (!empty($parameters)) {
$url .= '?' . http_build_query($parameters);
}
try {
$response = $this->client->get($url, ['auth' => 'oauth']);
} catch (RequestException $exception) {
$response = $exception->getResponse();
Logger::notice('Get failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]);
}
return $this->formatResponse($response);
}
/**
* OAuth Post to a given url with given parameters
*
* @param string $url
* @param array $parameter
* @return stdClass
*/
public function post(string $url, array $parameter): stdClass
{
try {
$response = $this->client->post($url, ['auth' => 'oauth', 'json' => $parameter]);
} catch (RequestException $exception) {
$response = $exception->getResponse();
Logger::notice('Post failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]);
}
return $this->formatResponse($response);
}
/**
* Convert the body in the given response to a class
*
* @param ResponseInterface|null $response
* @return stdClass
*/
private function formatResponse(ResponseInterface $response = null): stdClass
{
if (!is_null($response)) {
$content = $response->getBody()->getContents();
if (!empty($content)) {
$result = json_decode($content);
}
}
if (empty($result) || empty($result->meta)) {
$result = new stdClass;
$result->meta = new stdClass;
$result->meta->status = 500;
$result->meta->msg = '';
$result->response = [];
$result->errors = [];
}
return $result;
}
} }

View File

@ -2,6 +2,7 @@
{{include file="field_checkbox.tpl" field=$enable}} {{include file="field_checkbox.tpl" field=$enable}}
{{include file="field_checkbox.tpl" field=$bydefault}} {{include file="field_checkbox.tpl" field=$bydefault}}
{{include file="field_checkbox.tpl" field=$import}}
{{if $page_select}} {{if $page_select}}
{{include file="field_select.tpl" field=$page_select}} {{include file="field_select.tpl" field=$page_select}}

File diff suppressed because it is too large Load Diff