function share_init(&$a) { $post_id = $a->argc > 1 ? intval($a->argv[1]) : 0; if (!$post_id || !local_user()) { killme(); } $r = q("SELECT item.*, contact.network FROM `item` \n\t\tinner join contact on `item`.`contact-id` = `contact`.`id` \n\t\tWHERE `item`.`id` = %d AND `item`.`uid` = %d LIMIT 1", intval($post_id), intval(local_user())); if (!count($r) || $r[0]['private'] == 1) { killme(); } if (!intval(get_config('system', 'old_share'))) { if (strpos($r[0]['body'], "[/share]") !== false) { $pos = strpos($r[0]['body'], "[share"); $o = substr($r[0]['body'], $pos); } else { $o = share_header($r[0]['author-name'], $r[0]['author-link'], $r[0]['author-avatar'], $r[0]['guid'], $r[0]['created'], $r[0]['plink']); if ($r[0]['title']) { $o .= '[b]' . $r[0]['title'] . '[/b]' . "\n"; } $o .= $r[0]['body']; $o .= "[/share]"; } } else { $o = ''; $o .= "♲" . ' [url=' . $r[0]['author-link'] . ']' . $r[0]['author-name'] . '[/url]' . "\n"; if ($r[0]['title']) { $o .= '[b]' . $r[0]['title'] . '[/b]' . "\n"; } $o .= $r[0]['body'] . "\n"; $o .= $r[0]['plink'] ? '[url=' . $r[0]['plink'] . ']' . t('link') . '[/url]' . "\n" : ''; } echo $o; killme(); }
function diaspora_reshare($importer, $xml, $msg) { logger('diaspora_reshare: init: ' . print_r($xml, true)); $a = get_app(); $guid = notags(unxmlify($xml->guid)); $diaspora_handle = notags(unxmlify($xml->diaspora_handle)); if ($diaspora_handle != $msg['author']) { logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.'); return 202; } $contact = diaspora_get_contact_by_handle($importer['uid'], $diaspora_handle); if (!$contact) { return; } if (!diaspora_post_allow($importer, $contact, false)) { logger('diaspora_reshare: Ignoring this author: ' . $diaspora_handle . ' ' . print_r($xml, true)); return 202; } $message_id = $diaspora_handle . ':' . $guid; $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1", intval($importer['uid']), dbesc($guid)); if (count($r)) { logger('diaspora_reshare: message exists: ' . $guid); return; } $orig_author = notags(unxmlify($xml->root_diaspora_id)); $orig_guid = notags(unxmlify($xml->root_guid)); $orig_url = $a->get_baseurl() . "/display/" . $orig_guid; $create_original_post = false; // Do we already have this item? $r = q("SELECT `body`, `tag`, `app`, `created`, `plink`, `object`, `object-type`, `uri` FROM `item` WHERE `guid` = '%s' AND `visible` AND NOT `deleted` AND `body` != '' LIMIT 1", dbesc($orig_guid), dbesc(NETWORK_DIASPORA)); if (count($r)) { logger('reshared message ' . $orig_guid . " reshared by " . $guid . ' already exists on system.'); // Maybe it is already a reshared item? // Then refetch the content, since there can be many side effects with reshared posts from other networks or reshares from reshares require_once 'include/api.php'; if (api_share_as_retweet($r[0])) { $r = array(); } else { $body = $r[0]["body"]; $str_tags = $r[0]["tag"]; $app = $r[0]["app"]; $orig_created = $r[0]["created"]; $orig_plink = $r[0]["plink"]; $orig_uri = $r[0]["uri"]; $object = $r[0]["object"]; $objecttype = $r[0]["object-type"]; } } if (!count($r)) { $body = ""; $str_tags = ""; $app = ""; $server = 'https://' . substr($orig_author, strpos($orig_author, '@') + 1); logger('1st try: reshared message ' . $orig_guid . " reshared by " . $guid . ' will be fetched from original server: ' . $server); $item = diaspora_fetch_message($orig_guid, $server); if (!$item) { $server = 'https://' . substr($diaspora_handle, strpos($diaspora_handle, '@') + 1); logger('2nd try: reshared message ' . $orig_guid . " reshared by " . $guid . " will be fetched from sharer's server: " . $server); $item = diaspora_fetch_message($orig_guid, $server); } if (!$item) { $server = 'http://' . substr($orig_author, strpos($orig_author, '@') + 1); logger('3rd try: reshared message ' . $orig_guid . " reshared by " . $guid . ' will be fetched from original server: ' . $server); $item = diaspora_fetch_message($orig_guid, $server); } if (!$item) { $server = 'http://' . substr($diaspora_handle, strpos($diaspora_handle, '@') + 1); logger('4th try: reshared message ' . $orig_guid . " reshared by " . $guid . " will be fetched from sharer's server: " . $server); $item = diaspora_fetch_message($orig_guid, $server); } if ($item) { $body = $item["body"]; $str_tags = $item["tag"]; $app = $item["app"]; $orig_created = $item["created"]; $orig_author = $item["author"]; $orig_guid = $item["guid"]; $orig_plink = diaspora_plink($orig_author, $orig_guid); $orig_uri = $orig_author . ':' . $orig_guid; $create_original_post = $body != ""; $object = $item["object"]; $objecttype = $item["object-type"]; } } $plink = diaspora_plink($diaspora_handle, $guid); $person = find_diaspora_person_by_handle($orig_author); $created = unxmlify($xml->created_at); $private = unxmlify($xml->public) == 'false' ? 1 : 0; $datarray = array(); $datarray['uid'] = $importer['uid']; $datarray['contact-id'] = $contact['id']; $datarray['wall'] = 0; $datarray['network'] = NETWORK_DIASPORA; $datarray['guid'] = $guid; $datarray['uri'] = $datarray['parent-uri'] = $message_id; $datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert('UTC', 'UTC', $created); $datarray['private'] = $private; $datarray['parent'] = 0; $datarray['plink'] = $plink; $datarray['owner-name'] = $contact['name']; $datarray['owner-link'] = $contact['url']; $datarray['owner-avatar'] = x($contact, 'thumb') ? $contact['thumb'] : $contact['photo']; if (!intval(get_config('system', 'wall-to-wall_share'))) { $prefix = share_header($person['name'], $person['url'], x($person, 'thumb') ? $person['thumb'] : $person['photo'], $orig_guid, $orig_created, $orig_url); $datarray['author-name'] = $contact['name']; $datarray['author-link'] = $contact['url']; $datarray['author-avatar'] = $contact['thumb']; $datarray['body'] = $prefix . $body . "[/share]"; } else { // Let reshared messages look like wall-to-wall posts $datarray['author-name'] = $person['name']; $datarray['author-link'] = $person['url']; $datarray['author-avatar'] = x($person, 'thumb') ? $person['thumb'] : $person['photo']; $datarray['body'] = $body; } $datarray["object"] = json_encode($xml); $datarray['object-type'] = $objecttype; $datarray['tag'] = $str_tags; $datarray['app'] = $app; // if empty content it might be a photo that hasn't arrived yet. If a photo arrives, we'll make it visible. (testing) $datarray['visible'] = strlen($body) ? 1 : 0; // Store the original item of a reshare if ($create_original_post) { require_once "include/Contact.php"; $datarray2 = $datarray; $datarray2['uid'] = 0; $datarray2['contact-id'] = get_contact($person['url'], 0); $datarray2['guid'] = $orig_guid; $datarray2['uri'] = $datarray2['parent-uri'] = $orig_uri; $datarray2['changed'] = $datarray2['created'] = $datarray2['edited'] = $datarray2['commented'] = $datarray2['received'] = datetime_convert('UTC', 'UTC', $orig_created); $datarray2['parent'] = 0; $datarray2['plink'] = $orig_plink; $datarray2['author-name'] = $person['name']; $datarray2['author-link'] = $person['url']; $datarray2['author-avatar'] = x($person, 'thumb') ? $person['thumb'] : $person['photo']; $datarray2['owner-name'] = $datarray2['author-name']; $datarray2['owner-link'] = $datarray2['author-link']; $datarray2['owner-avatar'] = $datarray2['author-avatar']; $datarray2['body'] = $body; $datarray2["object"] = $object; DiasporaFetchGuid($datarray2); $message_id = item_store($datarray2); logger("Store original item " . $orig_guid . " under message id " . $message_id); } DiasporaFetchGuid($datarray); $message_id = item_store($datarray); return; }
/** * */ function api_statuses_repeat(&$a, $type) { global $called_api; if (api_user() === false) { return false; } $user_info = api_get_user($a); // params $id = intval($a->argv[3]); if ($id == 0) { $id = intval($_REQUEST["id"]); } // Hotot workaround if ($id == 0) { $id = intval($a->argv[4]); } logger('API: api_statuses_repeat: ' . $id); $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`, `contact`.`nick` as `reply_author`,\n\t\t\t`contact`.`name`, `contact`.`photo` as `reply_photo`, `contact`.`url` as `reply_url`, `contact`.`rel`,\n\t\t\t`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,\n\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item`, `contact`\n\t\t\tWHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0\n\t\t\tAND `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t{$sql_extra}\n\t\t\tAND `item`.`id`=%d", intval($id)); if ($r[0]['body'] != "") { if (!intval(get_config('system', 'old_share'))) { if (strpos($r[0]['body'], "[/share]") !== false) { $pos = strpos($r[0]['body'], "[share"); $post = substr($r[0]['body'], $pos); } else { $post = share_header($r[0]['author-name'], $r[0]['author-link'], $r[0]['author-avatar'], $r[0]['guid'], $r[0]['created'], $r[0]['plink']); $post .= $r[0]['body']; $post .= "[/share]"; } $_REQUEST['body'] = $post; } else { $_REQUEST['body'] = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . "[url=" . $r[0]['reply_url'] . "]" . $r[0]['reply_author'] . "[/url] \n" . $r[0]['body']; } $_REQUEST['profile_uid'] = api_user(); $_REQUEST['type'] = 'wall'; $_REQUEST['api_source'] = true; if (!x($_REQUEST, "source")) { $_REQUEST["source"] = api_source(); } item_post($a); } // this should output the last post (the one we just posted). $called_api = null; return api_status_show($a, $type); }
function get_atom_elements($feed, $item, $contact = array()) { require_once 'library/HTMLPurifier.auto.php'; require_once 'include/html2bbcode.php'; $best_photo = array(); $res = array(); $author = $item->get_author(); if ($author) { $res['author-name'] = unxmlify($author->get_name()); $res['author-link'] = unxmlify($author->get_link()); } else { $res['author-name'] = unxmlify($feed->get_title()); $res['author-link'] = unxmlify($feed->get_permalink()); } $res['uri'] = unxmlify($item->get_id()); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $res['plink'] = unxmlify($item->get_link(0)); if (isset($contact["network"]) and $contact["network"] == NETWORK_FEED and strstr($res['plink'], ".app.net/")) { logger("get_atom_elements: detected app.net posting: " . print_r($res, true), LOGGER_DEBUG); $res['title'] = ""; $res['body'] = nl2br($res['body']); } // removing the content of the title if its identically to the body // This helps with auto generated titles e.g. from tumblr if (title_is_body($res["title"], $res["body"])) { $res['title'] = ""; } if ($res['plink']) { $base_url = implode('/', array_slice(explode('/', $res['plink']), 0, 3)); } else { $base_url = ''; } // look for a photo. We should check media size and find the best one, // but for now let's just find any author photo // Additionally we look for an alternate author link. On OStatus this one is the one we want. $authorlinks = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"]["http://www.w3.org/2005/Atom"]["link"]; if (is_array($authorlinks)) { foreach ($authorlinks as $link) { $linkdata = array_shift($link["attribs"]); if ($linkdata["rel"] == "alternate") { $res["author-link"] = $linkdata["href"]; } } } $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate') { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar') || !$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); if ($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'], ACTIVITY_OBJ_PERSON)) { $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; if ($base && count($base)) { foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar') || !$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } } // No photo/profile-link on the item - look at the feed level if (!x($res, 'author-link') || !x($res, 'author-avatar')) { $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); if ($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'], ACTIVITY_OBJ_PERSON)) { $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; if ($base && count($base)) { foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar')) { if ($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } } } $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if ($apps && $apps[0]['attribs']['']['source']) { $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); if ($res['app'] === 'web') { $res['app'] = 'OStatus'; } } // base64 encoded json structure representing Diaspora signature $dsig = $item->get_item_tags(NAMESPACE_DFRN, 'diaspora_signature'); if ($dsig) { $res['dsprsig'] = unxmlify($dsig[0]['data']); } $dguid = $item->get_item_tags(NAMESPACE_DFRN, 'diaspora_guid'); if ($dguid) { $res['guid'] = unxmlify($dguid[0]['data']); } $bm = $item->get_item_tags(NAMESPACE_DFRN, 'bookmark'); if ($bm) { $res['bookmark'] = unxmlify($bm[0]['data']) === 'true' ? 1 : 0; } /** * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. */ $have_real_body = false; $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); if ($rawenv) { $have_real_body = true; $res['body'] = $rawenv[0]['data']; $res['body'] = str_replace(array(' ', "\t", "\r", "\n"), array('', '', '', ''), $res['body']); // make sure nobody is trying to sneak some html tags by us $res['body'] = notags(base64url_decode($res['body'])); } $res['body'] = limit_body_size($res['body']); // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust // the content type. Our own network only emits text normally, though it might have been converted to // html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will // have to assume it is all html and needs to be purified. // It doesn't matter all that much security wise - because before this content is used anywhere, we are // going to escape any tags we find regardless, but this lets us import a limited subset of html from // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining // html. if (strpos($res['body'], '<') !== false && strpos($res['body'], '>') !== false) { $res['body'] = reltoabs($res['body'], $base_url); $res['body'] = html2bb_video($res['body']); $res['body'] = oembed_html2bbcode($res['body']); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); // we shouldn't need a whitelist, because the bbcode converter // will strip out any unsupported tags. $purifier = new HTMLPurifier($config); $res['body'] = $purifier->purify($res['body']); $res['body'] = @html2bbcode($res['body']); } elseif (!$have_real_body) { // it's not one of our messages and it has no tags // so it's probably just text. We'll escape it just to be safe. $res['body'] = escape_tags($res['body']); } // this tag is obsolete but we keep it for really old sites $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] == 1) { $res['last-child'] = 1; } else { $res['last-child'] = 0; } $private = $item->get_item_tags(NAMESPACE_DFRN, 'private'); if ($private && intval($private[0]['data']) > 0) { $res['private'] = intval($private[0]['data']); } else { $res['private'] = 0; } $extid = $item->get_item_tags(NAMESPACE_DFRN, 'extid'); if ($extid && $extid[0]['data']) { $res['extid'] = $extid[0]['data']; } $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location'); if ($rawlocation) { $res['location'] = unxmlify($rawlocation[0]['data']); } $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); if ($rawcreated) { $res['created'] = unxmlify($rawcreated[0]['data']); } $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'); if ($rawedited) { $res['edited'] = unxmlify($rawedited[0]['data']); } if (x($res, 'edited') && !x($res, 'created')) { $res['created'] = $res['edited']; } if (!$res['created']) { $res['created'] = $item->get_date('c'); } if (!$res['edited']) { $res['edited'] = $item->get_date('c'); } // Disallow time travelling posts $d1 = strtotime($res['created']); $d2 = strtotime($res['edited']); $d3 = strtotime('now'); if ($d1 > $d3) { $res['created'] = datetime_convert(); } if ($d2 > $d3) { $res['edited'] = datetime_convert(); } $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if (!x($res, 'owner-avatar') || !$res['owner-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['owner-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS, 'point'); if ($rawgeo) { $res['coord'] = unxmlify($rawgeo[0]['data']); } if ($contact["network"] == NETWORK_FEED) { $res['verb'] = ACTIVITY_POST; $res['object-type'] = ACTIVITY_OBJ_NOTE; } $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); // select between supported verbs if ($rawverb) { $res['verb'] = unxmlify($rawverb[0]['data']); } // translate OStatus unfollow to activity streams if it happened to get selected if (x($res, 'verb') && $res['verb'] === 'http://ostatus.org/schema/1.0/unfollow') { $res['verb'] = ACTIVITY_UNFOLLOW; } $cats = $item->get_categories(); if ($cats) { $tag_arr = array(); foreach ($cats as $cat) { $term = $cat->get_term(); if (!$term) { $term = $cat->get_label(); } $scheme = $cat->get_scheme(); if ($scheme && $term && stristr($scheme, 'X-DFRN:')) { $tag_arr[] = substr($scheme, 7, 1) . '[url=' . unxmlify(substr($scheme, 9)) . ']' . unxmlify($term) . '[/url]'; } elseif ($term) { $tag_arr[] = notags(trim($term)); } } $res['tag'] = implode(',', $tag_arr); } $attach = $item->get_enclosures(); if ($attach) { $att_arr = array(); foreach ($attach as $att) { $len = intval($att->get_length()); $link = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_link())))); $title = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_title())))); $type = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_type())))); if (strpos($type, ';')) { $type = substr($type, 0, strpos($type, ';')); } if (!$link || strpos($link, 'http') !== 0) { continue; } if (!$title) { $title = ' '; } if (!$type) { $type = 'application/octet-stream'; } $att_arr[] = '[attach]href="' . $link . '" length="' . $len . '" type="' . $type . '" title="' . $title . '"[/attach]'; } $res['attach'] = implode(',', $att_arr); } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); if ($rawobj) { $res['object'] = '<object>' . "\n"; $child = $rawobj[0]['child']; if ($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; $res['object'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) { $res['object'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $res['object'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) { $res['object'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; if (!$body) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; } // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if (strpos($body, '<') !== false || strpos($body, '>') !== false) { $body = html2bb_video($body); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); $body = $purifier->purify($body); $body = html2bbcode($body); } $res['object'] .= '<content>' . $body . '</content>' . "\n"; } $res['object'] .= '</object>' . "\n"; } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target'); if ($rawobj) { $res['target'] = '<target>' . "\n"; $child = $rawobj[0]['child']; if ($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['target'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) { $res['target'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $res['target'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) { $res['target'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; if (!$body) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; } // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['target'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if (strpos($body, '<') !== false || strpos($body, '>') !== false) { $body = html2bb_video($body); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); $body = $purifier->purify($body); $body = html2bbcode($body); } $res['target'] .= '<content>' . $body . '</content>' . "\n"; } $res['target'] .= '</target>' . "\n"; } // This is some experimental stuff. By now retweets are shown with "RT:" // But: There is data so that the message could be shown similar to native retweets // There is some better way to parse this array - but it didn't worked for me. $child = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["entry"][0]["child"]["http://activitystrea.ms/spec/1.0/"][object][0]["child"]; if (is_array($child)) { logger('get_atom_elements: Looking for status.net repeated message'); $message = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["content"][0]["data"]; $orig_id = ostatus_convert_href($child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["id"][0]["data"]); $author = $child[SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]; $uri = $author["uri"][0]["data"]; $name = $author["name"][0]["data"]; $avatar = @array_shift($author["link"][2]["attribs"]); $avatar = $avatar["href"]; if ($name != "" and $uri != "" and $avatar != "" and $message != "") { logger('get_atom_elements: fixing sender of repeated message. ' . $orig_id, LOGGER_DEBUG); if (!intval(get_config('system', 'wall-to-wall_share'))) { $prefix = share_header($name, $uri, $avatar, "", "", $orig_link); $res["body"] = $prefix . html2bbcode($message) . "[/share]"; } else { $res["owner-name"] = $res["author-name"]; $res["owner-link"] = $res["author-link"]; $res["owner-avatar"] = $res["author-avatar"]; $res["author-name"] = $name; $res["author-link"] = $uri; $res["author-avatar"] = $avatar; $res["body"] = html2bbcode($message); } } } if (isset($contact["network"]) and $contact["network"] == NETWORK_FEED and $contact['fetch_further_information']) { $preview = ""; // Handle enclosures and treat them as preview picture if (isset($attach)) { foreach ($attach as $attachment) { if ($attachment->type == "image/jpeg") { $preview = $attachment->link; } } } $res["body"] = $res["title"] . add_page_info($res['plink'], false, $preview, $contact['fetch_further_information'] == 2, $contact['ffi_keyword_blacklist']); $res["tag"] = add_page_keywords($res['plink'], false, $preview, $contact['fetch_further_information'] == 2, $contact['ffi_keyword_blacklist']); $res["title"] = ""; $res["object-type"] = ACTIVITY_OBJ_BOOKMARK; unset($res["attach"]); } elseif (isset($contact["network"]) and $contact["network"] == NETWORK_OSTATUS) { $res["body"] = add_page_info_to_body($res["body"]); } elseif (isset($contact["network"]) and $contact["network"] == NETWORK_FEED and strstr($res['plink'], ".app.net/")) { $res["body"] = add_page_info_to_body($res["body"]); } $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); call_hooks('parse_atom', $arr); return $res; }
function fromgplus_fetch($a, $uid) { $maxfetch = 20; // Special blank to identify postings from the googleplus connector $blank = html_entity_decode(" ", ENT_QUOTES, 'UTF-8'); $account = get_pconfig($uid, 'fromgplus', 'account'); $key = get_config('fromgplus', 'key'); $result = fetch_url("https://www.googleapis.com/plus/v1/people/" . $account . "/activities/public?alt=json&pp=1&key=" . $key . "&maxResults=" . $maxfetch); //$result = file_get_contents("google.txt"); //file_put_contents("google.txt", $result); $activities = json_decode($result); $initiallastdate = get_pconfig($uid, 'fromgplus', 'lastdate'); $first_time = $initiallastdate == ""; $lastdate = 0; if (!is_array($activities->items)) { return; } $reversed = array_reverse($activities->items); foreach ($reversed as $item) { if (strtotime($item->published) <= $initiallastdate) { continue; } // Don't publish items that are too young if (strtotime($item->published) > time() - 3 * 60) { logger('fromgplus_fetch: item too new ' . $item->published); continue; } if ($lastdate < strtotime($item->published)) { $lastdate = strtotime($item->published); } if ($first_time) { continue; } if ($item->access->description == "Public") { // Loop prevention through the special blank from the googleplus connector //if (strstr($item->object->content, $blank)) if (strrpos($item->object->content, $blank) >= strlen($item->object->content) - 5) { continue; } switch ($item->object->objectType) { case "note": $post = fromgplus_html2bbcode($item->object->content); if (is_array($item->object->attachments)) { $post .= fromgplus_handleattachments($a, $uid, $item, $item->object->content, false); } $coord = ""; $location = ""; if (isset($item->location)) { if (isset($item->location->address->formatted)) { $location = $item->location->address->formatted; } if (isset($item->location->displayName)) { $location = $item->location->displayName; } if (isset($item->location->position->latitude) and isset($item->location->position->longitude)) { $coord = $item->location->position->latitude . " " . $item->location->position->longitude; } } elseif (isset($item->address)) { $location = $item->address; } fromgplus_post($a, $uid, $item->provider->title, $post, $location, $coord); break; case "activity": $post = fromgplus_html2bbcode($item->annotation) . "\n"; if (!intval(get_config('system', 'old_share'))) { if (function_exists("share_header")) { $post .= share_header($item->object->actor->displayName, $item->object->actor->url, $item->object->actor->image->url, "", datetime_convert('UTC', 'UTC', $item->object->published), $item->object->url); } else { $post .= "[share author='" . str_replace("'", "'", $item->object->actor->displayName) . "' profile='" . $item->object->actor->url . "' avatar='" . $item->object->actor->image->url . "' posted='" . datetime_convert('UTC', 'UTC', $item->object->published) . "' link='" . $item->object->url . "']"; } $post .= fromgplus_html2bbcode($item->object->content); if (is_array($item->object->attachments)) { $post .= "\n" . trim(fromgplus_handleattachments($a, $uid, $item, $item->object->content, true)); } $post .= "[/share]"; } else { $post .= fromgplus_html2bbcode("♲"); $post .= " [url=" . $item->object->actor->url . "]" . $item->object->actor->displayName . "[/url] \n"; $post .= fromgplus_html2bbcode($item->object->content); if (is_array($item->object->attachments)) { $post .= "\n" . trim(fromgplus_handleattachments($a, $uid, $item, $item->object->content, true)); } } $coord = ""; $location = ""; if (isset($item->location)) { if (isset($item->location->address->formatted)) { $location = $item->location->address->formatted; } if (isset($item->location->displayName)) { $location = $item->location->displayName; } if (isset($item->location->position->latitude) and isset($item->location->position->longitude)) { $coord = $item->location->position->latitude . " " . $item->location->position->longitude; } } elseif (isset($item->address)) { $location = $item->address; } fromgplus_post($a, $uid, $item->provider->title, $post, $location, $coord); break; } } } if ($lastdate != 0) { set_pconfig($uid, 'fromgplus', 'lastdate', $lastdate); } }
function twitter_fetchtimeline($a, $uid) { $ckey = get_config('twitter', 'consumerkey'); $csecret = get_config('twitter', 'consumersecret'); $otoken = get_pconfig($uid, 'twitter', 'oauthtoken'); $osecret = get_pconfig($uid, 'twitter', 'oauthsecret'); $lastid = get_pconfig($uid, 'twitter', 'lastid'); $application_name = get_config('twitter', 'application_name'); if ($application_name == "") { $application_name = $a->get_hostname(); } $has_picture = false; require_once 'mod/item.php'; require_once 'include/items.php'; require_once 'mod/share.php'; require_once 'library/twitteroauth.php'; $connection = new TwitterOAuth($ckey, $csecret, $otoken, $osecret); $parameters = array("exclude_replies" => true, "trim_user" => false, "contributor_details" => true, "include_rts" => true); $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_str > $lastid) { $lastid = $post->id_str; set_pconfig($uid, 'twitter', 'lastid', $lastid); } if ($first_time) { continue; } if (!stristr($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"] = "Twitter"; $_REQUEST["source"] = $post->source; $_REQUEST["extid"] = NETWORK_TWITTER; //$_REQUEST["date"] = $post->created_at; $_REQUEST["title"] = ""; if (is_object($post->retweeted_status)) { $_REQUEST['body'] = $post->retweeted_status->text; $picture = ""; // media if (is_array($post->retweeted_status->entities->media)) { foreach ($post->retweeted_status->entities->media as $media) { switch ($media->type) { case 'photo': //$_REQUEST['body'] = str_replace($media->url, "\n\n[img]".$media->media_url_https."[/img]\n", $_REQUEST['body']); //$has_picture = true; $_REQUEST['body'] = str_replace($media->url, "", $_REQUEST['body']); $picture = $media->media_url_https; break; } } } $converted = twitter_expand_entities($a, $_REQUEST['body'], $post->retweeted_status, true, $picture); $_REQUEST['body'] = $converted["body"]; if (function_exists("share_header")) { $_REQUEST['body'] = share_header($post->retweeted_status->user->name, "https://twitter.com/" . $post->retweeted_status->user->screen_name, $post->retweeted_status->user->profile_image_url_https, "", datetime_convert('UTC', 'UTC', $post->retweeted_status->created_at), "https://twitter.com/" . $post->retweeted_status->user->screen_name . "/status/" . $post->retweeted_status->id_str) . $_REQUEST['body']; } else { $_REQUEST['body'] = "[share author='" . $post->retweeted_status->user->name . "' profile='https://twitter.com/" . $post->retweeted_status->user->screen_name . "' avatar='" . $post->retweeted_status->user->profile_image_url_https . "' posted='" . datetime_convert('UTC', 'UTC', $post->retweeted_status->created_at) . "' link='https://twitter.com/" . $post->retweeted_status->user->screen_name . "/status/" . $post->retweeted_status->id_str . "']" . $_REQUEST['body']; } $_REQUEST['body'] .= "[/share]"; } else { $_REQUEST["body"] = $post->text; $picture = ""; if (is_array($post->entities->media)) { foreach ($post->entities->media as $media) { switch ($media->type) { case 'photo': //$_REQUEST['body'] = str_replace($media->url, "\n\n[img]".$media->media_url_https."[/img]\n", $_REQUEST['body']); //$has_picture = true; $_REQUEST['body'] = str_replace($media->url, "", $_REQUEST['body']); $picture = $media->media_url_https; break; } } } $converted = twitter_expand_entities($a, $_REQUEST["body"], $post, true, $picture); $_REQUEST['body'] = $converted["body"]; } 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); logger('twitter: posting for user ' . $uid); // require_once('mod/item.php'); item_post($a); } } } set_pconfig($uid, 'twitter', 'lastid', $lastid); }
function pumpio_dopost(&$a, $client, $uid, $self, $post, $own_id, $threadcompletion = true) { require_once 'include/items.php'; require_once 'include/html2bbcode.php'; if ($post->verb == "like" or $post->verb == "favorite") { return pumpio_dolike($a, $uid, $self, $post, $own_id); } if ($post->verb == "unlike" or $post->verb == "unfavorite") { return pumpio_dounlike($a, $uid, $self, $post, $own_id); } if ($post->verb == "delete") { return pumpio_dodelete($a, $uid, $self, $post, $own_id); } if ($post->verb != "update") { // Two queries for speed issues $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($post->object->id), intval($uid)); if (count($r)) { return false; } $r = q("SELECT * FROM `item` WHERE `extid` = '%s' AND `uid` = %d LIMIT 1", dbesc($post->object->id), intval($uid)); if (count($r)) { return false; } } // Only handle these three types if (!strstr("post|share|update", $post->verb)) { return false; } $receiptians = array(); if (@is_array($post->cc)) { $receiptians = array_merge($receiptians, $post->cc); } if (@is_array($post->to)) { $receiptians = array_merge($receiptians, $post->to); } foreach ($receiptians as $receiver) { if (is_string($receiver->objectType)) { if ($receiver->id == "http://activityschema.org/collection/public") { $public = true; } } } $postarray = array(); $postarray['network'] = NETWORK_PUMPIO; $postarray['gravity'] = 0; $postarray['uid'] = $uid; $postarray['wall'] = 0; $postarray['uri'] = $post->object->id; $postarray['object-type'] = NAMESPACE_ACTIVITY_SCHEMA . strtolower($post->object->objectType); if ($post->object->objectType != "comment") { $contact_id = pumpio_get_contact($uid, $post->actor); if (!$contact_id) { $contact_id = $self[0]['id']; } $postarray['parent-uri'] = $post->object->id; if (!$public) { $postarray['private'] = 1; $postarray['allow_cid'] = '<' . $self[0]['id'] . '>'; } } else { $contact_id = pumpio_get_contact($uid, $post->actor, true); if (link_compare($post->actor->url, $own_id)) { $contact_id = $self[0]['id']; $post->actor->displayName = $self[0]['name']; $post->actor->url = $self[0]['url']; $post->actor->image->url = $self[0]['photo']; } elseif ($contact_id == 0) { // Take an existing contact, the contact of the note or - as a fallback - the id of the user $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1", dbesc($post->actor->url), intval($uid)); if (count($r)) { $contact_id = $r[0]['id']; } else { $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1", dbesc($post->actor->url), intval($uid)); if (count($r)) { $contact_id = $r[0]['id']; } else { $contact_id = $self[0]['id']; } } } $reply = new stdClass(); $reply->verb = "note"; $reply->cc = $post->cc; $reply->to = $post->to; $reply->object = new stdClass(); $reply->object->objectType = $post->object->inReplyTo->objectType; $reply->object->content = $post->object->inReplyTo->content; $reply->object->id = $post->object->inReplyTo->id; $reply->actor = $post->object->inReplyTo->author; $reply->url = $post->object->inReplyTo->url; $reply->generator = new stdClass(); $reply->generator->displayName = "pumpio"; $reply->published = $post->object->inReplyTo->published; $reply->received = $post->object->inReplyTo->updated; $reply->url = $post->object->inReplyTo->url; pumpio_dopost($a, $client, $uid, $self, $reply, $own_id, false); $postarray['parent-uri'] = $post->object->inReplyTo->id; } if ($post->object->pump_io->proxyURL) { $postarray['extid'] = $post->object->pump_io->proxyURL; } $postarray['contact-id'] = $contact_id; $postarray['verb'] = ACTIVITY_POST; $postarray['owner-name'] = $post->actor->displayName; $postarray['owner-link'] = $post->actor->url; $postarray['owner-avatar'] = $post->actor->image->url; $postarray['author-name'] = $post->actor->displayName; $postarray['author-link'] = $post->actor->url; $postarray['author-avatar'] = $post->actor->image->url; $postarray['plink'] = $post->object->url; $postarray['app'] = $post->generator->displayName; $postarray['body'] = html2bbcode($post->object->content); $postarray['object'] = json_encode($post); if ($post->object->fullImage->url != "") { $postarray["body"] = "[url=" . $post->object->fullImage->url . "][img]" . $post->object->image->url . "[/img][/url]\n" . $postarray["body"]; } if ($post->object->displayName != "") { $postarray['title'] = $post->object->displayName; } $postarray['created'] = datetime_convert('UTC', 'UTC', $post->published); if (isset($post->updated)) { $postarray['edited'] = datetime_convert('UTC', 'UTC', $post->updated); } elseif (isset($post->received)) { $postarray['edited'] = datetime_convert('UTC', 'UTC', $post->received); } else { $postarray['edited'] = $postarray['created']; } if ($post->verb == "share") { if (!intval(get_config('system', 'wall-to-wall_share'))) { if (isset($post->object->author->displayName) and $post->object->author->displayName != "") { $share_author = $post->object->author->displayName; } elseif (isset($post->object->author->preferredUsername) and $post->object->author->preferredUsername != "") { $share_author = $post->object->author->preferredUsername; } else { $share_author = $post->object->author->url; } $postarray['body'] = share_header($share_author, $post->object->author->url, $post->object->author->image->url, "", datetime_convert('UTC', 'UTC', $post->object->created), $post->links->self->href) . $postarray['body'] . "[/share]"; /* $postarray['body'] = "[share author='".$share_author. "' profile='".$post->object->author->url. "' avatar='".$post->object->author->image->url. "' posted='".datetime_convert('UTC','UTC',$post->object->created). "' link='".$post->links->self->href."']".$postarray['body']."[/share]"; */ } else { // Let shares look like wall-to-wall posts $postarray['author-name'] = $post->object->author->displayName; $postarray['author-link'] = $post->object->author->url; $postarray['author-avatar'] = $post->object->author->image->url; } } if (trim($postarray['body']) == "") { return false; } $top_item = item_store($postarray); $postarray["id"] = $top_item; if ($top_item == 0 and $post->verb == "update") { $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s' , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d", dbesc($postarray["title"]), dbesc($postarray["body"]), dbesc($postarray["edited"]), dbesc($postarray["uri"]), intval($uid)); } if ($post->object->objectType == "comment") { if ($threadcompletion) { pumpio_fetchallcomments($a, $uid, $postarray['parent-uri']); } $user = q("SELECT * FROM `user` WHERE `uid` = %d AND `account_expired` = 0 LIMIT 1", intval($uid)); if (!count($user)) { return $top_item; } $importer_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname']; if (link_compare($own_id, $postarray['author-link'])) { return $top_item; } if (!function_exists("check_item_notification")) { $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0", dbesc($postarray['parent-uri']), intval($uid)); if (count($myconv)) { foreach ($myconv as $conv) { // now if we find a match, it means we're in this conversation if (!link_compare($conv['author-link'], $importer_url) and !link_compare($conv['author-link'], $own_id)) { continue; } require_once 'include/enotify.php'; $conv_parent = $conv['parent']; notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $user[0]['notify-flags'], 'language' => $user[0]['language'], 'to_name' => $user[0]['username'], 'to_email' => $user[0]['email'], 'uid' => $user[0]['uid'], 'item' => $postarray, 'link' => $a->get_baseurl() . '/display/' . urlencode(get_item_guid($top_item)), 'source_name' => $postarray['author-name'], 'source_link' => $postarray['author-link'], 'source_photo' => $postarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $conv_parent)); // only send one notification break; } } } } return $top_item; }