]> git.mxchange.org Git - friendica-addons.git/blobdiff - statusnet/statusnet.php
Merge remote-tracking branch 'upstream/master'
[friendica-addons.git] / statusnet / statusnet.php
index 66a1db814bd23af091e5e48867e7c32f9552ab1d..9bbe4dcd19bae6846a0827578f151d3152b83983 100755 (executable)
@@ -2,8 +2,8 @@
 /**
  * Name: StatusNet Connector
  * Description: Relay public postings to a connected StatusNet account
- * Version: 1.0.3
- * Author: Tobias Diekershoff <https://diekershoff.homeunix.net/friendika/profile/tobias>
+ * Version: 1.0.5
+ * Author: Tobias Diekershoff <http://diekershoff.homeunix.net/friendika/profile/tobias>
  */
  
 /*   StatusNet Plugin for Friendica
@@ -155,6 +155,7 @@ function statusnet_settings_post ($a,$post) {
             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');
        } else {
             if (isset($_POST['statusnet-preconf-apiurl'])) {
                 /***
@@ -218,14 +219,16 @@ function statusnet_settings_post ($a,$post) {
                                        //  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);
+                                        set_pconfig(local_user(),'statusnet', 'post', 1);
+                                        set_pconfig(local_user(),'statusnet', 'post_taglinks', 1);
                     //  reload the Addon Settings page, if we don't do it see Bug #42
                     goaway($a->get_baseurl().'/settings/connectors');
                                } 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
+                                       //  to post a dent for every new __public__ posting to the wall
                                        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_by_default',intval($_POST['statusnet-default']));
+                                        set_pconfig(local_user(),'statusnet','post_taglinks',intval($_POST['statusnet-sendtaglinks']));
                                        info( t('StatusNet settings updated.') . EOL);
                }}}}
 }
@@ -247,7 +250,9 @@ function statusnet_settings(&$a,&$s) {
        $enabled = get_pconfig(local_user(), 'statusnet', 'post');
        $checked = (($enabled) ? ' checked="checked" ' : '');
        $defenabled = get_pconfig(local_user(),'statusnet','post_by_default');
-       $defchecked = (($defenabled) ? ' checked="checked" ' : '');
+        $defchecked = (($defenabled) ? ' checked="checked" ' : '');
+        $linksenabled = get_pconfig(local_user(),'statusnet','post_taglinks');
+        $linkschecked = (($linksenabled) ? ' checked="checked" ' : '');
        $s .= '<div class="settings-block">';
        $s .= '<h3>'. t('StatusNet Posting Settings').'</h3>';
 
@@ -327,12 +332,18 @@ function statusnet_settings(&$a,&$s) {
                        $details = $connection->get('account/verify_credentials');
                        $s .= '<div id="statusnet-info" ><img id="statusnet-avatar" src="'.$details->profile_image_url.'" /><p id="statusnet-info-block">'. t('Currently connected to: ') .'<a href="'.$details->statusnet_profile_url.'" target="_statusnet">'.$details->screen_name.'</a><br /><em>'.$details->description.'</em></p></div>';
                        $s .= '<p>'. t('If enabled all your <strong>public</strong> postings can be posted to the associated StatusNet account. You can choose to do so by default (here) or for every posting separately in the posting options when writing the entry.') .'</p>';
+                        if ($a->user['hidewall']) {
+                            $s .= '<p>'. t('<strong>Note</strong>: Due your privacy settings (<em>Hide your profile details from unknown viewers?</em>) the link potentially included in public postings relayed to StatusNet will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted.') .'</p>';
+                        }
                        $s .= '<div id="statusnet-enable-wrapper">';
                        $s .= '<label id="statusnet-enable-label" for="statusnet-checkbox">'. t('Allow posting to StatusNet') .'</label>';
                        $s .= '<input id="statusnet-checkbox" type="checkbox" name="statusnet-enable" value="1" ' . $checked . '/>';
                        $s .= '<div class="clear"></div>';
                        $s .= '<label id="statusnet-default-label" for="statusnet-default">'. t('Send public postings to StatusNet by default') .'</label>';
                        $s .= '<input id="statusnet-default" type="checkbox" name="statusnet-default" value="1" ' . $defchecked . '/>';
+                       $s .= '<div class="clear"></div>';
+                        $s .= '<label id="statusnet-sendtaglinks-label" for="statusnet-sendtaglinks">'.t('Send linked #-tags and @-names to StatusNet').'</label>';
+                        $s .= '<input id="statusnet-sendtaglinks" type="checkbox" name="statusnet-sendtaglinks" value="1" '. $linkschecked . '/>';
                        $s .= '</div><div class="clear"></div>';
 
                        $s .= '<div id="statusnet-disconnect-wrapper">';
@@ -368,6 +379,135 @@ function statusnet_post_local(&$a,&$b) {
     }
 }
 
+if (! function_exists( 'short_link' )) {
+function short_link($url) {
+    require_once('library/slinky.php');
+    $slinky = new Slinky( $url );
+    $yourls_url = get_config('yourls','url1');
+    if ($yourls_url) {
+            $yourls_username = get_config('yourls','username1');
+            $yourls_password = get_config('yourls', 'password1');
+            $yourls_ssl = get_config('yourls', 'ssl1');
+            $yourls = new Slinky_YourLS();
+            $yourls->set( 'username', $yourls_username );
+            $yourls->set( 'password', $yourls_password );
+            $yourls->set( 'ssl', $yourls_ssl );
+            $yourls->set( 'yourls-url', $yourls_url );
+            $slinky->set_cascade( array( $yourls, new Slinky_UR1ca(), new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) );
+    }
+    else {
+            // 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() ) );
+    }
+    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;
+
+       // remove the recycle signs and the names since they aren't helpful on twitter
+       // recycle 1
+       $recycle = html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
+       $body = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', "\n", $body);
+       // recycle 2 (Test)
+       $recycle = html_entity_decode("&#x25CC; ", ENT_QUOTES, 'UTF-8');
+       $body = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', "\n", $body);
+
+       // At first convert the text to html
+       $html = bbcode($body, false, false);
+
+       // 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);
+
+       // 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 (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." ".$msglink), "image"=>$image));
+}
+
 function statusnet_post_hook(&$a,&$b) {
 
        /**
@@ -390,64 +530,115 @@ function statusnet_post_hook(&$a,&$b) {
 
        if($ckey && $csecret && $otoken && $osecret) {
 
-               require_once('include/bbcode.php');     
+               require_once('include/bbcode.php');
                $dent = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret);
-               $max_char = $dent->get_maxlength(); // max. length for a dent
-                $tmp = $b['body'];
-                // 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);
-                logger($tmp);
-//                $tmp = preg_replace( '/\[url\=(\w+.*?)\]\[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);
-                // if a #tag is linked, don't send the [url] over to SN
-                //   this is commented out by default as it means backlinks
-                //   to friendica, if you don't like this feel free to
-                //   uncomment the following line
-//                $tmp = preg_replace( '/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$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);
-                // TODO apply the shortener to the URLs in the releyed dent
-               $msg = strip_tags(bbcode($tmp));
-               // quotes not working - let's try this
-               $msg = html_entity_decode($msg);
-               if (( strlen($msg) > $max_char) && $max_char > 0) {
-                       $shortlink = "";
-                       require_once('library/slinky.php');
-                       $slinky = new Slinky( $b['plink'] );
-                       $yourls_url = get_config('yourls','url1');
-                       if ($yourls_url) {
-                               $yourls_username = get_config('yourls','username1');
-                               $yourls_password = get_config('yourls', 'password1');
-                               $yourls_ssl = get_config('yourls', 'ssl1');
-                               $yourls = new Slinky_YourLS();
-                               $yourls->set( 'username', $yourls_username );
-                               $yourls->set( 'password', $yourls_password );
-                               $yourls->set( 'ssl', $yourls_ssl );
-                               $yourls->set( 'yourls-url', $yourls_url );
-                               $slinky->set_cascade( array( $yourls, new Slinky_UR1ca(), new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) );
+                $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 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.
+
+               $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("&#x2672; ", ENT_QUOTES, 'UTF-8');
+                               $tmp = preg_replace( '/'.$recycle.'\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', $recycle.'$2', $tmp);
+                               // recycle 2 (test)
+                               $recycle = html_entity_decode("&#x25CC; ", 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('<br>','<br />'),"\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('<br>','<br />'),' ',$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;
                        }
-                       else {
-                               // 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;
+
+                       $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("", "upload");
+                               file_put_contents($tempfile, $imagedata);
+                               $postdata = array("status"=>$msg, "media"=>"@".$tempfile);
+                       } else
+                               $postdata = array("status"=>$msg);
                }
-               // and now tweet it :-)
-               if(strlen($msg))
-                       $dent->post('statuses/update', array('status' => $msg));
+
+               // and now dent it :-)
+               if(strlen($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)."\nPost Data: ".print_r($postdata));
+                    if ($result->error) {
+                        logger('Send to StatusNet failed: "' . $result->error . '"');
+                    }
+                }
+               if ($tempfile != "")
+                       unlink($tempfile);
        }
 }