diff options
Diffstat (limited to 'include/feedutils.php')
-rw-r--r-- | include/feedutils.php | 173 |
1 files changed, 158 insertions, 15 deletions
diff --git a/include/feedutils.php b/include/feedutils.php index 158ecb7a3..d96735c3a 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -246,9 +246,17 @@ function get_atom_elements($feed, $item, &$author) { $found_author = $item->get_author(); if($found_author) { + if($rawauthor) { + if($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']) + $author['full_name'] = unxmlify($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']); + } $author['author_name'] = unxmlify($found_author->get_name()); $author['author_link'] = unxmlify($found_author->get_link()); $author['author_is_feed'] = false; + + $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + logger('rawauthor: ' . print_r($rawauthor, true)); + } else { $author['author_name'] = unxmlify($feed->get_title()); @@ -305,12 +313,6 @@ function get_atom_elements($feed, $item, &$author) { $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; - } - // look for a photo. We should check media size and find the best one, // but for now let's just find any author photo @@ -391,8 +393,16 @@ function get_atom_elements($feed, $item, &$author) { $rawcnv = $item->get_item_tags(NAMESPACE_OSTATUS, 'conversation'); if($rawcnv) { + // new style $ostatus_conversation = normalise_id(unxmlify($rawcnv[0]['attribs']['']['ref'])); - set_iconfig($res,'ostatus','conversation',$ostatus_conversation,true); + if(! $ostatus_conversation) { + // old style + $ostatus_conversation = normalise_id(unxmlify($rawcnv[0]['data'])); + } + if($ostatus_conversation) { + set_iconfig($res,'ostatus','conversation',$ostatus_conversation,true); + logger('ostatus_conversation: ' . $ostatus_conversation, LOGGER_DATA, LOG_INFO); + } } $ostatus_protocol = (($ostatus_conversation) ? true : false); @@ -406,6 +416,21 @@ function get_atom_elements($feed, $item, &$author) { $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); } + if($ostatus_protocol) { + + // 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; + } + + // And OStatus 'favorite' is pretty much what we call 'like' on other networks + + if((x($res,'verb')) && ($res['verb'] === ACTIVITY_FAVORITE)) { + $res['verb'] = ACTIVITY_LIKE; + } + } + /* * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. */ @@ -603,10 +628,17 @@ function get_atom_elements($feed, $item, &$author) { if(! $type) $type = 'application/octet-stream'; - if(($ostatus_protocol) && (strpos($type,'image') === 0) && (strpos($res['body'],$link) === false) && (strpos($link,'http') === 0)) { - $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; + if($ostatus_protocol) { + if((strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; + } + if((strpos($type,'video') === 0) && (strpos($res['body'], ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[video]' . $link . '[/video]'; + } + if((strpos($type,'audio') === 0) && (strpos($res['body'], ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) { + $res['body'] .= "\n\n" . '[audio]' . $link . '[/audio]'; + } } - $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); } } @@ -691,7 +723,7 @@ function get_atom_elements($feed, $item, &$author) { if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE - && array_key_exists('obj_type',$res) && $res['obj_type'] === ACTIVITY_OBJ_NOTE) { + && array_key_exists('obj_type',$res) && in_array($res['obj_type'], [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, ACTIVITY_OBJ_ACTIVITY ] )) { feed_get_reshare($res,$item); } @@ -798,9 +830,15 @@ function feed_get_reshare(&$res,$item) { if(! $type) $type = 'application/octet-stream'; - if((strpos($type,'image') === 0) && (strpos($body,$link) === false) && (strpos($link,'http') === 0)) { + if((strpos($type,'image') === 0) && (strpos($body, ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { $body .= "\n\n" . '[img]' . $link . '[/img]'; } + if((strpos($type,'video') === 0) && (strpos($body, ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) { + $body .= "\n\n" . '[video]' . $link . '[/video]'; + } + if((strpos($type,'audio') === 0) && (strpos($body, ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) { + $body .= "\n\n" . '[audio]' . $link . '[/audio]'; + } } } @@ -958,6 +996,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { foreach($items as $item) { $is_reply = false; + $parent_link = ''; logger('processing ' . $item->get_id(), LOGGER_DEBUG); @@ -966,6 +1005,9 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $is_reply = true; $parent_mid = normalise_id($rawthread[0]['attribs']['']['ref']); } + if(isset($rawthread[0]['attribs']['']['href'])) { + $parent_link = $rawthread[0]['attribs']['']['href']; + } if($is_reply) { @@ -995,7 +1037,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['author_xchan'] = ''; if($author['author_link'] != $contact['xchan_url']) { - $x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); + $name = ''; + if($author['full_name']) { + $name = $author['full_name']; + if($author['author_name']) + $name .= ' (' . $author['author_name'] . ')'; + } + else { + $name = $author['author_name']; + } + $x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); if($x) $datarray['author_xchan'] = $x; } @@ -1037,7 +1088,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { intval($importer['channel_id']) ); if($c) { - $pmid = $x[0]['parent_mid']; + $pmid = $c[0]['parent_mid']; $datarray['parent_mid'] = $pmid; } } @@ -1052,6 +1103,44 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['parent_mid'] = $pmid; } } + if((! $pmid) && $parent_link !== '') { + $f = feed_conversation_fetch($importer,$contact,$parent_link); + if($f) { + // check both potential conversation parents again + if($conv_id) { + $c = q("select parent_mid from item left join iconfig on item.id = iconfig.iid where iconfig.cat = 'ostatus' and iconfig.k = 'conversation' and iconfig.v = '%s' and item.uid = %d order by item.id limit 1", + dbesc($conv_id), + intval($importer['channel_id']) + ); + if($c) { + $pmid = $c[0]['parent_mid']; + $datarray['parent_mid'] = $pmid; + } + } + if(! $pmid) { + $x = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", + dbesc($parent_mid), + intval($importer['channel_id']) + ); + + if($x) { + $pmid = $x[0]['parent_mid']; + $datarray['parent_mid'] = $pmid; + } + } + } + + // the conversation parent might just be the post we are trying to import. + // check existence again in case it was just delivered. + + $r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", + dbesc($datarray['mid']), + intval($importer['channel_id']) + ); + if($r) { + continue; + } + } if(! $pmid) { @@ -1116,7 +1205,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } if($author['author_link'] != $contact['xchan_url']) { - $x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); + $name = ''; + if($author['full_name']) { + $name = $author['full_name']; + if($author['author_name']) + $name .= ' (' . $author['author_name'] . ')'; + } + else { + $name = $author['author_name']; + } + $x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); if($x) $datarray['author_xchan'] = $x; } @@ -1182,6 +1280,51 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } + +function feed_conversation_fetch($importer,$contact,$parent_link) { + + logger('parent_link: ' . $parent_link, LOGGER_DEBUG, LOG_INFO); + + $link = ''; + + // GNU-Social flavoured feeds + if(strpos($parent_link,'/notice/')) { + $link = str_replace('/notice/','/api/statuses/show/',$parent_link) . '.atom'; + } + + // Mastodon flavoured feeds + if(strpos($parent_link,'/users/') && strpos($parent_link,'/updates/')) { + $link = $parent_link . '.atom'; + } + + if(! $link) + return false; + + logger('fetching: ' . $link, LOGGER_DEBUG, LOG_INFO); + + $fetch = z_fetch_url($link); + + if(! $fetch['success']) + return false; + + $data = $fetch['body']; + + // We will probably receive an atom 'entry' and not an atom 'feed'. Unfortunately + // our parser is a bit strict about compliance so we'll insert just enough of a feed + // tag to trick it into believing it's a compliant feed. + + if(! strstr($data,'<feed')) { + $data = str_replace('<entry ','<feed xmlns="http://www.w3.org/2005/Atom"><entry ',$data); + $data .= '</feed>'; + } + + consume_feed($data,$importer,$contact,1); + consume_feed($data,$importer,$contact,2); + + return true; + +} + /** * @brief Normalise an id. * |