From ca1b8a267da429de1fffa6207e76f0713e1536c7 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Tue, 8 Feb 2011 15:17:41 +0100 Subject: post to StatusNet addon for Friendika --- addon/statusnet/statusnet.php | 243 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 addon/statusnet/statusnet.php (limited to 'addon/statusnet/statusnet.php') diff --git a/addon/statusnet/statusnet.php b/addon/statusnet/statusnet.php new file mode 100644 index 000000000..b1d330541 --- /dev/null +++ b/addon/statusnet/statusnet.php @@ -0,0 +1,243 @@ +config['system']['addon'] + * setting. After this, your user can configure their Twitter account settings + * from "Settings -> Plugin Settings". + * + * Requirements: PHP5, curl [Slinky library] + * + * Documentation: http://diekershoff.homeunix.net/redmine/wiki/friendikaplugin/StatusNet_Plugin + */ + +/* __TODO__ + * + * - what about multimedia content? + * so far we just strip HTML tags from the message + */ + + +/*** + * We have to alter the TwitterOAuth class a little bit to work with any StatusNet + * installation abroad. Basically it's only make the API path variable and be happy. + * + * Thank you guys for the Twitter compatible API! + */ +require_once('addon/twitter/twitteroauth.php'); +class StatusNetOAuth extends TwitterOAuth { + function get_maxlength() { + $config = $this->get($this->host . 'statusnet/config.json'); + return $config->site->textlimit; + } + function accessTokenURL() { return $this->host.'oauth/access_token'; } + function authenticateURL() { return $this->host.'oauth/authenticate'; } + function authorizeURL() { return $this->host.'oauth/authorize'; } + function requestTokenURL() { return $this->host.'oauth/request_token'; } + function __construct($apipath, $consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { + parent::__construct($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret); + $this->host = $apipath; + } +} + +function statusnet_install() { + // we need some hooks, for the configuration and for sending tweets + register_hook('plugin_settings', 'addon/statusnet/statusnet.php', 'statusnet_settings'); + register_hook('plugin_settings_post', 'addon/statusnet/statusnet.php', 'statusnet_settings_post'); + register_hook('post_local_end', 'addon/statusnet/statusnet.php', 'statusnet_post_hook'); + logger("installed statusnet"); +} + + +function statusnet_uninstall() { + unregister_hook('plugin_settings', 'addon/statusnet/statusnet.php', 'statusnet_settings'); + unregister_hook('plugin_settings_post', 'addon/statusnet/statusnet.php', 'statusnet_settings_post'); + unregister_hook('post_local_end', 'addon/statusnet/statusnet.php', 'statusnet_post_hook'); +} + +function statusnet_settings_post ($a,$post) { + if(! local_user()) + return; + if (isset($_POST['statusnet-disconnect'])) { + /*** + * if the statusnet-disconnect checkbox is set, clear the statusnet configuration + * TODO can we revoke the access tokens at Twitter and do we need to do so? + */ + del_pconfig( local_user(), 'statusnet', 'consumerkey' ); + del_pconfig( local_user(), 'statusnet', 'consumersecret' ); + del_pconfig( local_user(), 'statusnet', 'post' ); + del_pconfig( local_user(), 'statusnet', 'oauthtoken' ); + del_pconfig( local_user(), 'statusnet', 'oauthsecret' ); + del_pconfig( local_user(), 'statusnet', 'baseapi' ); + } else { + if (isset($_POST['statusnet-consumersecret'])) { + set_pconfig(local_user(), 'statusnet', 'consumerkey', $_POST['statusnet-consumerkey']); + set_pconfig(local_user(), 'statusnet', 'consumersecret', $_POST['statusnet-consumersecret']); + set_pconfig(local_user(), 'statusnet', 'baseapi', $_POST['statusnet-baseapi']); + header('Location: '.$a->get_baseurl().'/settings/addon'); + } else { + if (isset($_POST['statusnet-pin'])) { + // if the user supplied us with a PIN from Twitter, let the magic of OAuth happen + logger('got a StatusNet security code'); + $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); + $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); + $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); + // the token and secret for which the PIN was generated were hidden in the settings + // form as token and token2, we need a new connection to Twitter using these token + // and secret to request a Access Token with the PIN + $connection = new StatusNetOAuth($api, $ckey, $csecret, $_POST['statusnet-token'], $_POST['statusnet-token2']); + $token = $connection->getAccessToken( $_POST['statusnet-pin'] ); + // ok, now that we have the Access Token, save them in the user config + set_pconfig(local_user(),'statusnet', 'oauthtoken', $token['oauth_token']); + set_pconfig(local_user(),'statusnet', 'oauthsecret', $token['oauth_token_secret']); + set_pconfig(local_user(),'statusnet', 'post', 1); + // reload the Addon Settings page, if we don't do it see Bug #42 + header('Location: '.$a->get_baseurl().'/settings/addon'); + } else { + // if no PIN is supplied in the POST variables, the user has changed the setting + // to post a tweet for every new __public__ posting to the wall + set_pconfig(local_user(),'statusnet','post',intval($_POST['statusnet-enable'])); + }}} +} +function statusnet_settings(&$a,&$s) { + if(! local_user()) + return; + $a->page['htmlhead'] .= '' . "\r\n"; + /*** + * 1) Check that we have a base api url and a consumer key & secret + * 2) If no OAuthtoken & stuff is present, generate button to get some + * 3) Checkbox for "Send public notices (respect size limitation) + */ + $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); + $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); + $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); + $otoken = get_pconfig(local_user(), 'statusnet', 'oauthtoken' ); + $osecret = get_pconfig(local_user(), 'statusnet', 'oauthsecret' ); + $enabled = get_pconfig(local_user(), 'statusnet', 'post'); + $checked = (($enabled) ? ' checked="checked" ' : ''); + $s .= '

'.t('StatusNet Posting Settings').'

'; + + if ( (!$ckey) && (!$csecret) ) { + /*** + * no consumer keys + */ + $s .= '

'.t('No consumer key pair for StatusNet found. Register your Friendika Account as an desktop client on your StatusNet account, copy the consumer key pair here and enter the API base root.
Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Friendika installation at your favorited StatusNet installation.').'

'; + $s .= '
'; + $s .= ''; + $s .= '
'; + $s .= ''; + $s .= '
'; + $s .= ''; + $s .= '
'; + $s .= '
'; + $s .= '
'; + } else { + /*** + * ok we have a consumer key pair now look into the OAuth stuff + */ + if ( (!$otoken) && (!$osecret) ) { + /*** + * the user has not yet connected the account to statusnet + * get a temporary OAuth key/secret pair and display a button with + * which the user can request a PIN to connect the account to a + * account at statusnet + */ + $connection = new StatusNetOAuth($api, $ckey, $csecret); + $request_token = $connection->getRequestToken('oob'); + $token = $request_token['oauth_token']; + /*** + * make some nice form + */ + $s .= '

'.t('To connect to your StatusNet account click the button below to get a security code from StatusNet which you have to copy into the input box below and submit the form. Only your public posts will be posted to StatusNet.').'

'; + $s .= ''.t('Log in with StatusNet').''; + $s .= '
'; + $s .= ''; + $s .= ''; + $s .= ''; + $s .= ''; + $s .= '
'; + $s .= '
'; + } else { + /*** + * we have an OAuth key / secret pair for the user + * so let's give a chance to disable the postings to statusnet + */ + $connection = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret); + $details = $connection->get('account/verify_credentials'); + $s .= '

'.t('Currently connected to: ').''.$details->screen_name.'
'.$details->description.'

'; + $s .= '

'.t('If enabled all your public postings will be posted to the associated StatusNet account as well.').'

'; + $s .= '
'; + $s .= ''; + $s .= ''; + $s .= '
'; + $s .= '
'; + $s .= ''; + $s .= ''; + $s .= '
'; + $s .= '
'; + } + } + $s .= '
'; +} + + +function statusnet_post_hook(&$a,&$b) { + + /** + * Post to statusnet + */ + + logger('StatusNet post invoked'); + + if((local_user()) && (local_user() == $b['uid']) && (! $b['private'])) { + + load_pconfig(local_user(), 'statusnet'); + + $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); + $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); + $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); + $otoken = get_pconfig(local_user(), 'statusnet', 'oauthtoken' ); + $osecret = get_pconfig(local_user(), 'statusnet', 'oauthsecret' ); + + if($ckey && $csecret && $otoken && $osecret) { + + $statusnet_post = get_pconfig(local_user(),'statusnet','post'); + + if($statusnet_post) { + require_once('include/bbcode.php'); + $dent = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret); + $max_char = $dent->get_maxlength(); // max. length for a dent + $msg = strip_tags(bbcode($b['body'])); + if ( strlen($msg) > $max_char) { + $shortlink = ""; + require_once('addon/statusnet/slinky.php'); + // post url = base url + /display/ + owner + post id + // we construct this from the Owner link and replace + // profile by display - this will cause an error when + // /profile/ is in the owner url twice but I don't + // think this will be very common... + $posturl = str_replace('/profile/','/display/',$b['owner-link']).'/'.$b['id']; + $slinky = new Slinky( $posturl ); + // setup a cascade of shortening services + // try to get a short link from these services + // in the order ur1.ca, trim, id.gd, tinyurl + $slinky->set_cascade( array( new Slinky_UR1ca(), new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) ); + $shortlink = $slinky->short(); + // the new message will be shortened such that "... $shortlink" + // will fit into the character limit + $msg = substr($msg, 0, $max_char-strlen($shortlink)-4); + $msg .= '... ' . $shortlink; + } + // and now tweet it :-) + $dent->post('statuses/update', array('status' => $msg)); + } + } + } +} + -- cgit v1.2.3 From 89da23c30e132fa1f0c118e32e386cbd9c3c88af Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 9 Feb 2011 09:40:56 +0100 Subject: spaces for the string extractor, check no parent --- addon/statusnet/statusnet.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'addon/statusnet/statusnet.php') diff --git a/addon/statusnet/statusnet.php b/addon/statusnet/statusnet.php index b1d330541..cd562cd1e 100644 --- a/addon/statusnet/statusnet.php +++ b/addon/statusnet/statusnet.php @@ -127,13 +127,13 @@ function statusnet_settings(&$a,&$s) { /*** * no consumer keys */ - $s .= '

'.t('No consumer key pair for StatusNet found. Register your Friendika Account as an desktop client on your StatusNet account, copy the consumer key pair here and enter the API base root.
Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Friendika installation at your favorited StatusNet installation.').'

'; + $s .= '

'. t('No consumer key pair for StatusNet found. Register your Friendika Account as an desktop client on your StatusNet account, copy the consumer key pair here and enter the API base root.
Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Friendika installation at your favorited StatusNet installation.') .'

'; $s .= '
'; - $s .= ''; + $s .= ''; $s .= '
'; - $s .= ''; + $s .= ''; $s .= '
'; - $s .= ''; + $s .= ''; $s .= '
'; $s .= '
'; $s .= '
'; @@ -154,10 +154,10 @@ function statusnet_settings(&$a,&$s) { /*** * make some nice form */ - $s .= '

'.t('To connect to your StatusNet account click the button below to get a security code from StatusNet which you have to copy into the input box below and submit the form. Only your public posts will be posted to StatusNet.').'

'; - $s .= ''.t('Log in with StatusNet').''; + $s .= '

'. t('To connect to your StatusNet account click the button below to get a security code from StatusNet which you have to copy into the input box below and submit the form. Only your public posts will be posted to StatusNet.') .'

'; + $s .= ''. t('Log in with StatusNet') .''; $s .= '
'; - $s .= ''; + $s .= ''; $s .= ''; $s .= ''; $s .= ''; @@ -170,14 +170,14 @@ function statusnet_settings(&$a,&$s) { */ $connection = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret); $details = $connection->get('account/verify_credentials'); - $s .= '

'.t('Currently connected to: ').''.$details->screen_name.'
'.$details->description.'

'; - $s .= '

'.t('If enabled all your public postings will be posted to the associated StatusNet account as well.').'

'; + $s .= '

'. t('Currently connected to: ') .''.$details->screen_name.'
'.$details->description.'

'; + $s .= '

'. t('If enabled all your public postings will be posted to the associated StatusNet account as well.') .'

'; $s .= '
'; - $s .= ''; + $s .= ''; $s .= ''; $s .= '
'; $s .= '
'; - $s .= ''; + $s .= ''; $s .= ''; $s .= '
'; $s .= '
'; @@ -195,7 +195,7 @@ function statusnet_post_hook(&$a,&$b) { logger('StatusNet post invoked'); - if((local_user()) && (local_user() == $b['uid']) && (! $b['private'])) { + if((local_user()) && (local_user() == $b['uid']) && (! $b['private']) && (!$b['parent']) ) { load_pconfig(local_user(), 'statusnet'); -- cgit v1.2.3 From a18bb816cd4a0d82b1e2d0f9c456669987ced83b Mon Sep 17 00:00:00 2001 From: Friendika Date: Thu, 10 Feb 2011 03:51:42 -0800 Subject: entirely possible media/links were the only thing posted - don't forward empty message to twitter/SN --- addon/statusnet/statusnet.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addon/statusnet/statusnet.php') diff --git a/addon/statusnet/statusnet.php b/addon/statusnet/statusnet.php index cd562cd1e..bc47242fc 100644 --- a/addon/statusnet/statusnet.php +++ b/addon/statusnet/statusnet.php @@ -235,7 +235,8 @@ function statusnet_post_hook(&$a,&$b) { $msg .= '... ' . $shortlink; } // and now tweet it :-) - $dent->post('statuses/update', array('status' => $msg)); + if(strlen($msg)) + $dent->post('statuses/update', array('status' => $msg)); } } } -- cgit v1.2.3