From eeb9103e267a01ad5f076afeb02bedabfcc70db9 Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Fri, 5 May 2017 00:23:57 +0200 Subject: :bulb: correct some Doxygen syntax mistakes. --- include/feedutils.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 06a342a3f..6bb7d103e 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -742,7 +742,7 @@ function encode_rel_links($links) { * @param $importer * The contact_record (joined to user_record) of the local user who owns this * relationship. It is this person's stuff that is going to be updated. - * @param array $contact[in,out] + * @param[in,out] array $contact * The person who is sending us stuff. If not set, we MAY be processing a "follow" activity * from an external network and MAY create an appropriate contact record. Otherwise, we MUST * have a contact record. @@ -1232,8 +1232,11 @@ function handle_feed($uid, $abook_id, $url) { /** * @brief Return a XML tag with author information. * + * @hooks \b atom_author Possibility to add further tags to returned XML string + * * \e string The created XML tag as a string without closing tag * @param string $tag The XML tag to create - * @param string $name Name of the author + * @param string $nick preferred username + * @param string $name displayed name of the author * @param string $uri * @param int $h image height * @param int $w image width -- cgit v1.2.3 From e501289a5544823eed3834a831770c07159664ff Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 11 May 2017 17:39:26 -0700 Subject: consolidate and simplify the generation of activitystreams persons, add a couple more fields hoping eventually Mastodon will accept legal follow activities without choking on them. Requires an update of plugins also. --- include/feedutils.php | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 6bb7d103e..6c411723a 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -79,9 +79,11 @@ function get_feed_for($channel, $observer_hash, $params) { $feed_author = ''; if(intval($params['compat']) === 1) { - $feed_author = atom_author('author',$channel['channel_address'],$channel['channel_name'],$channel['xchan_url'],300,300,$channel['xchan_photo_mimetype'],$channel['xchan_photo_l']); + $feed_author = atom_render_author('author',$channel); } + $owner = atom_render_author('zot:owner',$channel); + $atom .= replace_macros($feed_template, array( '$version' => xmlify(Zotlabs\Lib\System::get_project_version()), '$red' => xmlify(Zotlabs\Lib\System::get_platform_name()), @@ -89,6 +91,7 @@ function get_feed_for($channel, $observer_hash, $params) { '$feed_title' => xmlify($channel['channel_name']), '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), '$author' => $feed_author, + '$owner' => $owner, '$name' => xmlify($channel['channel_name']), '$profile_page' => xmlify($channel['xchan_url']), '$mimephoto' => xmlify($channel['xchan_photo_mimetype']), @@ -1272,6 +1275,37 @@ function atom_author($tag, $nick, $name, $uri, $h, $w, $type, $photo) { return $o; } + +function atom_render_author($tag,$xchan) { + + + $nick = xmlify(substr($xchan['xchan_addr'],0,strpos($xchan['xchan_addr'],'@'))); + $id = xmlify($xchan['xchan_url']); + $name = xmlify($xchan['xchan_name']); + $photo = xmlify($xchan['xchan_photo_l']); + $type = xmlify($xchan['xchan_photo_mimetype']); + $w = $h = 300; + + $o .= "<$tag>\r\n"; + $o .= " http://activitystrea.ms/schema/1.0/person\r\n"; + $o .= " $id\r\n"; + $o .= " $nick\r\n"; + $o .= " $id\r\n"; + $o .= ' ' . "\r\n"; + $o .= ' ' . "\r\n"; + $o .= ' ' . "\r\n"; + $o .= ' ' . $nick . '' . "\r\n"; + $o .= ' ' . $name . '' . "\r\n"; + + call_hooks('atom_render_author', $o); + + $o .= "\r\n"; + + return $o; + + +} + /** * @brief Create an item for the Atom feed. * @@ -1303,16 +1337,13 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0) { $o = "\r\n\r\n\r\n"; if(is_array($author)) { - $reddress = substr($author['xchan_addr'],0,strpos($author['xchan_addr'],'@')); - $o .= atom_author('author',$reddress,$author['xchan_name'],$author['xchan_url'],80,80,$author['xchan_photo_mimetype'],$author['xchan_photo_m']); + $o .= atom_render_author('author',$author); } else { - $reddress = substr($item['author']['xchan_addr'],0,strpos($item['author']['xchan_addr'],'@')); - $o .= atom_author('author',$reddress,$item['author']['xchan_name'],$item['author']['xchan_url'],80,80,$item['author']['xchan_photo_mimetype'], $item['author']['xchan_photo_m']); + $o .= atom_render_author('author',$item['author']); } - $reddress = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@')); - $o .= atom_author('zot:owner',$reddress,$item['owner']['xchan_name'],$item['owner']['xchan_url'],80,80,$item['owner']['xchan_photo_mimetype'],$item['owner']['xchan_photo_m']); + $o .= atom_render_author('zot:owner',$item['owner']); if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); -- cgit v1.2.3 From 36d40866738ca81a31002251d4ca63f1087d8054 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 4 Jun 2017 19:09:05 -0700 Subject: ostatus feeds: extract photo information from posts and convert to enclosures as otherwise OStatus servers will strip them from the HTML in the feed and refuse to render them --- include/feedutils.php | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 6c411723a..1563bdb41 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -136,7 +136,7 @@ function get_feed_for($channel, $observer_hash, $params) { continue; /** @BUG $owner is undefined in this call */ - $atom .= atom_entry($item, $type, null, $owner, true); + $atom .= atom_entry($item, $type, null, $owner, true, '', $params['compat']); } } @@ -1306,6 +1306,28 @@ function atom_render_author($tag,$xchan) { } +function compat_photos_list($s) { + + $ret = []; + + $found = preg_match_all('/\[[zi]mg(.*?)\](.*?)\[/ism',$s,$matches,PREG_SET_ORDER); + + if($found) { + foreach($matches as $match) { + $ret[] = [ + 'href' => $match[2], + 'length' => 0, + 'type' => guess_image_type($match[2]) + ]; + + } + } + + return $ret; +} + + + /** * @brief Create an item for the Atom feed. * @@ -1319,7 +1341,8 @@ function atom_render_author($tag,$xchan) { * @param number $cid default 0 * @return void|string */ -function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0) { +function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $compat = false) { + if(! $item['parent']) return; @@ -1334,6 +1357,13 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0) { else $body = $item['body']; + if($compat) { + $compat_photos = compat_photos_list($body); + } + else { + $compat_photos = null; + } + $o = "\r\n\r\n\r\n"; if(is_array($author)) { @@ -1403,10 +1433,19 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0) { . (($enc['href']) ? 'href="' . $enc['href'] . '" ' : '') . (($enc['length']) ? 'length="' . $enc['length'] . '" ' : '') . (($enc['type']) ? 'type="' . $enc['type'] . '" ' : '') - . ' />'; + . ' />' . "\r\n"; } } } + if($compat_photos) { + foreach($compat_photos as $enc) { + $o .= '' . "\r\n"; + } + } if($item['term']) { foreach($item['term'] as $term) { -- cgit v1.2.3 From cdfd42053d4920bc2c7c508d512ad3c7033d8095 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 4 Jun 2017 20:07:08 -0700 Subject: always add a length to ostatus compat enclosures - even if unknown (0) --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 1563bdb41..5f86ad5a4 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1441,7 +1441,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ foreach($compat_photos as $enc) { $o .= '' . "\r\n"; } -- cgit v1.2.3 From bea0a491cf319946a11c9a5b8e913e4cfc8b08d0 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 6 Jun 2017 22:49:45 -0700 Subject: Looks like we need the mastodon feed check in core - grrr. Will do that for now until it can be put back into plugins. --- include/feedutils.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 5f86ad5a4..708532013 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -397,6 +397,9 @@ function get_atom_elements($feed, $item, &$author) { } $ostatus_protocol = (($item->get_item_tags(NAMESPACE_OSTATUS, 'conversation')) ? true : false); + $mastodon = (($item->get_item_tags('http://mastodon.social/schema/1.0','scope')) ? true : false); + if($mastodon) + $ostatus_protocol = true; $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if($apps && $apps[0]['attribs']['']['source']) { -- cgit v1.2.3 From 3563568f6f965c755323a233a99a60e3b0b85102 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 7 Jun 2017 21:49:50 -0700 Subject: fall back on feed logo if an author avatar cannot be found --- include/feedutils.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 708532013..f1cee4194 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1185,6 +1185,10 @@ function feed_meta($xml) { } } + if(! $author['author_photo']) + $author['author_photo'] = $feed->get_image_url(); + + if(substr($author['author_link'],-1,1) == '/') $author['author_link'] = substr($author['author_link'],0,-1); -- cgit v1.2.3 From 5d2035b729d2d0075addf19cbe29536fbff5914a Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 12 Jun 2017 19:17:50 -0700 Subject: implement feed_get_reshare to extract shared post info from atom feed and convert to bbcode --- include/feedutils.php | 261 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 170 insertions(+), 91 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index f1cee4194..23a065298 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -278,6 +278,23 @@ function get_atom_elements($feed, $item, &$author) { $base_url = ''; + $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'); + $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); // select between supported verbs @@ -288,112 +305,85 @@ function get_atom_elements($feed, $item, &$author) { // 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')) + if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) { $res['verb'] = ACTIVITY_UNFOLLOW; + } - if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE) { - // For Mastodon shares ("boosts"), we need to parse the original author information - // from the activity:object -> author structure - $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); - - if($rawobj) { - $rawauthor = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); - if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']) { - $author['author_name'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']); - } + // look for a photo. We should check media size and find the best one, + // but for now let's just find any author photo + + $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); - if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri']) { - $author['author_link'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri']); + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { + $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + foreach($base as $link) { + if(!x($author, 'author_photo') || ! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') + $author['author_photo'] = unxmlify($link['attribs']['']['href']); } - if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { - $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - foreach($base as $link) { - if(!x($author, 'author_photo') || ! $author['author_photo']) { - if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } + } + } + $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); + + if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_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'])) + $author['author_link'] = unxmlify($link['attribs']['']['href']); + if(!x($author, 'author_photo') || ! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') + $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } } - else { - // look for a photo. We should check media size and find the best one, - // but for now let's just find any author photo - $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + // check for a yahoo media element (github etc.) + if(! $author['author_photo']) { + $rawmedia = $item->get_item_tags(NAMESPACE_YMEDIA,'thumbnail'); + if($rawmedia && $rawmedia[0]['attribs']['']['url']) { + $author['author_photo'] = strip_tags(unxmlify($rawmedia[0]['attribs']['']['url'])); + } + } + + + // No photo/profile-link on the item - look at the feed level + + if((! (x($author,'author_link'))) || (! (x($author,'author_photo')))) { + $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(!x($author, 'author_photo') || ! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'alternate' && (! $author['author_link'])) { + $author['author_link'] = unxmlify($link['attribs']['']['href']); + $author['author_is_feed'] = true; + } + if(! $author['author_photo']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } - $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); + $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); - if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'], ACTIVITY_OBJ_PERSON)) { + if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_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'])) $author['author_link'] = unxmlify($link['attribs']['']['href']); - if(!x($author, 'author_photo') || ! $author['author_photo']) { + if(! (x($author,'author_photo'))) { if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } } - - // check for a yahoo media element (github etc.) - - if(! $author['author_photo']) { - $rawmedia = $item->get_item_tags(NAMESPACE_YMEDIA,'thumbnail'); - if($rawmedia && $rawmedia[0]['attribs']['']['url']) { - $author['author_photo'] = strip_tags(unxmlify($rawmedia[0]['attribs']['']['url'])); - } - } - - - // No photo/profile-link on the item - look at the feed level - - if((! (x($author,'author_link'))) || (! (x($author,'author_photo')))) { - $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' && (! $author['author_link'])) { - $author['author_link'] = unxmlify($link['attribs']['']['href']); - $author['author_is_feed'] = true; - } - if(! $author['author_photo']) { - if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - - $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); - - if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_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'])) - $author['author_link'] = unxmlify($link['attribs']['']['href']); - if(! (x($author,'author_photo'))) { - if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - } - } } $ostatus_protocol = (($item->get_item_tags(NAMESPACE_OSTATUS, 'conversation')) ? true : false); @@ -499,23 +489,6 @@ function get_atom_elements($feed, $item, &$author) { 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 @@ -597,6 +570,7 @@ function get_atom_elements($feed, $item, &$author) { $attach = $item->get_enclosures(); if($attach) { + $res['attach'] = array(); foreach($attach as $att) { $len = intval($att->get_length()); @@ -616,6 +590,7 @@ function get_atom_elements($feed, $item, &$author) { $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); } } + $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); @@ -693,6 +668,10 @@ function get_atom_elements($feed, $item, &$author) { $res['target'] = $obj; } + if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE) { + feed_get_reshare($res,$item); + } + // build array to pass to hook $arr = [ 'feed' => $feed, @@ -709,6 +688,106 @@ function get_atom_elements($feed, $item, &$author) { return $arr['result']; } +function feed_get_reshare(&$res,$item) { + + $share = []; + + // For Mastodon shares ("boosts"), we need to parse the original author information + // from the activity:object -> author structure + $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); + + if($rawobj) { + + $rawauthor = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']) { + $share['author'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']); + } + + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri']) { + $share['profile'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri']); + } + + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { + $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + foreach($base as $link) { + if(! (array_key_exists('avatar',$share) && $share['avatar'])) { + if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') + $share['avatar'] = unxmlify($link['attribs']['']['href']); + } + } + } + + if(! $share['author']) + $share['author'] = t('unknown'); + if(! $share['avatar']) + $share['avatar'] = z_root() . '/' . get_default_profile_photo(80); + if(! $share['profile']) + $share['profile'] = z_root(); + + $child = $rawobj[0]['child']; + + + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) + $share['link'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); + + $rawcreated = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); + if($rawcreated) + $share['created'] = unxmlify($rawcreated[0]['data']); + else + $share['created'] = $res['created']; + + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) + $share['message_id'] = unxmlify($child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']); + + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { + $body = unxmlify($child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']); + if(! $body) + $body = unxmlify($child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']); + + if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { + $body = purify_html($body); + $body = html2bbcode($body); + } + } + + $attach = $rawobj->get_enclosures(); + if($attach) { + 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'; + + if((strpos($type,'image') === 0) && (strpos($body,$link) === false) && (strpos($link,'http') === 0)) { + $body .= "\n\n" . '[img]' . $link . '[/img]'; + } + } + } + + $res['body'] = "[share author='" . urlencode($share['author']) . + "' profile='" . $share['profile'] . + "' avatar='" . $share['avatar'] . + "' link='" . $share['link'] . + "' posted='" . $share['created'] . + "' message_id='" . $share['message_id'] . "']"; + $o .= $body; + $o .= "[/share]"; + } + +} + + + /** * @brief Encodes SimplePie_Item link arrays. * -- cgit v1.2.3 From 2f8fb2b663c9b1ea1879724d8542654263085b6d Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 12 Jun 2017 21:12:14 -0700 Subject: ostatus is almost unrecognisable these days from its former self. In this case thr:in-reply-to has almost no meaning since it almost never refers to a top level post; which makes it quite difficult to preserve conversations --- include/feedutils.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 23a065298..22e2b5add 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -996,11 +996,23 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { dbesc($parent_mid), intval($importer['channel_id']) ); - if($x) - $parent_mid = $x[0]['mid']; - $datarray['parent_mid'] = $parent_mid; + if($x) { + $pmid = $x[0]['mid']; + $datarray['parent_mid'] = $pmid; + } + else { + // immediate parent wasn't found. Turn into a top-level post if permissions allow + // but save the thread_parent in case we need to refer to it later. We should probably + // also save the ostatus:conversation_id + + if(! post_is_importable($datarray, $contact)) + continue; + $datarray['parent_mid'] = $datarray['mid']; + set_iconfig($datarray,'system','parent_mid',$parent_mid,true); + } + $datarray['aid'] = $importer['channel_account_id']; $datarray['uid'] = $importer['channel_id']; -- cgit v1.2.3 From 5530833bf88342bc407375fb9c29b99b2c79e7bc Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 12 Jun 2017 21:58:40 -0700 Subject: preserve the ostatus:conversation pointer also --- include/feedutils.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 22e2b5add..317516c74 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -386,7 +386,14 @@ function get_atom_elements($feed, $item, &$author) { } } - $ostatus_protocol = (($item->get_item_tags(NAMESPACE_OSTATUS, 'conversation')) ? true : false); + $rawcnv = $item->get_item_tags(NAMESPACE_OSTATUS, 'conversation'); + if($rawcnv) { + $ostatus_conversation = unxmlify($rawcnv[0]['attribs']['']['ref']); + set_iconfig($res,'ostatus','conversation',$ostatus_conversation,true); + } + + $ostatus_protocol = (($ostatus_conversation) ? true : false); + $mastodon = (($item->get_item_tags('http://mastodon.social/schema/1.0','scope')) ? true : false); if($mastodon) $ostatus_protocol = true; -- cgit v1.2.3 From 8eccd7d47d300f569ddb06d85f1a38441610d61e Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 13 Jun 2017 18:06:45 -0700 Subject: attempt to group gnu-social and mastodon conversations by ostatus:conversation in addition to falling back on thr:in_reply_to --- include/feedutils.php | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 317516c74..156a78a39 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -999,20 +999,35 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { continue; } - $x = q("select mid from item where mid = '%s' and uid = %d limit 1", - dbesc($parent_mid), - intval($importer['channel_id']) - ); - - if($x) { - $pmid = $x[0]['mid']; - $datarray['parent_mid'] = $pmid; + $pmid = ''; + $conv_id = get_iconfig($datarray,'ostatus','conversation'); + + 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 = $x[0]['parent_mid']; + $datarray['parent_mid'] = $pmid; + } } else { + $x = q("select mid from item where mid = '%s' and uid = %d limit 1", + dbesc($parent_mid), + intval($importer['channel_id']) + ); + + if($x) { + $pmid = $x[0]['mid']; + $datarray['parent_mid'] = $pmid; + } + } + + if(! $pmid) { // immediate parent wasn't found. Turn into a top-level post if permissions allow - // but save the thread_parent in case we need to refer to it later. We should probably - // also save the ostatus:conversation_id + // but save the thread_parent in case we need to refer to it later. if(! post_is_importable($datarray, $contact)) continue; -- cgit v1.2.3 From 70e912736f10bb8eaf8978689ae0183f7970043c Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 13 Jun 2017 19:52:16 -0700 Subject: support mastodon content warnings by converting into n-s-f-w tag --- include/feedutils.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 156a78a39..c9c7522b1 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -266,6 +266,8 @@ function get_atom_elements($feed, $item, &$author) { $res['item_rss'] = 1; + $summary = unxmlify($item->get_description(true)); + // removing the content of the title if its identically to the body // This helps with auto generated titles e.g. from tumblr @@ -486,6 +488,12 @@ function get_atom_elements($feed, $item, &$author) { ); } + // turn Mastodon content warning into a #nsfw hashtag + if($mastodon && $summary) { + $res['body'] .= "\n\n#nsfw\n"; + } + + $private = $item->get_item_tags(NAMESPACE_DFRN, 'private'); if($private && intval($private[0]['data']) > 0) $res['item_private'] = ((intval($private[0]['data'])) ? 1 : 0); -- cgit v1.2.3 From 54e07389fa1ebe7a2d2815258b021c07d2fc4dd0 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 14 Jun 2017 22:14:52 +0200 Subject: thr:in-reply-to seems to must not have a type set. there is no mention of this in the spec and replies will be shown as replies in mastodon this way. --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index c9c7522b1..d1c7a5c64 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1505,7 +1505,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); - $o .= '' . "\r\n"; + $o .= '' . "\r\n"; } if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { -- cgit v1.2.3 From ec74b5700024063ea8bd3fb8d644df881c704fb3 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 14 Jun 2017 23:21:47 +0200 Subject: re-add type since the actual culprit was the X-ZOT prefix --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index d1c7a5c64..eb2d3a6e1 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1505,7 +1505,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); - $o .= '' . "\r\n"; + $o .= '' . "\r\n"; } if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { -- cgit v1.2.3 From fe02665f54a2bd4746757348680a2cee439c2750 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 15 Jun 2017 00:17:26 +0200 Subject: typo --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index eb2d3a6e1..c9c7522b1 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1505,7 +1505,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); - $o .= '' . "\r\n"; + $o .= '' . "\r\n"; } if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { -- cgit v1.2.3 From 1f075d92bc4e47ae282f811d10c31cd6f09191a6 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 15 Jun 2017 00:19:50 +0200 Subject: sigh... x-zot prefix slipped in again --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index c9c7522b1..02decca69 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1505,7 +1505,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); - $o .= '' . "\r\n"; + $o .= '' . "\r\n"; } if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { -- cgit v1.2.3 From b8c77bbcfcc5f1f25ff61ac5fc9f284148955221 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 14 Jun 2017 16:06:25 -0700 Subject: use parent_mid --- include/feedutils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 02decca69..5e5056f7c 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1021,13 +1021,13 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } else { - $x = q("select mid from item where mid = '%s' and uid = %d limit 1", + $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]['mid']; + $pmid = $x[0]['parent_mid']; $datarray['parent_mid'] = $pmid; } } -- cgit v1.2.3 From 0d7e7ac657ce4d1e7d2797b565882d3a57dfd8de Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 14 Jun 2017 19:59:25 -0700 Subject: always transmit a valid uri --- include/feedutils.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 5e5056f7c..2f3927748 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1505,6 +1505,10 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); + // ensure it's a legal uri and not just a message-id + if(! strpos($parent_item,':')) + $parent_item = 'X-ZOT:' . $parent_item; + $o .= '' . "\r\n"; } -- cgit v1.2.3 From bb9557a9ae9bbec806ef6e91c25120df0da8a72e Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 14 Jun 2017 20:20:18 -0700 Subject: remove some duplicated code --- include/feedutils.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 2f3927748..0d7e1d6c2 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -259,7 +259,7 @@ function get_atom_elements($feed, $item, &$author) { if(substr($author['author_link'],-1,1) == '/') $author['author_link'] = substr($author['author_link'],0,-1); - $res['mid'] = unxmlify($item->get_id()); + $res['mid'] = normalise_id(unxmlify($item->get_id())); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $res['plink'] = unxmlify($item->get_link(0)); @@ -390,7 +390,7 @@ function get_atom_elements($feed, $item, &$author) { $rawcnv = $item->get_item_tags(NAMESPACE_OSTATUS, 'conversation'); if($rawcnv) { - $ostatus_conversation = unxmlify($rawcnv[0]['attribs']['']['ref']); + $ostatus_conversation = normalise_id(unxmlify($rawcnv[0]['attribs']['']['ref'])); set_iconfig($res,'ostatus','conversation',$ostatus_conversation,true); } @@ -938,7 +938,6 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { foreach($items as $item) { $is_reply = false; - $item_id = normalise_id($item->get_id()); logger('processing ' . $item->get_id(), LOGGER_DEBUG); @@ -955,12 +954,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { // Have we seen it? If not, import it. - $item_id = normalise_id($item->get_id()); $author = array(); $datarray = get_atom_elements($feed,$item,$author); - if($datarray['mid']) - $datarray['mid'] = normalise_id($item->get_id()); + if(! $datarray['mid']) + continue; if($contact['xchan_network'] === 'rss') { $datarray['public_policy'] = 'specific'; @@ -987,7 +985,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['owner_xchan'] = $contact['xchan_hash']; $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", - dbesc($item_id), + dbesc($datarray['mid']), intval($importer['channel_id']) ); @@ -1010,6 +1008,9 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $pmid = ''; $conv_id = get_iconfig($datarray,'ostatus','conversation'); + // match conversations - first try ostatus:conversation + // next try thr:in_reply_to + 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), @@ -1020,7 +1021,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['parent_mid'] = $pmid; } } - else { + if(! $pmid) { $x = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", dbesc($parent_mid), intval($importer['channel_id']) @@ -1056,12 +1057,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { // Head post of a conversation. Have we seen it? If not, import it. - $item_id = normalise_id($item->get_id()); $author = array(); $datarray = get_atom_elements($feed,$item,$author); - if($datarray['mid']) - $datarray['mid'] = normalise_id($item->get_id()); + if(! $datarray['mid']) + continue; if($contact['xchan_network'] === 'rss') { $datarray['public_policy'] = 'specific'; @@ -1116,7 +1116,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", - dbesc($item_id), + dbesc($datarray['mid']), intval($importer['channel_id']) ); @@ -1136,7 +1136,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { continue; } - $datarray['parent_mid'] = $item_id; + $datarray['parent_mid'] = $datarray['mid']; $datarray['uid'] = $importer['channel_id']; $datarray['aid'] = $importer['channel_account_id']; -- cgit v1.2.3 From f25e0c3829abd4a89956773b965e45d0e9db18cc Mon Sep 17 00:00:00 2001 From: zotlabs Date: Fri, 16 Jun 2017 19:30:02 -0700 Subject: testing mastodon boosts/reshares --- include/feedutils.php | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 0d7e1d6c2..158ecb7a3 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -354,6 +354,7 @@ function get_atom_elements($feed, $item, &$author) { // No photo/profile-link on the item - look at the feed level + if((! (x($author,'author_link'))) || (! (x($author,'author_photo')))) { $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { @@ -602,6 +603,10 @@ 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]'; + } + $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); } } @@ -683,7 +688,10 @@ function get_atom_elements($feed, $item, &$author) { $res['target'] = $obj; } - if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE) { + + + if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE + && array_key_exists('obj_type',$res) && $res['obj_type'] === ACTIVITY_OBJ_NOTE) { feed_get_reshare($res,$item); } @@ -713,14 +721,14 @@ function feed_get_reshare(&$res,$item) { if($rawobj) { - $rawauthor = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + $rawauthor = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['author']; if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']) { - $share['author'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']); + $share['author'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); } if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri']) { - $share['profile'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri']); + $share['profile'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); } if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { @@ -744,9 +752,10 @@ function feed_get_reshare(&$res,$item) { if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) - $share['link'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); + $share['links'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); + + $rawcreated = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['published']; - $rawcreated = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); if($rawcreated) $share['created'] = unxmlify($rawcreated[0]['data']); else @@ -766,13 +775,19 @@ function feed_get_reshare(&$res,$item) { } } - $attach = $rawobj->get_enclosures(); + $attach = $share['links']; if($attach) { 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($att['rel'] === 'alternate') { + $share['alternate'] = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att['href'])))); + continue; + } + if($att['rel'] !== 'enclosure') + continue; + $len = intval($att['length']); + $link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att['href'])))); + $title = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att['title'])))); + $type = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att['type'])))); if(strpos($type,';')) $type = substr($type,0,strpos($type,';')); if((! $link) || (strpos($link,'http') !== 0)) @@ -792,11 +807,12 @@ function feed_get_reshare(&$res,$item) { $res['body'] = "[share author='" . urlencode($share['author']) . "' profile='" . $share['profile'] . "' avatar='" . $share['avatar'] . - "' link='" . $share['link'] . + "' link='" . $share['alternate'] . "' posted='" . $share['created'] . "' message_id='" . $share['message_id'] . "']"; - $o .= $body; - $o .= "[/share]"; + + $res['body'] .= $body; + $res['body'] .= "[/share]"; } } @@ -818,6 +834,10 @@ function encode_rel_links($links) { $l = array(); if($link['attribs']['']['rel']) $l['rel'] = $link['attribs']['']['rel']; + if($link['attribs']['']['length']) + $l['length'] = $link['attribs']['']['length']; + if($link['attribs']['']['title']) + $l['title'] = $link['attribs']['']['title']; if($link['attribs']['']['type']) $l['type'] = $link['attribs']['']['type']; if($link['attribs']['']['href']) @@ -1724,3 +1744,4 @@ function asencode_person($p) { return $ret; } + -- cgit v1.2.3 From 07d6472eea377a9be7e35cca823307382a43df46 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 25 Jun 2017 18:07:07 -0700 Subject: mastodon reshares can be either posts or comments; silence warning from guess_image_type when handed a URL to a non-existent resource. --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 158ecb7a3..cc873876a 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -691,7 +691,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 ] )) { feed_get_reshare($res,$item); } -- cgit v1.2.3 From b0dd824dbc25e8ec12011cbc334471fc47a87735 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 26 Jun 2017 16:54:28 -0700 Subject: add ostatus attached photos (inline to the post body) even if there's a link to the photo in the post but it isn't wrapped in an img tag. --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index cc873876a..b785bd64a 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -603,7 +603,7 @@ 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)) { + if(($ostatus_protocol) && (strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) { $res['body'] .= "\n\n" . '[img]' . $link . '[/img]'; } -- cgit v1.2.3 From 4d81c498e2f9a65eac7f71b077aa3e787d53325d Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 26 Jun 2017 17:07:59 -0700 Subject: in gnu-social reshare objects are activities, not posts or comments --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index b785bd64a..7314f69a6 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -691,7 +691,7 @@ function get_atom_elements($feed, $item, &$author) { if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE - && array_key_exists('obj_type',$res) && in_array($res['obj_type'], [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT ] )) { + && 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); } -- cgit v1.2.3 From 676481de58d078c93789f696ac003936461575d7 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 26 Jun 2017 23:06:15 -0700 Subject: support linked media (audio/video) elements in feeds as well as images --- include/feedutils.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 7314f69a6..2a0dba982 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -603,10 +603,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 . '[/img]') === 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 ); } } @@ -798,9 +805,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]'; + } } } -- cgit v1.2.3 From 1273ac67f40c4c45807b178a9f679efc18bcc9c2 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 27 Jun 2017 19:20:13 -0700 Subject: (untested currently) fetch conversation for GNU-Social and Mastodon when provided a comment with no local copy of the parent. --- include/feedutils.php | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 2a0dba982..8bd4673f5 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -971,6 +971,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); @@ -979,6 +980,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) { @@ -1050,7 +1054,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; } } @@ -1065,6 +1069,20 @@ 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) { + $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; + } + } + } if(! $pmid) { @@ -1195,6 +1213,34 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } + +function feed_conversation_fetch($importer,$contact,$parent_link) { + + $link = ''; + + // GNU-Social flavoured feeds + if(strpos($parent_link,'/notice/')) { + $link = str_replace('/notice/','/api/statuses/show',$link) . '.atom'; + } + + // Mastodon flavoured feeds + if(strpos($parent_link,'/users/') && strpos($parent_link,'/updates/')) { + $link = $parent_link . '.xml'; + } + + if(! $link) + return false; + + $fetch = z_fetch_url($link); + + if(! $fetch['success']) + return false; + + consume_feed($fetch['body'],$importer,$contact,1); + consume_feed($fetch['body'],$importer,$contact,2); + +} + /** * @brief Normalise an id. * -- cgit v1.2.3 From 2b2ea40bce41ad8d5688f42e71837a2caca8e9a8 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 27 Jun 2017 19:57:03 -0700 Subject: log conversation fetches (also a missed / char in the string replace) --- include/feedutils.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 8bd4673f5..19b4e27ae 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1216,11 +1216,13 @@ 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',$link) . '.atom'; + $link = str_replace('/notice/','/api/statuses/show/',$link) . '.atom'; } // Mastodon flavoured feeds -- cgit v1.2.3 From dab00a98e0b450183ef5f6ad9d6f4708e2246695 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 27 Jun 2017 20:07:48 -0700 Subject: translate 'favorite' verb to 'like' if it's an ostatus feed --- include/feedutils.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 19b4e27ae..de0cedcc0 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -305,12 +305,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 @@ -406,6 +400,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. */ -- cgit v1.2.3 From c2af3702828fcfa3817f84d5ff8424740b516b35 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 28 Jun 2017 15:58:14 -0700 Subject: refetch testing --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index de0cedcc0..a7c2b7ca8 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1231,7 +1231,7 @@ function feed_conversation_fetch($importer,$contact,$parent_link) { // GNU-Social flavoured feeds if(strpos($parent_link,'/notice/')) { - $link = str_replace('/notice/','/api/statuses/show/',$link) . '.atom'; + $link = str_replace('/notice/','/api/statuses/show/',$parent_link) . '.atom'; } // Mastodon flavoured feeds -- cgit v1.2.3 From c5cff7d6377bc193a07fb9476490f71f59c7e19a Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 28 Jun 2017 16:02:44 -0700 Subject: more refetch testing --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index a7c2b7ca8..8c2a7a8d7 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1236,7 +1236,7 @@ function feed_conversation_fetch($importer,$contact,$parent_link) { // Mastodon flavoured feeds if(strpos($parent_link,'/users/') && strpos($parent_link,'/updates/')) { - $link = $parent_link . '.xml'; + $link = $parent_link . '.atom'; } if(! $link) -- cgit v1.2.3 From b91d95d2418237f4344fa0906dd47815e20de2e9 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 28 Jun 2017 19:20:11 -0700 Subject: add logging --- include/feedutils.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 8c2a7a8d7..937a2d28c 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1242,11 +1242,14 @@ function feed_conversation_fetch($importer,$contact,$parent_link) { if(! $link) return false; + logger('fetching: ' . $link, LOGGER_DEBUG, LOG_INFO); + $fetch = z_fetch_url($link); if(! $fetch['success']) return false; + consume_feed($fetch['body'],$importer,$contact,1); consume_feed($fetch['body'],$importer,$contact,2); -- cgit v1.2.3 From 126af3a24a0dffc705235ed083a9192f97749829 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 28 Jun 2017 19:34:49 -0700 Subject: pretend it's a real feed even though it isn't --- include/feedutils.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 937a2d28c..184f8ed09 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1249,9 +1249,19 @@ function feed_conversation_fetch($importer,$contact,$parent_link) { if(! $fetch['success']) return false; + $data = $fetch['body']; - consume_feed($fetch['body'],$importer,$contact,1); - consume_feed($fetch['body'],$importer,$contact,2); + // 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,' Date: Wed, 28 Jun 2017 20:07:53 -0700 Subject: conversation fetching is partially working - but it isn't always glueing the conversation pieces together. --- include/feedutils.php | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 184f8ed09..a262b9562 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1081,14 +1081,27 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if((! $pmid) && $parent_link !== '') { $f = feed_conversation_fetch($importer,$contact,$parent_link); if($f) { - $x = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", - dbesc($parent_mid), - intval($importer['channel_id']) - ); + // 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; + if($x) { + $pmid = $x[0]['parent_mid']; + $datarray['parent_mid'] = $pmid; + } } } } -- cgit v1.2.3 From c7b4a53af2d2d73b8c0bb59cf851813163f65987 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 28 Jun 2017 20:11:03 -0700 Subject: log the conversation so we can debug this easier --- include/feedutils.php | 1 + 1 file changed, 1 insertion(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index a262b9562..835d739df 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -387,6 +387,7 @@ function get_atom_elements($feed, $item, &$author) { if($rawcnv) { $ostatus_conversation = normalise_id(unxmlify($rawcnv[0]['attribs']['']['ref'])); set_iconfig($res,'ostatus','conversation',$ostatus_conversation,true); + logger('ostatus_conversation: ' . $ostatus_conversation, LOGGER_DATA, LOG_INFO); } $ostatus_protocol = (($ostatus_conversation) ? true : false); -- cgit v1.2.3 From da1b10b741ec7525b9d76b2bdfaa3b794a39dde3 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 29 Jun 2017 21:09:08 -0700 Subject: forgot to return true from the conversation_fetch routine - which triggers the rescan for potential parent posts --- include/feedutils.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 835d739df..2755a7e3f 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1276,6 +1276,8 @@ function feed_conversation_fetch($importer,$contact,$parent_link) { consume_feed($data,$importer,$contact,1); consume_feed($data,$importer,$contact,2); + + return true; } -- cgit v1.2.3 From b73c844d1aec260c323715b55f2b290ce339615b Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 29 Jun 2017 22:38:43 -0700 Subject: use "Full Name (username)" for ostatus commenter xchans --- include/feedutils.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 2755a7e3f..27f189119 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()); @@ -1022,7 +1030,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; } @@ -1170,7 +1187,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; } -- cgit v1.2.3 From 64cad0a041e44940f75bf351fc3755b3202f9029 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Fri, 30 Jun 2017 00:50:57 -0700 Subject: duplicated posts after conversation fetch --- include/feedutils.php | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 27f189119..b64a98a7f 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1122,6 +1122,17 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } } + + // 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) { -- cgit v1.2.3 From f3816836e5943868cb395746cbf3310e5e4bcb7f Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 4 Jul 2017 22:05:17 -0700 Subject: some sites use the old style ostatus:conversation xml field, check for it. --- include/feedutils.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index b64a98a7f..d96735c3a 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -393,9 +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); - logger('ostatus_conversation: ' . $ostatus_conversation, LOGGER_DATA, LOG_INFO); + 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); -- cgit v1.2.3 From e3734328eb7393bbdb76ce195d735ab48aa87324 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 9 Jul 2017 17:08:25 -0700 Subject: find_parent for feeds needs more debug logging. Something is still falling through the cracks and it isn't obvious why --- include/feedutils.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index d96735c3a..8696cc867 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1009,6 +1009,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $parent_link = $rawthread[0]['attribs']['']['href']; } + logger('in-reply-to: ' . $parent_mid, LOGGER_DEBUG); + if($is_reply) { if($pass == 1) @@ -1088,6 +1090,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { intval($importer['channel_id']) ); if($c) { + logger('find_parent: matched conversation: ' . $conv_id, LOGGER_DEBUG); $pmid = $c[0]['parent_mid']; $datarray['parent_mid'] = $pmid; } @@ -1099,6 +1102,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { ); if($x) { + logger('find_parent: matched in-reply-to: ' . $parent_mid, LOGGER_DEBUG); $pmid = $x[0]['parent_mid']; $datarray['parent_mid'] = $pmid; } -- cgit v1.2.3 From ad9990e1004e58e0049768f5282d86e5e0eb2602 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 11 Jul 2017 17:31:57 -0700 Subject: even more logging of conversation parent discovery --- include/feedutils.php | 1 + 1 file changed, 1 insertion(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 8696cc867..a725e66e3 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1085,6 +1085,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { // next try thr:in_reply_to if($conv_id) { + logger('find_parent: conversation_id: ' . $conv_id, LOGGER_DEBUG); $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']) -- cgit v1.2.3 From 6db717a1a09f936f72d5c6c7643b0caa81a40667 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 12 Jul 2017 17:07:31 -0700 Subject: make websub/PuSH and salmon both use consume_feed() for item storage as there is a lot of duplication of effort and patches applied to one that haven't been applied to the other. This will require an update of addons as well or follow activities may be duplicated --- include/feedutils.php | 56 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 13 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index a725e66e3..fac2a272c 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -516,7 +516,7 @@ function get_atom_elements($feed, $item, &$author) { // turn Mastodon content warning into a #nsfw hashtag if($mastodon && $summary) { - $res['body'] .= "\n\n#nsfw\n"; + $res['body'] .= "\n\n#ContentWarning\n"; } @@ -1147,7 +1147,48 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } } - if(! $pmid) { + if($pmid) { + + // check comment permissions on the parent + + $r = q("select * from item where parent_mid = '%s' and parent_mid = mid and uid = %d limit 1" + dbesc($pmid), + intval($importer['channel_id']) + ); + if($r) { + $parent_item = $r[0]; + + if(intval($parent_item['item_nocomment']) || $parent_item['comment_policy'] === 'none' + || ($parent_item['comments_closed'] > NULL_DATE && $parent_item['comments_closed'] < datetime_convert())) { + logger('comments disabled for post ' . $parent_item['mid']); + continue; + } + + $allowed = false; + + if($parent_item) { + if($parent_item['owner_xchan'] == $importer['channel_hash']) + $allowed = perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'post_comments'); + else + $allowed = true; + + if(! $allowed) { + logger('Ignoring this comment author.'); + $status = 202; + continue; + } + } + else { + if((! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream')) && (! $importer['system'])) { + // @fixme check for and process ostatus autofriend + // otherwise + + logger('Ignoring this author.'); + continue; + } + } + } + else { // immediate parent wasn't found. Turn into a top-level post if permissions allow // but save the thread_parent in case we need to refer to it later. @@ -1198,17 +1239,6 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['author_xchan'] = ''; - if(activity_match($datarray['verb'],ACTIVITY_FOLLOW) && $datarray['obj_type'] === ACTIVITY_OBJ_PERSON) { - $cb = array('item' => $datarray,'channel' => $importer, 'xchan' => [ 'placeholder' => '' ], 'author' => $author, 'caught' => false); - call_hooks('follow_from_feed',$cb); - if($cb['caught']) { - if($cb['return_code']) - http_status_exit($cb['return_code']); - - continue; - } - } - if($author['author_link'] != $contact['xchan_url']) { $name = ''; if($author['full_name']) { -- cgit v1.2.3 From aa70cbbf21950e37ab9b5198de76ded0f1c8351d Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 12 Jul 2017 17:16:21 -0700 Subject: fix typos --- include/feedutils.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index fac2a272c..b1fcce9d3 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1151,17 +1151,19 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { // check comment permissions on the parent - $r = q("select * from item where parent_mid = '%s' and parent_mid = mid and uid = %d limit 1" + $parent_item = 0; + + $r = q("select * from item where parent_mid = '%s' and parent_mid = mid and uid = %d limit 1", dbesc($pmid), intval($importer['channel_id']) ); if($r) { $parent_item = $r[0]; - - if(intval($parent_item['item_nocomment']) || $parent_item['comment_policy'] === 'none' - || ($parent_item['comments_closed'] > NULL_DATE && $parent_item['comments_closed'] < datetime_convert())) { - logger('comments disabled for post ' . $parent_item['mid']); - continue; + if(intval($parent_item['item_nocomment']) || $parent_item['comment_policy'] === 'none' + || ($parent_item['comments_closed'] > NULL_DATE && $parent_item['comments_closed'] < datetime_convert())) { + logger('comments disabled for post ' . $parent_item['mid']); + continue; + } } $allowed = false; -- cgit v1.2.3 From e891199a23eb8839f0a6baa4b5695b058793917f Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sat, 15 Jul 2017 15:49:10 -0700 Subject: deal with mastodon privacy scopes - mark private and block commenting since we refuse to send private activities through the public OStatus connector. --- include/feedutils.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index b1fcce9d3..6ee53e2f6 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -408,8 +408,11 @@ function get_atom_elements($feed, $item, &$author) { $ostatus_protocol = (($ostatus_conversation) ? true : false); $mastodon = (($item->get_item_tags('http://mastodon.social/schema/1.0','scope')) ? true : false); - if($mastodon) + if($mastodon) { $ostatus_protocol = true; + if(($mastodon[0]['data']) && ($mastodon[0]['data'] !== 'public')) + $res['item_private'] = 1; + } $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if($apps && $apps[0]['attribs']['']['source']) { @@ -1024,6 +1027,14 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if(! $datarray['mid']) continue; + // A Mastodon privacy tag has been found. We cannot send private comments + // through the OStatus protocol, so block commenting. + + if(array_key_exists('item_private',$datarray) && intval($datarray['item_private'])) { + $datarray['public_policy'] = 'specific'; + $datarray['comment_policy'] = 'none'; + } + if($contact['xchan_network'] === 'rss') { $datarray['public_policy'] = 'specific'; $datarray['comment_policy'] = 'none'; @@ -1220,6 +1231,14 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if(! $datarray['mid']) continue; + // A Mastodon privacy tag has been found. We cannot send private comments + // through the OStatus protocol, so block commenting. + + if(array_key_exists('item_private',$datarray) && intval($datarray['item_private'])) { + $datarray['public_policy'] = 'specific'; + $datarray['comment_policy'] = 'none'; + } + if($contact['xchan_network'] === 'rss') { $datarray['public_policy'] = 'specific'; $datarray['comment_policy'] = 'none'; -- cgit v1.2.3 From c352047228126ab439ca4582995f83f119188588 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 16 Jul 2017 22:51:36 -0700 Subject: mis-attributed profile photo when Mastodon comment author has no profile photo --- include/feedutils.php | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 6ee53e2f6..be7c926d4 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1040,6 +1040,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['comment_policy'] = 'none'; } + // if we have everything but a photo, provide the default profile photo + + if($author['author_name'] && $author['author_link'] && (! $author['author_photo'])) + $author['author_photo'] = z_root() . '/' . get_default_profile_photo(80); + if((! x($author,'author_name')) || ($author['author_is_feed'])) $author['author_name'] = $contact['xchan_name']; if((! x($author,'author_link')) || ($author['author_is_feed'])) @@ -1244,6 +1249,12 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['comment_policy'] = 'none'; } + + // if we have everything but a photo, provide the default profile photo + + if($author['author_name'] && $author['author_link'] && (! $author['author_photo'])) + $author['author_photo'] = z_root() . '/' . get_default_profile_photo(80); + if(is_array($contact)) { if((! x($author,'author_name')) || ($author['author_is_feed'])) $author['author_name'] = $contact['xchan_name']; -- cgit v1.2.3 From ecb1515e5d6cd854bd64444b9c07af50df370efb Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 17 Jul 2017 19:28:27 -0700 Subject: activitystreams converters updated to recent spec --- include/feedutils.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index be7c926d4..5f2a06029 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1890,17 +1890,17 @@ function i2asld($i) { $ret = array(); - $ret['@context'] = array( 'http://www.w3.org/ns/activitystreams', 'zot' => 'http://purl.org/zot/protocol'); + $ret['@context'] = array( 'https://www.w3.org/ns/activitystreams', 'zot' => 'http://purl.org/zot/protocol'); if($i['verb']) { if(strpos(dirname($i['verb'],'activitystrea.ms/schema/1.0'))) { - $ret['@type'] = ucfirst(basename($i['verb'])); + $ret['type'] = ucfirst(basename($i['verb'])); } elseif(strpos(dirname($i['verb'],'purl.org/zot'))) { - $ret['@type'] = 'zot:' . ucfirst(basename($i['verb'])); + $ret['type'] = 'zot:' . ucfirst(basename($i['verb'])); } } - $ret['@id'] = $i['plink']; + $ret['id'] = $i['plink']; $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); @@ -1922,7 +1922,7 @@ function asencode_note($i) { $ret = array(); $ret['@type'] = 'Note'; - $ret['@id'] = $i['plink']; + $ret['id'] = $i['plink']; if($i['title']) $ret['title'] = bbcode($i['title']); @@ -1938,16 +1938,18 @@ function asencode_note($i) { function asencode_person($p) { $ret = array(); - $ret['@type'] = 'Person'; - $ret['@id'] = 'acct:' . $p['xchan_addr']; - $ret['displayName'] = $p['xchan_name']; - $ret['icon'] = array( - '@type' => 'Link', + $ret['type'] = 'Person'; + $ret['id'] = $p['xchan_url']; + $ret['name'] = $p['xchan_name']; + $ret['image'] = array( + 'type' => 'Link', 'mediaType' => $p['xchan_photo_mimetype'], - 'href' => $p['xchan_photo_m'] + 'href' => $p['xchan_photo_l'], + 'height' => 300, + 'width' => 300 ); $ret['url'] = array( - '@type' => 'Link', + 'type' => 'Link', 'mediaType' => 'text/html', 'href' => $p['xchan_url'] ); -- cgit v1.2.3 From d8c93c0d13133d336e2cc3dbf3c48e0a6350c2d6 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 17 Jul 2017 22:17:40 -0700 Subject: activitypub, cont. --- include/feedutils.php | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 5f2a06029..b31448d81 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1937,22 +1937,34 @@ function asencode_note($i) { function asencode_person($p) { - $ret = array(); - $ret['type'] = 'Person'; - $ret['id'] = $p['xchan_url']; - $ret['name'] = $p['xchan_name']; - $ret['image'] = array( - 'type' => 'Link', + $ret = []; + $ret['type'] = 'Person'; + $ret['id'] = $p['xchan_url']; + $ret['name'] = $p['xchan_name']; + $ret['icon'] = [ $p['xchan_photo_l'] ]; + $ret['image'] = [ + 'type' => 'Link', 'mediaType' => $p['xchan_photo_mimetype'], - 'href' => $p['xchan_photo_l'], - 'height' => 300, - 'width' => 300 - ); - $ret['url'] = array( - 'type' => 'Link', + 'href' => $p['xchan_photo_l'], + 'height' => 300, + 'width' => 300 + ]; + $ret['url'] = [ + 'type' => 'Link', 'mediaType' => 'text/html', - 'href' => $p['xchan_url'] - ); + 'href' => $p['xchan_url'] + ]; + + if(array_key_exists('channel_id',$p)) { + $ret['inbox'] = z_root() . '/inbox/' . $p['channel_address']; + $ret['outbox'] = z_root() . '/outbox/' . $p['channel_address']; + } + else { + $collections = get_xconfig($p['xchan_hash'],'activitystreams','collections',[]); + if($collections) { + $ret = array_merge($ret,$collections); + } + } return $ret; } -- cgit v1.2.3 From 9daa3b85c8b3ee48222a4b6c7c7ba70a3ca57fbb Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 17 Jul 2017 22:52:19 -0700 Subject: some corrections to AS encoding based on the current spec (some of this work was completed long before the spec settled). --- include/feedutils.php | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index b31448d81..daab1a741 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1941,13 +1941,28 @@ function asencode_person($p) { $ret['type'] = 'Person'; $ret['id'] = $p['xchan_url']; $ret['name'] = $p['xchan_name']; - $ret['icon'] = [ $p['xchan_photo_l'] ]; - $ret['image'] = [ - 'type' => 'Link', - 'mediaType' => $p['xchan_photo_mimetype'], - 'href' => $p['xchan_photo_l'], - 'height' => 300, - 'width' => 300 + $ret['icon'] = [ + [ + 'type' => 'Image', + 'mediaType' => $p['xchan_photo_mimetype'], + 'url' => $p['xchan_photo_l'], + 'height' => 300, + 'width' => 300, + ], + [ + 'type' => 'Image', + 'mediaType' => $p['xchan_photo_mimetype'], + 'url' => $p['xchan_photo_m'], + 'height' => 80, + 'width' => 80, + ], + [ + 'type' => 'Image', + 'mediaType' => $p['xchan_photo_mimetype'], + 'url' => $p['xchan_photo_l'], + 'height' => 48, + 'width' => 48, + ] ]; $ret['url'] = [ 'type' => 'Link', -- cgit v1.2.3 From 6103c301848105a3bca3de81e9982276b2c38d76 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 18 Jul 2017 21:16:18 -0700 Subject: provide optional salmon signatures for AP entities --- include/feedutils.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index daab1a741..5d537553f 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1973,6 +1973,14 @@ function asencode_person($p) { if(array_key_exists('channel_id',$p)) { $ret['inbox'] = z_root() . '/inbox/' . $p['channel_address']; $ret['outbox'] = z_root() . '/outbox/' . $p['channel_address']; + $ret['me:magic_keys'] = [ + [ + 'value' => salmon_key($p['channel_pubkey']), + 'key_id' => base64url_encode(hash('sha256',salmon_key($p['channel_pubkey'])),true) + ] + ]; + + } else { $collections = get_xconfig($p['xchan_hash'],'activitystreams','collections',[]); -- cgit v1.2.3 From ceeb9836b98c8a854fe6501fd51c3de7c4c91655 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 19 Jul 2017 20:31:11 -0700 Subject: implement update_feed_item --- include/feedutils.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 5d537553f..9a70fdae4 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1073,7 +1073,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['owner_xchan'] = $contact['xchan_hash']; - $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", + $r = q("SELECT id, edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($datarray['mid']), intval($importer['channel_id']) ); @@ -1089,7 +1089,12 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) continue; + $datarray['uid'] = $importer['channel_id']; + $datarray['aid'] = $importer['channel_account_id']; + $datarray['id'] = $r[0]['id']; + update_feed_item($importer['channel_id'],$datarray); + } continue; } @@ -1300,7 +1305,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } - $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", + $r = q("SELECT id, edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($datarray['mid']), intval($importer['channel_id']) ); @@ -1315,6 +1320,10 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) continue; + $datarray['uid'] = $importer['channel_id']; + $datarray['aid'] = $importer['channel_account_id']; + $datarray['id'] = $r[0]['id']; + update_feed_item($importer['channel_id'],$datarray); } @@ -1555,7 +1564,7 @@ function feed_meta($xml) { * @param array $datarray */ function update_feed_item($uid, $datarray) { - logger('Not implemented! ' . $uid . ' ' . print_r($datarray, true), LOGGER_DATA); + item_store_update($datarray); } /** -- cgit v1.2.3 From 89d21c08735ad9bb151acee5ee1f372a803e2213 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 20 Jul 2017 22:55:04 -0700 Subject: begin the tedious process of mapping activities between AS1, zot, and AS2 --- include/feedutils.php | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 9a70fdae4..4f68fdeef 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -2001,3 +2001,52 @@ function asencode_person($p) { return $ret; } + +function activity_mapper($verb) { + + $acts = [ + 'http://activitystrea.ms/schema/1.0/post' => 'Create', + 'http://activitystrea.ms/schema/1.0/update' => 'Update', + 'http://activitystrea.ms/schema/1.0/like' => 'Like', + 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', + 'http://purl.org/zot/activity/dislike' => 'Dislike', + 'http://activitystrea.ms/schema/1.0/tag' => 'Add', + 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', + 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', + ]; + + + if(array_key_exists($acts[$verb])) { + return $acts[$verb]; + } + return false; +} + + +function activity_obj_mapper($obj,$reverse = false) { + + $objs = [ + 'http://activitystrea.ms/schema/1.0/note' => 'Note', + 'http://activitystrea.ms/schema/1.0/comment' => 'Note', + 'http://activitystrea.ms/schema/1.0/person' => 'Person', + 'http://purl.org/zot/activity/profile' => 'Profile', + 'http://activitystrea.ms/schema/1.0/photo' => 'Image', + 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', + 'http://activitystrea.ms/schema/1.0/event' => 'Event', + 'http://activitystrea.ms/schema/1.0/wiki' => 'Document', + 'http://purl.org/zot/activity/location' => 'Place', + 'http://purl.org/zot/activity/chessgame' => 'Game', + 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', + 'http://purl.org/zot/activity/thing' => 'zot:Thing', + 'http://purl.org/zot/activity/file' => 'zot:File', + 'http://purl.org/zot/activity/poke' => 'zot:Action', + 'http://purl.org/zot/activity/react' => 'zot:Reaction', + 'http://purl.org/zot/activity/mood' => 'zot:Mood', + + ]; + + if(array_key_exists($objs[$verb])) { + return $objs[$verb]; + } + return false; +} -- cgit v1.2.3 From d3d184192d93e614bbcf31f6149084e8489befe0 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 26 Jul 2017 17:38:34 -0700 Subject: issue with OStatus comments being propagated downstream --- include/feedutils.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index 4f68fdeef..dbf60f553 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -999,6 +999,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { foreach($items as $item) { $is_reply = false; + $send_downstream = false; $parent_link = ''; logger('processing ' . $item->get_id(), LOGGER_DEBUG); @@ -1200,6 +1201,15 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $status = 202; continue; } + + // The salmon endpoint sets this to indicate that we should send comments from + // interactive feeds (such as OStatus) downstream to our followers + // We do not want to set it for non-interactive feeds or conversations we do not own + + if(array_key_exists('send_downstream',$importer) && intval($importer['send_downstream']) + && ($parent_item['owner_xchan'] == $importer['channel_hash'])) { + $send_downstream = true; + } } else { if((! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream')) && (! $importer['system'])) { @@ -1229,6 +1239,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $xx = item_store($datarray); $r = $xx['item_id']; + + if($send_downstream) { + \Zotlabs\Daemon\Master::Summon(array('Notifier', 'comment', $r)); + } + continue; } else { -- cgit v1.2.3 From 75d63684b8c6ee7bd6ef53a1981319f3235ff7dc Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 26 Jul 2017 16:39:13 -0700 Subject: remove activitypub components from core --- include/feedutils.php | 182 -------------------------------------------------- 1 file changed, 182 deletions(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index dbf60f553..eb24f9032 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1883,185 +1883,3 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $ return $x['entry']; } -/** - * @brief - * - * @param array $items - * @return array - */ -function gen_asld($items) { - $ret = array(); - if(! $items) - return $ret; - - foreach($items as $item) { - $ret[] = i2asld($item); - } - - return $ret; -} - -/** - * @brief - * - * @param array $i - * @return array - */ -function i2asld($i) { - - if(! $i) - return array(); - - $ret = array(); - - $ret['@context'] = array( 'https://www.w3.org/ns/activitystreams', 'zot' => 'http://purl.org/zot/protocol'); - - if($i['verb']) { - if(strpos(dirname($i['verb'],'activitystrea.ms/schema/1.0'))) { - $ret['type'] = ucfirst(basename($i['verb'])); - } - elseif(strpos(dirname($i['verb'],'purl.org/zot'))) { - $ret['type'] = 'zot:' . ucfirst(basename($i['verb'])); - } - } - $ret['id'] = $i['plink']; - - $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); - - // we need to pass the parent into this -// if($i['id'] != $i['parent'] && $i['obj_type'] === ACTIVITY_OBJ_NOTE) { -// $ret['inReplyTo'] = asencode_note -// } - - if($i['obj_type'] === ACTIVITY_OBJ_NOTE) - $ret['object'] = asencode_note($i); - - $ret['actor'] = asencode_person($i['author']); - - return $ret; -} - -function asencode_note($i) { - - $ret = array(); - - $ret['@type'] = 'Note'; - $ret['id'] = $i['plink']; - if($i['title']) - $ret['title'] = bbcode($i['title']); - - $ret['content'] = bbcode($i['body']); - $ret['zot:owner'] = asencode_person($i['owner']); - $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); - if($i['created'] !== $i['edited']) - $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); - - return $ret; -} - - -function asencode_person($p) { - $ret = []; - $ret['type'] = 'Person'; - $ret['id'] = $p['xchan_url']; - $ret['name'] = $p['xchan_name']; - $ret['icon'] = [ - [ - 'type' => 'Image', - 'mediaType' => $p['xchan_photo_mimetype'], - 'url' => $p['xchan_photo_l'], - 'height' => 300, - 'width' => 300, - ], - [ - 'type' => 'Image', - 'mediaType' => $p['xchan_photo_mimetype'], - 'url' => $p['xchan_photo_m'], - 'height' => 80, - 'width' => 80, - ], - [ - 'type' => 'Image', - 'mediaType' => $p['xchan_photo_mimetype'], - 'url' => $p['xchan_photo_l'], - 'height' => 48, - 'width' => 48, - ] - ]; - $ret['url'] = [ - 'type' => 'Link', - 'mediaType' => 'text/html', - 'href' => $p['xchan_url'] - ]; - - if(array_key_exists('channel_id',$p)) { - $ret['inbox'] = z_root() . '/inbox/' . $p['channel_address']; - $ret['outbox'] = z_root() . '/outbox/' . $p['channel_address']; - $ret['me:magic_keys'] = [ - [ - 'value' => salmon_key($p['channel_pubkey']), - 'key_id' => base64url_encode(hash('sha256',salmon_key($p['channel_pubkey'])),true) - ] - ]; - - - } - else { - $collections = get_xconfig($p['xchan_hash'],'activitystreams','collections',[]); - if($collections) { - $ret = array_merge($ret,$collections); - } - } - - return $ret; -} - - -function activity_mapper($verb) { - - $acts = [ - 'http://activitystrea.ms/schema/1.0/post' => 'Create', - 'http://activitystrea.ms/schema/1.0/update' => 'Update', - 'http://activitystrea.ms/schema/1.0/like' => 'Like', - 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', - 'http://purl.org/zot/activity/dislike' => 'Dislike', - 'http://activitystrea.ms/schema/1.0/tag' => 'Add', - 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', - 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', - ]; - - - if(array_key_exists($acts[$verb])) { - return $acts[$verb]; - } - return false; -} - - -function activity_obj_mapper($obj,$reverse = false) { - - $objs = [ - 'http://activitystrea.ms/schema/1.0/note' => 'Note', - 'http://activitystrea.ms/schema/1.0/comment' => 'Note', - 'http://activitystrea.ms/schema/1.0/person' => 'Person', - 'http://purl.org/zot/activity/profile' => 'Profile', - 'http://activitystrea.ms/schema/1.0/photo' => 'Image', - 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', - 'http://activitystrea.ms/schema/1.0/event' => 'Event', - 'http://activitystrea.ms/schema/1.0/wiki' => 'Document', - 'http://purl.org/zot/activity/location' => 'Place', - 'http://purl.org/zot/activity/chessgame' => 'Game', - 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', - 'http://purl.org/zot/activity/thing' => 'zot:Thing', - 'http://purl.org/zot/activity/file' => 'zot:File', - 'http://purl.org/zot/activity/poke' => 'zot:Action', - 'http://purl.org/zot/activity/react' => 'zot:Reaction', - 'http://purl.org/zot/activity/mood' => 'zot:Mood', - - ]; - - if(array_key_exists($objs[$verb])) { - return $objs[$verb]; - } - return false; -} -- cgit v1.2.3 From a3fef34a3f542905247031d0dfd7ec661fbefd1c Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 30 Jul 2017 16:15:34 -0700 Subject: provide a better "is_commentable" default for OStatus conversations that were fetched on the fly --- include/feedutils.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index eb24f9032..e3f899a1e 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1028,6 +1028,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if(! $datarray['mid']) continue; + // This probably isn't an appropriate default but we're about to change it + // if it's wrong. + + $datarray['comment_policy'] = 'authenticated'; + // A Mastodon privacy tag has been found. We cannot send private comments // through the OStatus protocol, so block commenting. @@ -1256,6 +1261,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if(! $datarray['mid']) continue; + // This probably isn't an appropriate default but we're about to change it + // if it's wrong. + + $datarray['comment_policy'] = 'authenticated'; + // A Mastodon privacy tag has been found. We cannot send private comments // through the OStatus protocol, so block commenting. @@ -1270,6 +1280,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } + // if we have everything but a photo, provide the default profile photo if($author['author_name'] && $author['author_link'] && (! $author['author_photo'])) @@ -1493,7 +1504,7 @@ function process_salmon_feed($xml, $importer) { // reset policies which are restricted by default for RSS connections // This item is likely coming from GNU-social via salmon and allows public interaction $datarray['public_policy'] = ''; - $datarray['comment_policy'] = ''; + $datarray['comment_policy'] = 'authenticated'; $ret['item'] = $datarray; } -- cgit v1.2.3 From 037e1edb1fd2e56f776d0f86f0023141949154cf Mon Sep 17 00:00:00 2001 From: zotlabs Date: Sun, 6 Aug 2017 19:33:51 -0700 Subject: ostatus feed was missing comments --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/feedutils.php') diff --git a/include/feedutils.php b/include/feedutils.php index e3f899a1e..07cb79340 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -115,7 +115,7 @@ function get_feed_for($channel, $observer_hash, $params) { $items = items_fetch( [ - 'wall' => '1', + 'wall' => '1', 'datequery' => $params['end'], 'datequery2' => $params['begin'], 'start' => intval($params['start']), -- cgit v1.2.3