X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=statusnet%2Fstatusnet.php;h=d168955cd4deec2e3d95350e8da7b12ad1d48f35;hb=0655fe3cbab458d836b4508c9c7f1ee0b5506e2d;hp=46b3f03f520fa3fab23581da76839430bf54b10b;hpb=a30ee1587f4662e8d21235d0e7f1ea2e2eea24cd;p=friendica-addons.git diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index 46b3f03f..d168955c 100755 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -3,25 +3,36 @@ * Name: StatusNet Connector * Description: Relay public postings to a connected StatusNet account * Version: 1.0.5 - * Author: Tobias Diekershoff - */ - -/* StatusNet Plugin for Friendica + * Author: Tobias Diekershoff + * Author: Michael Vogel * - * Author: Tobias Diekershoff - * tobias.diekershoff@gmx.net + * Copyright (c) 2011-2013 Tobias Diekershoff, Michael Vogel + * All rights reserved. * - * License:3-clause BSD license + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * * copyright notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * Configuration: - * To activate the plugin itself add it to the $a->config['system']['addon'] - * setting. After this, your user can configure their Twitter account settings - * from "Settings -> Plugin Settings". + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Requirements: PHP5, curl [Slinky library] - * - * Documentation: http://diekershoff.homeunix.net/redmine/wiki/friendikaplugin/StatusNet_Plugin */ + /*** * We have to alter the TwitterOAuth class a little bit to work with any StatusNet @@ -30,6 +41,8 @@ * Thank you guys for the Twitter compatible API! */ +define('STATUSNET_DEFAULT_POLL_INTERVAL', 5); // given in minutes + require_once('library/twitteroauth.php'); class StatusNetOAuth extends TwitterOAuth { @@ -104,6 +117,7 @@ function statusnet_install() { register_hook('notifier_normal', 'addon/statusnet/statusnet.php', 'statusnet_post_hook'); register_hook('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local'); register_hook('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets'); + register_hook('cron', 'addon/statusnet/statusnet.php', 'statusnet_cron'); logger("installed statusnet"); } @@ -114,6 +128,7 @@ function statusnet_uninstall() { unregister_hook('notifier_normal', 'addon/statusnet/statusnet.php', 'statusnet_post_hook'); unregister_hook('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local'); unregister_hook('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets'); + unregister_hook('cron', 'addon/statusnet/statusnet.php', 'statusnet_cron'); // old setting - remove only unregister_hook('post_local_end', 'addon/statusnet/statusnet.php', 'statusnet_post_hook'); @@ -131,13 +146,10 @@ function statusnet_jot_nets(&$a,&$b) { $statusnet_defpost = get_pconfig(local_user(),'statusnet','post_by_default'); $selected = ((intval($statusnet_defpost) == 1) ? ' checked="checked" ' : ''); $b .= '
' - . t('Post to StatusNet') . '
'; + . t('Post to StatusNet') . ''; } } - - - function statusnet_settings_post ($a,$post) { if(! local_user()) return; @@ -148,14 +160,17 @@ function statusnet_settings_post ($a,$post) { /*** * if the statusnet-disconnect checkbox is set, clear the statusnet configuration */ - del_pconfig( local_user(), 'statusnet', 'consumerkey' ); - del_pconfig( local_user(), 'statusnet', 'consumersecret' ); - del_pconfig( local_user(), 'statusnet', 'post' ); - del_pconfig( local_user(), 'statusnet', 'post_by_default' ); - del_pconfig( local_user(), 'statusnet', 'oauthtoken' ); - del_pconfig( local_user(), 'statusnet', 'oauthsecret' ); - del_pconfig( local_user(), 'statusnet', 'baseapi' ); - del_pconfig( local_user(), 'statusnet', 'post_taglinks'); + del_pconfig(local_user(), 'statusnet', 'consumerkey'); + del_pconfig(local_user(), 'statusnet', 'consumersecret'); + del_pconfig(local_user(), 'statusnet', 'post'); + del_pconfig(local_user(), 'statusnet', 'post_by_default'); + del_pconfig(local_user(), 'statusnet', 'oauthtoken'); + del_pconfig(local_user(), 'statusnet', 'oauthsecret'); + del_pconfig(local_user(), 'statusnet', 'baseapi'); + del_pconfig(local_user(), 'statusnet', 'post_taglinks'); + del_pconfig(local_user(), 'statusnet', 'lastid'); + del_pconfig(local_user(), 'statusnet', 'mirror_posts'); + del_pconfig(local_user(), 'statusnet', 'intelligent_shortening'); } else { if (isset($_POST['statusnet-preconf-apiurl'])) { /*** @@ -172,6 +187,7 @@ function statusnet_settings_post ($a,$post) { set_pconfig(local_user(), 'statusnet', 'consumerkey', $asn['consumerkey'] ); set_pconfig(local_user(), 'statusnet', 'consumersecret', $asn['consumersecret'] ); set_pconfig(local_user(), 'statusnet', 'baseapi', $asn['apiurl'] ); + set_pconfig(local_user(), 'statusnet', 'application_name', $asn['applicationname'] ); } else { notice( t('Please contact your site administrator.
The provided API URL is not valid.').EOL.$asn['apiurl'].EOL ); } @@ -190,6 +206,7 @@ function statusnet_settings_post ($a,$post) { set_pconfig(local_user(), 'statusnet', 'consumerkey', $_POST['statusnet-consumerkey']); set_pconfig(local_user(), 'statusnet', 'consumersecret', $_POST['statusnet-consumersecret']); set_pconfig(local_user(), 'statusnet', 'baseapi', $apibase ); + set_pconfig(local_user(), 'statusnet', 'application_name', $_POST['statusnet-applicationname'] ); } else { // the API path is not correct, maybe missing trailing / ? $apibase = $apibase . '/'; @@ -207,7 +224,7 @@ function statusnet_settings_post ($a,$post) { goaway($a->get_baseurl().'/settings/connectors'); } else { if (isset($_POST['statusnet-pin'])) { - // if the user supplied us with a PIN from Twitter, let the magic of OAuth happen + // if the user supplied us with a PIN from StatusNet, let the magic of OAuth happen $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); @@ -229,6 +246,8 @@ function statusnet_settings_post ($a,$post) { set_pconfig(local_user(),'statusnet','post',intval($_POST['statusnet-enable'])); set_pconfig(local_user(),'statusnet','post_by_default',intval($_POST['statusnet-default'])); set_pconfig(local_user(),'statusnet','post_taglinks',intval($_POST['statusnet-sendtaglinks'])); + set_pconfig(local_user(), 'statusnet', 'mirror_posts', intval($_POST['statusnet-mirror'])); + set_pconfig(local_user(), 'statusnet', 'intelligent_shortening', intval($_POST['statusnet-shortening'])); info( t('StatusNet settings updated.') . EOL); }}}} } @@ -253,6 +272,12 @@ function statusnet_settings(&$a,&$s) { $defchecked = (($defenabled) ? ' checked="checked" ' : ''); $linksenabled = get_pconfig(local_user(),'statusnet','post_taglinks'); $linkschecked = (($linksenabled) ? ' checked="checked" ' : ''); + + $mirrorenabled = get_pconfig(local_user(),'statusnet','mirror_posts'); + $mirrorchecked = (($mirrorenabled) ? ' checked="checked" ' : ''); + $shorteningenabled = get_pconfig(local_user(),'statusnet','intelligent_shortening'); + $shorteningchecked = (($shorteningenabled) ? ' checked="checked" ' : ''); + $s .= '
'; $s .= '

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

'; @@ -289,6 +314,9 @@ function statusnet_settings(&$a,&$s) { $s .= ''; $s .= '
'; $s .= '

'; + $s .= ''; + $s .= '
'; + $s .= '

'; $s .= '
'; } else { /*** @@ -342,6 +370,15 @@ function statusnet_settings(&$a,&$s) { $s .= ''; $s .= ''; $s .= '
'; + + $s .= ''; + $s .= ''; + $s .= '
'; + + $s .= ''; + $s .= ''; + $s .= '
'; + $s .= ''; $s .= ''; $s .= '
'; @@ -404,6 +441,137 @@ function short_link($url) { return $slinky->short(); } }; +function statusnet_shortenmsg($b, $max_char) { + require_once("include/bbcode.php"); + require_once("include/html2plain.php"); + + // Looking for the first image + $image = ''; + if(preg_match("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/is",$b['body'],$matches)) + $image = $matches[3]; + + if ($image == '') + if(preg_match("/\[img\](.*?)\[\/img\]/is",$b['body'],$matches)) + $image = $matches[1]; + + $multipleimages = (strpos($b['body'], "[img") != strrpos($b['body'], "[img")); + + // When saved into the database the content is sent through htmlspecialchars + // That means that we have to decode all image-urls + $image = htmlspecialchars_decode($image); + + $body = $b["body"]; + if ($b["title"] != "") + $body = $b["title"]."\n\n".$body; + + if (strpos($body, "[bookmark") !== false) { + // splitting the text in two parts: + // before and after the bookmark + $pos = strpos($body, "[bookmark"); + $body1 = substr($body, 0, $pos); + $body2 = substr($body, $pos); + + // Removing all quotes after the bookmark + // they are mostly only the content after the bookmark. + $body2 = preg_replace("/\[quote\=([^\]]*)\](.*?)\[\/quote\]/ism",'',$body2); + $body2 = preg_replace("/\[quote\](.*?)\[\/quote\]/ism",'',$body2); + $body = $body1.$body2; + } + + // Add some newlines so that the message could be cut better + $body = str_replace(array("[quote", "[bookmark", "[/bookmark]", "[/quote]"), + array("\n[quote", "\n[bookmark", "[/bookmark]\n", "[/quote]\n"), $body); + + // remove the recycle signs and the names since they aren't helpful on twitter + // recycle 1 + $recycle = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8'); + $body = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', "\n", $body); + // recycle 2 (Test) + $recycle = html_entity_decode("◌ ", ENT_QUOTES, 'UTF-8'); + $body = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', "\n", $body); + + // remove the share element + //$body = preg_replace("/\[share(.*?)\](.*?)\[\/share\]/ism","\n\n$2\n\n",$body); + + // At first convert the text to html + $html = bbcode($body, false, false, 2); + + // Then convert it to plain text + //$msg = trim($b['title']." \n\n".html2plain($html, 0, true)); + $msg = trim(html2plain($html, 0, true)); + $msg = html_entity_decode($msg,ENT_QUOTES,'UTF-8'); + + // Removing multiple newlines + while (strpos($msg, "\n\n\n") !== false) + $msg = str_replace("\n\n\n", "\n\n", $msg); + + // Removing multiple spaces + while (strpos($msg, " ") !== false) + $msg = str_replace(" ", " ", $msg); + + $origmsg = $msg; + + // Removing URLs + $msg = preg_replace('/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/i', "", $msg); + + $msg = trim($msg); + + $link = ''; + // look for bookmark-bbcode and handle it with priority + if(preg_match("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/is",$b['body'],$matches)) + $link = $matches[1]; + + $multiplelinks = (strpos($b['body'], "[bookmark") != strrpos($b['body'], "[bookmark")); + + // If there is no bookmark element then take the first link + if ($link == '') { + $links = collecturls($html); + if (sizeof($links) > 0) { + reset($links); + $link = current($links); + } + $multiplelinks = (sizeof($links) > 1); + } + + $msglink = ""; + if ($multiplelinks) + $msglink = $b["plink"]; + else if ($link != "") + $msglink = $link; + else if ($multipleimages) + $msglink = $b["plink"]; + else if ($image != "") + $msglink = $image; + + if (($msglink == "") and strlen($msg) > $max_char) + $msglink = $b["plink"]; + + // If the message is short enough then don't modify it. (if the link exists in the original message) + if ((strlen(trim($origmsg)) <= $max_char) AND (strpos($origmsg, $msglink) OR ($msglink == ""))) + return(array("msg"=>trim($origmsg), "image"=>"")); + + if (strlen($msglink) > 20) + $msglink = short_link($msglink); + + if (strlen(trim($msg." ".$msglink)) > $max_char) { + $msg = substr($msg, 0, $max_char - (strlen($msglink))); + $lastchar = substr($msg, -1); + $msg = substr($msg, 0, -1); + $pos = strrpos($msg, "\n"); + if ($pos > 0) + $msg = substr($msg, 0, $pos); + else if ($lastchar != "\n") + $msg = substr($msg, 0, -3)."..."; + } + //$msg = str_replace("\n", " ", $msg); + + // Removing multiple spaces - again + while (strpos($msg, " ") !== false) + $msg = str_replace(" ", " ", $msg); + + return(array("msg"=>trim($msg."\n".$msglink), "image"=>$image)); +} + function statusnet_post_hook(&$a,&$b) { /** @@ -416,105 +584,139 @@ function statusnet_post_hook(&$a,&$b) { if(! strstr($b['postopts'],'statusnet')) return; + if($b['parent'] != $b['id']) + return; + + // if posts comes from statusnet don't send it back + if($b['app'] == "StatusNet") + return; + + logger('statusnet post invoked'); + load_pconfig($b['uid'], 'statusnet'); - + $api = get_pconfig($b['uid'], 'statusnet', 'baseapi'); - $ckey = get_pconfig($b['uid'], 'statusnet', 'consumerkey' ); - $csecret = get_pconfig($b['uid'], 'statusnet', 'consumersecret' ); - $otoken = get_pconfig($b['uid'], 'statusnet', 'oauthtoken' ); - $osecret = get_pconfig($b['uid'], 'statusnet', 'oauthsecret' ); + $ckey = get_pconfig($b['uid'], 'statusnet', 'consumerkey'); + $csecret = get_pconfig($b['uid'], 'statusnet', 'consumersecret'); + $otoken = get_pconfig($b['uid'], 'statusnet', 'oauthtoken'); + $osecret = get_pconfig($b['uid'], 'statusnet', 'oauthsecret'); + $intelligent_shortening = get_pconfig($b['uid'], 'statusnet', 'intelligent_shortening'); + + // Global setting overrides this + if (get_config('statusnet','intelligent_shortening')) + $intelligent_shortening = get_config('statusnet','intelligent_shortening'); if($ckey && $csecret && $otoken && $osecret) { require_once('include/bbcode.php'); $dent = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret); $max_char = $dent->get_maxlength(); // max. length for a dent - // we will only work with up to two times the length of the dent + // we will only work with up to two times the length of the dent // we can later send to StatusNet. This way we can "gain" some // information during shortening of potential links but do not // shorten all the links in a 200000 character long essay. - if (! $b['title']=='') { - $tmp = $b['title'].": \n".$b['body']; -// $tmp = substr($tmp, 0, 4*$max_char); - } else { - $tmp = $b['body']; // substr($b['body'], 0, 3*$max_char); - } - // if [url=bla][img]blub.png[/img][/url] get blub.png - $tmp = preg_replace( '/\[url\=(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)\]\[img\](\\w+.*?)\\[\\/img\]\\[\\/url\]/i', '$2', $tmp); - // preserve links to images, videos and audios - $tmp = preg_replace( '/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism', '$3', $tmp); - $tmp = preg_replace( '/\[\\/?img(\\s+.*?\]|\])/i', '', $tmp); - $tmp = preg_replace( '/\[\\/?video(\\s+.*?\]|\])/i', '', $tmp); - $tmp = preg_replace( '/\[\\/?youtube(\\s+.*?\]|\])/i', '', $tmp); - $tmp = preg_replace( '/\[\\/?vimeo(\\s+.*?\]|\])/i', '', $tmp); - $tmp = preg_replace( '/\[\\/?audio(\\s+.*?\]|\])/i', '', $tmp); - $linksenabled = get_pconfig($b['uid'],'statusnet','post_taglinks'); - // if a #tag is linked, don't send the [url] over to SN - // that is, don't send if the option is not set in the - // connector settings - if ($linksenabled=='0') { - // #-tags - $tmp = preg_replace( '/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$2', $tmp); - // @-mentions - $tmp = preg_replace( '/@\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '@$2', $tmp); - // recycle 1 - $recycle = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8'); - $tmp = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', $recycle.'$2', $tmp); - // recycle 2 (test) - $recycle = html_entity_decode("◌ ", ENT_QUOTES, 'UTF-8'); - $tmp = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', $recycle.'$2', $tmp); - } - // preserve links to webpages - $tmp = preg_replace( '/\[url\=(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)\](\w+.*?)\[\/url\]/i', '$2 $1', $tmp); - $tmp = preg_replace( '/\[bookmark\=(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)\](\w+.*?)\[\/bookmark\]/i', '$2 $1', $tmp); - // find all http or https links in the body of the entry and - // apply the shortener if the link is longer then 20 characters - if (( strlen($tmp)>$max_char ) && ( $max_char > 0 )) { - preg_match_all ( '/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/i', $tmp, $allurls ); - foreach ($allurls as $url) { - foreach ($url as $u) { - if (strlen($u)>20) { - $sl = short_link($u); - $tmp = str_replace( $u, $sl, $tmp ); - } - } - } - } - // ok, all the links we want to send out are save, now strip - // away the remaining bbcode - //$msg = strip_tags(bbcode($tmp, false, false)); - $msg = bbcode($tmp, false, false); - $msg = str_replace(array('
','
'),"\n",$msg); - $msg = strip_tags($msg); - - // quotes not working - let's try this - $msg = html_entity_decode($msg); - - if (( strlen($msg) > $max_char) && $max_char > 0) { - $shortlink = short_link( $b['plink'] ); - // the new message will be shortened such that "... $shortlink" - // will fit into the character limit - $msg = nl2br(substr($msg, 0, $max_char-strlen($shortlink)-4)); - $msg = str_replace(array('
','
'),' ',$msg); - $e = explode(' ', $msg); - // remove the last word from the cut down message to - // avoid sending cut words to the MicroBlog - array_pop($e); - $msg = implode(' ', $e); - $msg .= '... ' . $shortlink; - } - $msg = trim($msg); + $tempfile = ""; + $intelligent_shortening = get_config('statusnet','intelligent_shortening'); + if (!$intelligent_shortening) { + if (! $b['title']=='') { + $tmp = $b['title'].": \n".$b['body']; + // $tmp = substr($tmp, 0, 4*$max_char); + } else { + $tmp = $b['body']; // substr($b['body'], 0, 3*$max_char); + } + // if [url=bla][img]blub.png[/img][/url] get blub.png + $tmp = preg_replace( '/\[url\=(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)\]\[img\](\\w+.*?)\\[\\/img\]\\[\\/url\]/i', '$2', $tmp); + // preserve links to images, videos and audios + $tmp = preg_replace( '/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism', '$3', $tmp); + $tmp = preg_replace( '/\[\\/?img(\\s+.*?\]|\])/i', '', $tmp); + $tmp = preg_replace( '/\[\\/?video(\\s+.*?\]|\])/i', '', $tmp); + $tmp = preg_replace( '/\[\\/?youtube(\\s+.*?\]|\])/i', '', $tmp); + $tmp = preg_replace( '/\[\\/?vimeo(\\s+.*?\]|\])/i', '', $tmp); + $tmp = preg_replace( '/\[\\/?audio(\\s+.*?\]|\])/i', '', $tmp); + $linksenabled = get_pconfig($b['uid'],'statusnet','post_taglinks'); + // if a #tag is linked, don't send the [url] over to SN + // that is, don't send if the option is not set in the + // connector settings + if ($linksenabled=='0') { + // #-tags + $tmp = preg_replace( '/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$2', $tmp); + // @-mentions + $tmp = preg_replace( '/@\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '@$2', $tmp); + // recycle 1 + $recycle = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8'); + $tmp = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', $recycle.'$2', $tmp); + // recycle 2 (test) + $recycle = html_entity_decode("◌ ", ENT_QUOTES, 'UTF-8'); + $tmp = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', $recycle.'$2', $tmp); + } + // preserve links to webpages + $tmp = preg_replace( '/\[url\=(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)\](\w+.*?)\[\/url\]/i', '$2 $1', $tmp); + $tmp = preg_replace( '/\[bookmark\=(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)\](\w+.*?)\[\/bookmark\]/i', '$2 $1', $tmp); + // find all http or https links in the body of the entry and + // apply the shortener if the link is longer then 20 characters + if (( strlen($tmp)>$max_char ) && ( $max_char > 0 )) { + preg_match_all ( '/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/i', $tmp, $allurls ); + foreach ($allurls as $url) { + foreach ($url as $u) { + if (strlen($u)>20) { + $sl = short_link($u); + $tmp = str_replace( $u, $sl, $tmp ); + } + } + } + } + // ok, all the links we want to send out are save, now strip + // away the remaining bbcode + //$msg = strip_tags(bbcode($tmp, false, false)); + $msg = bbcode($tmp, false, false, true); + $msg = str_replace(array('
','
'),"\n",$msg); + $msg = strip_tags($msg); + + // quotes not working - let's try this + $msg = html_entity_decode($msg); + + if (( strlen($msg) > $max_char) && $max_char > 0) { + $shortlink = short_link( $b['plink'] ); + // the new message will be shortened such that "... $shortlink" + // will fit into the character limit + $msg = nl2br(substr($msg, 0, $max_char-strlen($shortlink)-4)); + $msg = str_replace(array('
','
'),' ',$msg); + $e = explode(' ', $msg); + // remove the last word from the cut down message to + // avoid sending cut words to the MicroBlog + array_pop($e); + $msg = implode(' ', $e); + $msg .= '... ' . $shortlink; + } + + $msg = trim($msg); + $postdata = array('status' => $msg); + } else { + $msgarr = statusnet_shortenmsg($b, $max_char); + $msg = $msgarr["msg"]; + $image = $msgarr["image"]; + if ($image != "") { + $imagedata = file_get_contents($image); + $tempfile = tempnam(get_config("system","temppath"), "upload"); + file_put_contents($tempfile, $imagedata); + $postdata = array("status"=>$msg, "media"=>"@".$tempfile); + } else + $postdata = array("status"=>$msg); + } // and now dent it :-) if(strlen($msg)) { - $result = $dent->post('statuses/update', array('status' => $msg)); + //$result = $dent->post('statuses/update', array('status' => $msg)); + $result = $dent->post('statuses/update', $postdata); logger('statusnet_post send, result: ' . print_r($result, true). - "\nmessage: ".$msg, LOGGER_DEBUG."\nOriginal post: ".print_r($b)); + "\nmessage: ".$msg, LOGGER_DEBUG."\nOriginal post: ".print_r($b, true)."\nPost Data: ".print_r($postdata, true)); if ($result->error) { logger('Send to StatusNet failed: "' . $result->error . '"'); } } + if ($tempfile != "") + unlink($tempfile); } } @@ -525,8 +727,11 @@ function statusnet_plugin_admin_post(&$a){ foreach($_POST['sitename'] as $id=>$sitename){ $sitename=trim($sitename); $apiurl=trim($_POST['apiurl'][$id]); + if (! (substr($apiurl, -1)=='/')) + $apiurl=$apiurl.'/'; $secret=trim($_POST['secret'][$id]); $key=trim($_POST['key'][$id]); + $applicationname = ((x($_POST, 'applicationname')) ? notags(trim($_POST['applicationname'][$id])):''); if ($sitename!="" && $apiurl!="" && $secret!="" && @@ -537,7 +742,8 @@ function statusnet_plugin_admin_post(&$a){ 'sitename' => $sitename, 'apiurl' => $apiurl, 'consumersecret' => $secret, - 'consumerkey' => $key + 'consumerkey' => $key, + 'applicationname' => $applicationname ); } } @@ -554,9 +760,10 @@ function statusnet_plugin_admin(&$a, &$o){ foreach($sites as $id=>$s){ $sitesform[] = Array( 'sitename' => Array("sitename[$id]", "Site name", $s['sitename'], ""), - 'apiurl' => Array("apiurl[$id]", "Api url", $s['apiurl'], ""), + 'apiurl' => Array("apiurl[$id]", "Api url", $s['apiurl'], t("Base API Path \x28remember the trailing /\x29") ), 'secret' => Array("secret[$id]", "Secret", $s['consumersecret'], ""), 'key' => Array("key[$id]", "Key", $s['consumerkey'], ""), + 'applicationname' => Array("applicationname[$id]", "Application name", $s['applicationname'], ""), 'delete' => Array("delete[$id]", "Delete", False , "Check to delete this preset"), ); } @@ -565,19 +772,135 @@ function statusnet_plugin_admin(&$a, &$o){ $id++; $sitesform[] = Array( 'sitename' => Array("sitename[$id]", t("Site name"), "", ""), - 'apiurl' => Array("apiurl[$id]", t("API URL"), "", ""), + 'apiurl' => Array("apiurl[$id]", "Api url", "", t("Base API Path \x28remember the trailing /\x29") ), 'secret' => Array("secret[$id]", t("Consumer Secret"), "", ""), 'key' => Array("key[$id]", t("Consumer Key"), "", ""), + 'applicationname' => Array("applicationname[$id]", t("Application name"), "", ""), ); - - $t = file_get_contents( dirname(__file__). "/admin.tpl" ); + $t = get_markup_template( "admin.tpl", "addon/statusnet/" ); $o = replace_macros($t, array( '$submit' => t('Submit'), - '$sites' => $sitesform, - )); - - } + +function statusnet_cron($a,$b) { + $last = get_config('statusnet','last_poll'); + + $poll_interval = intval(get_config('statusnet','poll_interval')); + if(! $poll_interval) + $poll_interval = STATUSNET_DEFAULT_POLL_INTERVAL; + + if($last) { + $next = $last + ($poll_interval * 60); + if($next > time()) { + logger('statusnet: poll intervall not reached'); + return; + } + } + logger('statusnet: cron_start'); + + $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'statusnet' AND `k` = 'mirror_posts' AND `v` = '1' ORDER BY RAND() "); + if(count($r)) { + foreach($r as $rr) { + logger('statusnet: fetching for user '.$rr['uid']); + statusnet_fetchtimeline($a, $rr['uid']); + } + } + + logger('statusnet: cron_end'); + + set_config('statusnet','last_poll', time()); +} + +function statusnet_fetchtimeline($a, $uid) { + $ckey = get_pconfig($uid, 'statusnet', 'consumerkey'); + $csecret = get_pconfig($uid, 'statusnet', 'consumersecret'); + $api = get_pconfig($uid, 'statusnet', 'baseapi'); + $otoken = get_pconfig($uid, 'statusnet', 'oauthtoken'); + $osecret = get_pconfig($uid, 'statusnet', 'oauthsecret'); + $lastid = get_pconfig($uid, 'statusnet', 'lastid'); + + // get the application name for the SN app + // 1st try personal config, then system config and fallback to the + // hostname of the node if neither one is set. + $application_name = get_pconfig( $uid, 'statusnet', 'application_name'); + if ($application_name == "") + $application_name = get_config('statusnet', 'application_name'); + if ($application_name == "") + $application_name = $a->get_hostname(); + + $connection = new StatusNetOAuth($api, $ckey,$csecret,$otoken,$osecret); + + $parameters = array("exclude_replies" => true, "trim_user" => true, "contributor_details" => false, "include_rts" => false); + + $first_time = ($lastid == ""); + + if ($lastid <> "") + $parameters["since_id"] = $lastid; + + $items = $connection->get('statuses/user_timeline', $parameters); + + if (!is_array($items)) + return; + + $posts = array_reverse($items); + + if (count($posts)) { + foreach ($posts as $post) { + if ($post->id > $lastid) + $lastid = $post->id; + + if ($first_time) + continue; + + if ($post->source == "activity") + continue; + + if (is_object($post->retweeted_status)) + continue; + + if ($post->in_reply_to_status_id != "") + continue; + + if (!strpos($post->source, $application_name)) { + $_SESSION["authenticated"] = true; + $_SESSION["uid"] = $uid; + + unset($_REQUEST); + $_REQUEST["type"] = "wall"; + $_REQUEST["api_source"] = true; + $_REQUEST["profile_uid"] = $uid; + $_REQUEST["source"] = "StatusNet"; + + //$_REQUEST["date"] = $post->created_at; + + $_REQUEST["title"] = ""; + + $_REQUEST["body"] = $post->text; + if (is_string($post->place->name)) + $_REQUEST["location"] = $post->place->name; + + if (is_string($post->place->full_name)) + $_REQUEST["location"] = $post->place->full_name; + + if (is_array($post->geo->coordinates)) + $_REQUEST["coord"] = $post->geo->coordinates[0]." ".$post->geo->coordinates[1]; + + if (is_array($post->coordinates->coordinates)) + $_REQUEST["coord"] = $post->coordinates->coordinates[1]." ".$post->coordinates->coordinates[0]; + + //print_r($_REQUEST); + if ($_REQUEST["body"] != "") { + logger('statusnet: posting for user '.$uid); + + require_once('mod/item.php'); + item_post($a); + } + } + } + } + set_pconfig($uid, 'statusnet', 'lastid', $lastid); +} +