function statusnet_post_hook(&$a, &$b) { /** * Post to GNU Social */ if (!get_pconfig($b["uid"], 'statusnet', 'import')) { if ($b['deleted'] || $b['private'] || $b['created'] !== $b['edited']) { return; } } $api = get_pconfig($b["uid"], 'statusnet', 'baseapi'); $hostname = preg_replace("=https?://([\\w\\.]*)/.*=ism", "\$1", $api); if ($b['parent'] != $b['id']) { logger("statusnet_post_hook: parameter " . print_r($b, true), LOGGER_DATA); // Looking if its a reply to a GNU Social post $hostlength = strlen($hostname) + 2; if (substr($b["parent-uri"], 0, $hostlength) != $hostname . "::" and substr($b["extid"], 0, $hostlength) != $hostname . "::" and substr($b["thr-parent"], 0, $hostlength) != $hostname . "::") { logger("statusnet_post_hook: no GNU Social post " . $b["parent"]); return; } $r = q("SELECT `item`.`author-link`, `item`.`uri`, `contact`.`nick` AS contact_nick\n\t\t\tFROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\tWHERE `item`.`uri` = '%s' AND `item`.`uid` = %d LIMIT 1", dbesc($b["thr-parent"]), intval($b["uid"])); if (!count($r)) { logger("statusnet_post_hook: no parent found " . $b["thr-parent"]); return; } else { $iscomment = true; $orig_post = $r[0]; } //$nickname = "@[url=".$orig_post["author-link"]."]".$orig_post["contact_nick"]."[/url]"; //$nicknameplain = "@".$orig_post["contact_nick"]; $nick = preg_replace("=https?://(.*)/(.*)=ism", "\$2", $orig_post["author-link"]); $nickname = "@[url=" . $orig_post["author-link"] . "]" . $nick . "[/url]"; $nicknameplain = "@" . $nick; logger("statusnet_post_hook: comparing " . $nickname . " and " . $nicknameplain . " with " . $b["body"], LOGGER_DEBUG); if (strpos($b["body"], $nickname) === false and strpos($b["body"], $nicknameplain) === false) { $b["body"] = $nickname . " " . $b["body"]; } logger("statusnet_post_hook: parent found " . print_r($orig_post, true), LOGGER_DEBUG); } else { $iscomment = false; if ($b['private'] or !strstr($b['postopts'], 'statusnet')) { return; } } if ($b['verb'] == ACTIVITY_POST and $b['deleted']) { statusnet_action($a, $b["uid"], substr($orig_post["uri"], $hostlength), "delete"); } if ($b['verb'] == ACTIVITY_LIKE) { logger("statusnet_post_hook: parameter 2 " . substr($b["thr-parent"], $hostlength), LOGGER_DEBUG); if ($b['deleted']) { statusnet_action($a, $b["uid"], substr($b["thr-parent"], $hostlength), "unlike"); } else { statusnet_action($a, $b["uid"], substr($b["thr-parent"], $hostlength), "like"); } return; } if ($b['deleted'] || $b['created'] !== $b['edited']) { return; } // if posts comes from GNU Social don't send it back if ($b['extid'] == NETWORK_STATUSNET) { return; } if ($b['app'] == "StatusNet") { return; } logger('GNU Socialpost 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'); if ($ckey && $csecret && $otoken && $osecret) { // If it's a repeated message from GNU Social then do a native retweet and exit if (statusnet_is_retweet($a, $b['uid'], $b['body'])) { return; } require_once 'include/bbcode.php'; $dent = new StatusNetOAuth($api, $ckey, $csecret, $otoken, $osecret); $max_char = $dent->get_maxlength(); // max. length for a dent set_pconfig($b['uid'], 'statusnet', 'max_char', $max_char); $tempfile = ""; require_once "include/plaintext.php"; require_once "include/network.php"; $msgarr = plaintext($a, $b, $max_char, true, 7); $msg = $msgarr["text"]; if ($msg == "" and isset($msgarr["title"])) { $msg = shortenmsg($msgarr["title"], $max_char - 50); } $image = ""; if (isset($msgarr["url"]) and $msgarr["type"] != "photo") { if (strlen($msgarr["url"]) > 20 and strlen($msg . " \n" . $msgarr["url"]) > $max_char) { $msg .= " \n" . short_link($msgarr["url"]); } else { $msg .= " \n" . $msgarr["url"]; } } elseif (isset($msgarr["image"]) and $msgarr["type"] != "video") { $image = $msgarr["image"]; } if ($image != "") { $img_str = fetch_url($image); $tempfile = tempnam(get_temppath(), "cache"); file_put_contents($tempfile, $img_str); $postdata = array("status" => $msg, "media[]" => $tempfile); } else { $postdata = array("status" => $msg); } // and now dent it :-) if (strlen($msg)) { if ($iscomment) { $postdata["in_reply_to_status_id"] = substr($orig_post["uri"], $hostlength); logger('statusnet_post send reply ' . print_r($postdata, true), LOGGER_DEBUG); } // New code that is able to post pictures require_once "addon/statusnet/codebird.php"; $cb = \CodebirdSN\CodebirdSN::getInstance(); $cb->setAPIEndpoint($api); $cb->setConsumerKey($ckey, $csecret); $cb->setToken($otoken, $osecret); $result = $cb->statuses_update($postdata); //$result = $dent->post('statuses/update', $postdata); logger('statusnet_post send, result: ' . print_r($result, true) . "\nmessage: " . $msg, LOGGER_DEBUG . "\nOriginal post: " . print_r($b, true) . "\nPost Data: " . print_r($postdata, true)); if ($result->source) { set_pconfig($b["uid"], "statusnet", "application_name", strip_tags($result->source)); } if ($result->error) { logger('Send to GNU Social failed: "' . $result->error . '"'); } elseif ($iscomment) { logger('statusnet_post: Update extid ' . $result->id . " for post id " . $b['id']); q("UPDATE `item` SET `extid` = '%s', `body` = '%s' WHERE `id` = %d", dbesc($hostname . "::" . $result->id), dbesc($result->text), intval($b['id'])); } } if ($tempfile != "") { unlink($tempfile); } } }
function statusnet_post_hook(&$a, &$b) { /** * Post to statusnet */ if (!strstr($b['postopts'], 'statusnet')) { logger('crosspost not enabled.'); return; } if (!is_item_normal($b) || $b['item_private'] || $b['created'] !== $b['edited']) { logger('not a usable post. ' . print_r($b, true), LOGGER_DEBUG); return; } if (!perm_is_allowed($b['uid'], '', 'view_stream')) { logger('permissions prevent crossposting.', LOGGER_DEBUG); return; } if ($b['parent'] != $b['id']) { logger('not a top level post.', LOGGER_DEBUG); return; } // if posts comes from statusnet don't send it back if ($b['app'] == "StatusNet") { logger('potential recursion. Crosspost ignored.'); 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'); $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 can later send to GNU social. 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); $tmp = preg_replace('/\\[zrl\\=(https?\\:\\/\\/[a-zA-Z0-9\\:\\/\\-\\?\\&\\;\\.\\=\\_\\~\\#\\%\\$\\!\\+\\,]+)\\]\\[zmg\\](\\w+.*?)\\[\\/zmg\\]\\[\\/zrl\\]/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('/\\[zmg\\=([0-9]*)x([0-9]*)\\](.*?)\\[\\/zmg\\]/ism', '$3', $tmp); $tmp = preg_replace('/\\[\\/?zmg(\\s+.*?\\]|\\])/i', '', $tmp); $tmp = preg_replace('/\\[\\/?video(\\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); // #-tags $tmp = preg_replace('/#\\[zrl\\=(\\w+.*?)\\](\\w+.*?)\\[\\/zrl\\]/i', '#$2', $tmp); // @-mentions $tmp = preg_replace('/@\\[zrl\\=(\\w+.*?)\\](\\w+.*?)\\[\\/zrl\\]/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('/\\[zrl\\=(https?\\:\\/\\/[a-zA-Z0-9\\:\\/\\-\\?\\&\\;\\.\\=\\_\\~\\#\\%\\$\\!\\+\\,]+)\\](\\w+.*?)\\[\\/zrl\\]/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 = bbcode($tmp, false, false, true); $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; } $msg = trim($msg); $postdata = array('status' => $msg); } else { $msgarr = statusnet_shortenmsg($b, $max_char); $msg = $msgarr["msg"]; $image = $msgarr["image"]; if ($image != "") { $x = z_fetch_url($image, true, 0, array('novalidate' => true)); if ($x['success']) { $imagedata = $x['body']; $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', $postdata); logger('statusnet_post send, result: ' . print_r($result, true) . "\nmessage: " . $msg, LOGGER_DEBUG); logger("Original post: " . print_r($b, true) . "\nPost Data: " . print_r($postdata, true), LOGGER_DEBUG); if ($result->error) { logger('Send to GNU social failed: queued."' . $result->error . '"'); // @fixme - unable to queue media uploads if (!$image) { queue_insert(array('hash' => random_string(), 'account_id' => $b['aid'], 'channel_id' => $b['uid'], 'driver' => 'statusnet', 'posturl' => $api, 'msg' => $msg)); } } } if ($tempfile != "") { unlink($tempfile); } } }
function statusnet_post_hook(&$a, &$b) { /** * Post to statusnet */ if ($b['deleted'] || $b['private'] || $b['created'] !== $b['edited']) { return; } if (!strstr($b['postopts'], 'statusnet')) { return; } 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'); 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 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'] . ' : ' . $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); } // 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)); // 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; } // and now dent it :-) if (strlen($msg)) { $result = $dent->post('statuses/update', array('status' => $msg)); logger('statusnet_post send, result: ' . print_r($result, true), LOGGER_DEBUG); if ($result->error) { logger('Send to StatusNet failed: "' . $result->error . '"'); } } } }