1622 lines
51 KiB
PHP
1622 lines
51 KiB
PHP
<?php
|
|
/**
|
|
* Name: pump.io Post Connector
|
|
* Description: Bidirectional (posting, relaying and reading) connector for pump.io.
|
|
* Version: 0.2
|
|
* Author: Michael Vogel <http://pirati.ca/profile/heluecht>
|
|
*/
|
|
|
|
use Friendica\App;
|
|
use Friendica\Content\Text\BBCode;
|
|
use Friendica\Content\Text\HTML;
|
|
use Friendica\Core\Config;
|
|
use Friendica\Core\Hook;
|
|
use Friendica\Core\L10n;
|
|
use Friendica\Core\Logger;
|
|
use Friendica\Core\PConfig;
|
|
use Friendica\Core\Protocol;
|
|
use Friendica\Core\Worker;
|
|
use Friendica\Database\DBA;
|
|
use Friendica\Model\Contact;
|
|
use Friendica\Model\Group;
|
|
use Friendica\Model\Item;
|
|
use Friendica\Model\User;
|
|
use Friendica\Protocol\Activity;
|
|
use Friendica\Util\ConfigFileLoader;
|
|
use Friendica\Util\DateTimeFormat;
|
|
use Friendica\Util\Network;
|
|
use Friendica\Util\Strings;
|
|
use Friendica\Util\XML;
|
|
|
|
require 'addon/pumpio/oauth/http.php';
|
|
require 'addon/pumpio/oauth/oauth_client.php';
|
|
require_once "mod/share.php";
|
|
|
|
define('PUMPIO_DEFAULT_POLL_INTERVAL', 5); // given in minutes
|
|
|
|
function pumpio_install()
|
|
{
|
|
Hook::register('load_config', 'addon/pumpio/pumpio.php', 'pumpio_load_config');
|
|
Hook::register('hook_fork', 'addon/pumpio/pumpio.php', 'hook_fork');
|
|
Hook::register('post_local', 'addon/pumpio/pumpio.php', 'pumpio_post_local');
|
|
Hook::register('notifier_normal', 'addon/pumpio/pumpio.php', 'pumpio_send');
|
|
Hook::register('jot_networks', 'addon/pumpio/pumpio.php', 'pumpio_jot_nets');
|
|
Hook::register('connector_settings', 'addon/pumpio/pumpio.php', 'pumpio_settings');
|
|
Hook::register('connector_settings_post', 'addon/pumpio/pumpio.php', 'pumpio_settings_post');
|
|
Hook::register('cron', 'addon/pumpio/pumpio.php', 'pumpio_cron');
|
|
Hook::register('check_item_notification', 'addon/pumpio/pumpio.php', 'pumpio_check_item_notification');
|
|
}
|
|
|
|
function pumpio_uninstall()
|
|
{
|
|
Hook::unregister('load_config', 'addon/pumpio/pumpio.php', 'pumpio_load_config');
|
|
Hook::unregister('hook_fork', 'addon/pumpio/pumpio.php', 'pumpio_hook_fork');
|
|
Hook::unregister('post_local', 'addon/pumpio/pumpio.php', 'pumpio_post_local');
|
|
Hook::unregister('notifier_normal', 'addon/pumpio/pumpio.php', 'pumpio_send');
|
|
Hook::unregister('jot_networks', 'addon/pumpio/pumpio.php', 'pumpio_jot_nets');
|
|
Hook::unregister('connector_settings', 'addon/pumpio/pumpio.php', 'pumpio_settings');
|
|
Hook::unregister('connector_settings_post', 'addon/pumpio/pumpio.php', 'pumpio_settings_post');
|
|
Hook::unregister('cron', 'addon/pumpio/pumpio.php', 'pumpio_cron');
|
|
Hook::unregister('check_item_notification', 'addon/pumpio/pumpio.php', 'pumpio_check_item_notification');
|
|
}
|
|
|
|
function pumpio_module() {}
|
|
|
|
function pumpio_content(App $a)
|
|
{
|
|
if (!local_user()) {
|
|
notice(L10n::t('Permission denied.') . EOL);
|
|
return '';
|
|
}
|
|
|
|
require_once("mod/settings.php");
|
|
settings_init($a);
|
|
|
|
if (isset($a->argv[1])) {
|
|
switch ($a->argv[1]) {
|
|
case "connect":
|
|
$o = pumpio_connect($a);
|
|
break;
|
|
default:
|
|
$o = print_r($a->argv, true);
|
|
break;
|
|
}
|
|
} else {
|
|
$o = pumpio_connect($a);
|
|
}
|
|
return $o;
|
|
}
|
|
|
|
function pumpio_check_item_notification($a, &$notification_data)
|
|
{
|
|
$hostname = PConfig::get($notification_data["uid"], 'pumpio', 'host');
|
|
$username = PConfig::get($notification_data["uid"], "pumpio", "user");
|
|
|
|
$notification_data["profiles"][] = "https://".$hostname."/".$username;
|
|
}
|
|
|
|
function pumpio_registerclient(App $a, $host)
|
|
{
|
|
$url = "https://".$host."/api/client/register";
|
|
|
|
$params = [];
|
|
|
|
$application_name = Config::get('pumpio', 'application_name');
|
|
|
|
if ($application_name == "") {
|
|
$application_name = $a->getHostName();
|
|
}
|
|
|
|
$adminlist = explode(",", str_replace(" ", "", Config::get('config', 'admin_email')));
|
|
|
|
$params["type"] = "client_associate";
|
|
$params["contacts"] = $adminlist[0];
|
|
$params["application_type"] = "native";
|
|
$params["application_name"] = $application_name;
|
|
$params["logo_url"] = $a->getBaseURL()."/images/friendica-256.png";
|
|
$params["redirect_uris"] = $a->getBaseURL()."/pumpio/connect";
|
|
|
|
Logger::log("pumpio_registerclient: ".$url." parameters ".print_r($params, true), Logger::DEBUG);
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt($ch, CURLOPT_HEADER, false);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_POST,1);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
|
|
curl_setopt($ch, CURLOPT_USERAGENT, "Friendica");
|
|
|
|
$s = curl_exec($ch);
|
|
$curl_info = curl_getinfo($ch);
|
|
|
|
if ($curl_info["http_code"] == "200") {
|
|
$values = json_decode($s);
|
|
Logger::log("pumpio_registerclient: success ".print_r($values, true), Logger::DEBUG);
|
|
return $values;
|
|
}
|
|
Logger::log("pumpio_registerclient: failed: ".print_r($curl_info, true), Logger::DEBUG);
|
|
return false;
|
|
|
|
}
|
|
|
|
function pumpio_connect(App $a)
|
|
{
|
|
// Define the needed keys
|
|
$consumer_key = PConfig::get(local_user(), 'pumpio', 'consumer_key');
|
|
$consumer_secret = PConfig::get(local_user(), 'pumpio', 'consumer_secret');
|
|
$hostname = PConfig::get(local_user(), 'pumpio', 'host');
|
|
|
|
if ((($consumer_key == "") || ($consumer_secret == "")) && ($hostname != "")) {
|
|
Logger::log("pumpio_connect: register client");
|
|
$clientdata = pumpio_registerclient($a, $hostname);
|
|
PConfig::set(local_user(), 'pumpio', 'consumer_key', $clientdata->client_id);
|
|
PConfig::set(local_user(), 'pumpio', 'consumer_secret', $clientdata->client_secret);
|
|
|
|
$consumer_key = PConfig::get(local_user(), 'pumpio', 'consumer_key');
|
|
$consumer_secret = PConfig::get(local_user(), 'pumpio', 'consumer_secret');
|
|
|
|
Logger::log("pumpio_connect: ckey: ".$consumer_key." csecrect: ".$consumer_secret, Logger::DEBUG);
|
|
}
|
|
|
|
if (($consumer_key == "") || ($consumer_secret == "")) {
|
|
Logger::log("pumpio_connect: ".sprintf("Unable to register the client at the pump.io server '%s'.", $hostname));
|
|
|
|
$o .= L10n::t("Unable to register the client at the pump.io server '%s'.", $hostname);
|
|
return $o;
|
|
}
|
|
|
|
// The callback URL is the script that gets called after the user authenticates with pumpio
|
|
$callback_url = $a->getBaseURL()."/pumpio/connect";
|
|
|
|
// Let's begin. First we need a Request Token. The request token is required to send the user
|
|
// to pumpio's login page.
|
|
|
|
// Create a new instance of the oauth_client_class library. For this step, all we need to give the library is our
|
|
// Consumer Key and Consumer Secret
|
|
$client = new oauth_client_class;
|
|
$client->debug = 0;
|
|
$client->server = '';
|
|
$client->oauth_version = '1.0a';
|
|
$client->request_token_url = 'https://'.$hostname.'/oauth/request_token';
|
|
$client->dialog_url = 'https://'.$hostname.'/oauth/authorize';
|
|
$client->access_token_url = 'https://'.$hostname.'/oauth/access_token';
|
|
$client->url_parameters = false;
|
|
$client->authorization_header = true;
|
|
$client->redirect_uri = $callback_url;
|
|
$client->client_id = $consumer_key;
|
|
$client->client_secret = $consumer_secret;
|
|
|
|
if (($success = $client->Initialize())) {
|
|
if (($success = $client->Process())) {
|
|
if (strlen($client->access_token)) {
|
|
Logger::log("pumpio_connect: otoken: ".$client->access_token." osecrect: ".$client->access_token_secret, Logger::DEBUG);
|
|
PConfig::set(local_user(), "pumpio", "oauth_token", $client->access_token);
|
|
PConfig::set(local_user(), "pumpio", "oauth_token_secret", $client->access_token_secret);
|
|
}
|
|
}
|
|
$success = $client->Finalize($success);
|
|
}
|
|
if ($client->exit) {
|
|
$o = 'Could not connect to pumpio. Refresh the page or try again later.';
|
|
}
|
|
|
|
if ($success) {
|
|
Logger::log("pumpio_connect: authenticated");
|
|
$o = L10n::t("You are now authenticated to pumpio.");
|
|
$o .= '<br /><a href="'.$a->getBaseURL().'/settings/connectors">'.L10n::t("return to the connector page").'</a>';
|
|
} else {
|
|
Logger::log("pumpio_connect: could not connect");
|
|
$o = 'Could not connect to pumpio. Refresh the page or try again later.';
|
|
}
|
|
|
|
return $o;
|
|
}
|
|
|
|
function pumpio_jot_nets(App $a, array &$jotnets_fields)
|
|
{
|
|
if (! local_user()) {
|
|
return;
|
|
}
|
|
|
|
if (PConfig::get(local_user(), 'pumpio', 'post')) {
|
|
$jotnets_fields[] = [
|
|
'type' => 'checkbox',
|
|
'field' => [
|
|
'pumpio_enable',
|
|
L10n::t('Post to pumpio'),
|
|
PConfig::get(local_user(), 'pumpio', 'post_by_default')
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
function pumpio_settings(App $a, &$s)
|
|
{
|
|
if (!local_user()) {
|
|
return;
|
|
}
|
|
|
|
/* Add our stylesheet to the page so we can make our settings look nice */
|
|
|
|
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->getBaseURL() . '/addon/pumpio/pumpio.css' . '" media="all" />' . "\r\n";
|
|
|
|
/* Get the current state of our config variables */
|
|
|
|
$import_enabled = PConfig::get(local_user(), 'pumpio', 'import');
|
|
$import_checked = (($import_enabled) ? ' checked="checked" ' : '');
|
|
|
|
$enabled = PConfig::get(local_user(), 'pumpio', 'post');
|
|
$checked = (($enabled) ? ' checked="checked" ' : '');
|
|
$css = (($enabled) ? '' : '-disabled');
|
|
|
|
$def_enabled = PConfig::get(local_user(), 'pumpio', 'post_by_default');
|
|
$def_checked = (($def_enabled) ? ' checked="checked" ' : '');
|
|
|
|
$public_enabled = PConfig::get(local_user(), 'pumpio', 'public');
|
|
$public_checked = (($public_enabled) ? ' checked="checked" ' : '');
|
|
|
|
$mirror_enabled = PConfig::get(local_user(), 'pumpio', 'mirror');
|
|
$mirror_checked = (($mirror_enabled) ? ' checked="checked" ' : '');
|
|
|
|
$servername = PConfig::get(local_user(), "pumpio", "host");
|
|
$username = PConfig::get(local_user(), "pumpio", "user");
|
|
|
|
/* Add some HTML to the existing form */
|
|
|
|
$s .= '<span id="settings_pumpio_inflated" class="settings-block fakelink" style="display: block;" onclick="openClose(\'settings_pumpio_expanded\'); openClose(\'settings_pumpio_inflated\');">';
|
|
$s .= '<img class="connector'.$css.'" src="images/pumpio.png" /><h3 class="connector">'. L10n::t('Pump.io Import/Export/Mirror').'</h3>';
|
|
$s .= '</span>';
|
|
$s .= '<div id="settings_pumpio_expanded" class="settings-block" style="display: none;">';
|
|
$s .= '<span class="fakelink" onclick="openClose(\'settings_pumpio_expanded\'); openClose(\'settings_pumpio_inflated\');">';
|
|
$s .= '<img class="connector'.$css.'" src="images/pumpio.png" /><h3 class="connector">'. L10n::t('Pump.io Import/Export/Mirror').'</h3>';
|
|
$s .= '</span>';
|
|
|
|
$s .= '<div id="pumpio-username-wrapper">';
|
|
$s .= '<label id="pumpio-username-label" for="pumpio-username">'.L10n::t('pump.io username (without the servername)').'</label>';
|
|
$s .= '<input id="pumpio-username" type="text" name="pumpio_user" value="'.$username.'" />';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
$s .= '<div id="pumpio-servername-wrapper">';
|
|
$s .= '<label id="pumpio-servername-label" for="pumpio-servername">'.L10n::t('pump.io servername (without "http://" or "https://" )').'</label>';
|
|
$s .= '<input id="pumpio-servername" type="text" name="pumpio_host" value="'.$servername.'" />';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
if (($username != '') && ($servername != '')) {
|
|
$oauth_token = PConfig::get(local_user(), "pumpio", "oauth_token");
|
|
$oauth_token_secret = PConfig::get(local_user(), "pumpio", "oauth_token_secret");
|
|
|
|
$s .= '<div id="pumpio-password-wrapper">';
|
|
if (($oauth_token == "") || ($oauth_token_secret == "")) {
|
|
$s .= '<div id="pumpio-authenticate-wrapper">';
|
|
$s .= '<a href="'.$a->getBaseURL().'/pumpio/connect">'.L10n::t("Authenticate your pump.io connection").'</a>';
|
|
$s .= '</div><div class="clear"></div>';
|
|
} else {
|
|
$s .= '<div id="pumpio-import-wrapper">';
|
|
$s .= '<label id="pumpio-import-label" for="pumpio-import">' . L10n::t('Import the remote timeline') . '</label>';
|
|
$s .= '<input id="pumpio-import" type="checkbox" name="pumpio_import" value="1" ' . $import_checked . '/>';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
$s .= '<div id="pumpio-enable-wrapper">';
|
|
$s .= '<label id="pumpio-enable-label" for="pumpio-checkbox">' . L10n::t('Enable pump.io Post Addon') . '</label>';
|
|
$s .= '<input id="pumpio-checkbox" type="checkbox" name="pumpio" value="1" ' . $checked . '/>';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
$s .= '<div id="pumpio-bydefault-wrapper">';
|
|
$s .= '<label id="pumpio-bydefault-label" for="pumpio-bydefault">' . L10n::t('Post to pump.io by default') . '</label>';
|
|
$s .= '<input id="pumpio-bydefault" type="checkbox" name="pumpio_bydefault" value="1" ' . $def_checked . '/>';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
$s .= '<div id="pumpio-public-wrapper">';
|
|
$s .= '<label id="pumpio-public-label" for="pumpio-public">' . L10n::t('Should posts be public?') . '</label>';
|
|
$s .= '<input id="pumpio-public" type="checkbox" name="pumpio_public" value="1" ' . $public_checked . '/>';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
$s .= '<div id="pumpio-mirror-wrapper">';
|
|
$s .= '<label id="pumpio-mirror-label" for="pumpio-mirror">' . L10n::t('Mirror all public posts') . '</label>';
|
|
$s .= '<input id="pumpio-mirror" type="checkbox" name="pumpio_mirror" value="1" ' . $mirror_checked . '/>';
|
|
$s .= '</div><div class="clear"></div>';
|
|
|
|
$s .= '<div id="pumpio-delete-wrapper">';
|
|
$s .= '<label id="pumpio-delete-label" for="pumpio-delete">' . L10n::t('Check to delete this preset') . '</label>';
|
|
$s .= '<input id="pumpio-delete" type="checkbox" name="pumpio_delete" value="1" />';
|
|
$s .= '</div><div class="clear"></div>';
|
|
}
|
|
|
|
$s .= '</div><div class="clear"></div>';
|
|
}
|
|
|
|
/* provide a submit button */
|
|
|
|
$s .= '<div class="settings-submit-wrapper" ><input type="submit" id="pumpio-submit" name="pumpio-submit" class="settings-submit" value="' . L10n::t('Save Settings') . '" /></div></div>';
|
|
}
|
|
|
|
function pumpio_settings_post(App $a, array &$b)
|
|
{
|
|
if (!empty($_POST['pumpio-submit'])) {
|
|
if (!empty($_POST['pumpio_delete'])) {
|
|
PConfig::set(local_user(), 'pumpio', 'consumer_key' , '');
|
|
PConfig::set(local_user(), 'pumpio', 'consumer_secret' , '');
|
|
PConfig::set(local_user(), 'pumpio', 'oauth_token' , '');
|
|
PConfig::set(local_user(), 'pumpio', 'oauth_token_secret', '');
|
|
PConfig::set(local_user(), 'pumpio', 'post' , false);
|
|
PConfig::set(local_user(), 'pumpio', 'import' , false);
|
|
PConfig::set(local_user(), 'pumpio', 'host' , '');
|
|
PConfig::set(local_user(), 'pumpio', 'user' , '');
|
|
PConfig::set(local_user(), 'pumpio', 'public' , false);
|
|
PConfig::set(local_user(), 'pumpio', 'mirror' , false);
|
|
PConfig::set(local_user(), 'pumpio', 'post_by_default' , false);
|
|
PConfig::set(local_user(), 'pumpio', 'lastdate' , 0);
|
|
PConfig::set(local_user(), 'pumpio', 'last_id' , '');
|
|
} else {
|
|
// filtering the username if it is filled wrong
|
|
$user = $_POST['pumpio_user'];
|
|
if (strstr($user, "@")) {
|
|
$pos = strpos($user, "@");
|
|
|
|
if ($pos > 0) {
|
|
$user = substr($user, 0, $pos);
|
|
}
|
|
}
|
|
|
|
// Filtering the hostname if someone is entering it with "http"
|
|
$host = $_POST['pumpio_host'];
|
|
$host = trim($host);
|
|
$host = str_replace(["https://", "http://"], ["", ""], $host);
|
|
|
|
PConfig::set(local_user(), 'pumpio', 'post' , $_POST['pumpio'] ?? false);
|
|
PConfig::set(local_user(), 'pumpio', 'import' , $_POST['pumpio_import'] ?? false);
|
|
PConfig::set(local_user(), 'pumpio', 'host' , $host);
|
|
PConfig::set(local_user(), 'pumpio', 'user' , $user);
|
|
PConfig::set(local_user(), 'pumpio', 'public' , $_POST['pumpio_public'] ?? false);
|
|
PConfig::set(local_user(), 'pumpio', 'mirror' , $_POST['pumpio_mirror'] ?? false);
|
|
PConfig::set(local_user(), 'pumpio', 'post_by_default', $_POST['pumpio_bydefault'] ?? false);
|
|
|
|
if (!empty($_POST['pumpio_mirror'])) {
|
|
PConfig::delete(local_user(), 'pumpio', 'lastdate');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function pumpio_load_config(App $a, ConfigFileLoader $loader)
|
|
{
|
|
$a->getConfigCache()->load($loader->loadAddonConfig('pumpio'));
|
|
}
|
|
|
|
function pumpio_hook_fork(App $a, array &$b)
|
|
{
|
|
if ($b['name'] != 'notifier_normal') {
|
|
return;
|
|
}
|
|
|
|
$post = $b['data'];
|
|
|
|
// Deleting and editing is not supported by the addon (deleting could, but isn't by now)
|
|
if ($post['deleted'] || ($post['created'] !== $post['edited'])) {
|
|
$b['execute'] = false;
|
|
return;
|
|
}
|
|
|
|
// if post comes from pump.io don't send it back
|
|
if ($post['app'] == "pump.io") {
|
|
$b['execute'] = false;
|
|
return;
|
|
}
|
|
|
|
if (PConfig::get($post['uid'], 'pumpio', 'import')) {
|
|
// Don't fork if it isn't a reply to a pump.io post
|
|
if (($post['parent'] != $post['id']) && !Item::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) {
|
|
Logger::log('No pump.io parent found for item ' . $post['id']);
|
|
$b['execute'] = false;
|
|
return;
|
|
}
|
|
} else {
|
|
// Comments are never exported when we don't import the pumpio timeline
|
|
if (!strstr($post['postopts'], 'pumpio') || ($post['parent'] != $post['id']) || $post['private']) {
|
|
$b['execute'] = false;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|