X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FOStatus.php;h=d6a2f2dad1ce3b8cb8bb180087ba2a377afa3c7f;hb=5cf71baf551bf209e62cf13b16173bddcd76a0fc;hp=1efbb0bf39a610f50883773d1b7520ea285bf116;hpb=121607b8d943fd57e6fe3f6219c8d925f1be423d;p=friendica.git diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 1efbb0bf39..d6a2f2dad1 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -1,6 +1,6 @@ $importer['uid'], + 'network' => Protocol::OSTATUS, + 'wall' => 0, + 'origin' => 0, + 'gravity' => Item::GRAVITY_COMMENT, + ]; if (!is_object($doc->firstChild) || empty($doc->firstChild->tagName)) { return false; @@ -497,9 +498,9 @@ class OStatus $orig_uri = $xpath->query('activity:object/atom:id', $entry)->item(0)->nodeValue; Logger::notice('Favorite', ['uri' => $orig_uri, 'item' => $item]); - $item['verb'] = Activity::LIKE; + $item['body'] = $item['verb'] = Activity::LIKE; $item['thr-parent'] = $orig_uri; - $item['gravity'] = GRAVITY_ACTIVITY; + $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['object-type'] = Activity\ObjectType::NOTE; } @@ -616,16 +617,16 @@ class OStatus $item['created'] = XML::getFirstNodeValue($xpath, 'atom:published/text()', $entry); $item['edited'] = XML::getFirstNodeValue($xpath, 'atom:updated/text()', $entry); - $item['conversation-uri'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry); + $item['conversation'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry); $conv = $xpath->query('ostatus:conversation', $entry); if (is_object($conv->item(0))) { foreach ($conv->item(0)->attributes as $attributes) { if ($attributes->name == 'ref') { - $item['conversation-uri'] = $attributes->textContent; + $item['conversation'] = $attributes->textContent; } if ($attributes->name == 'href') { - $item['conversation-href'] = $attributes->textContent; + $item['conversation'] = $attributes->textContent; } } } @@ -704,14 +705,6 @@ class OStatus } } - if (($self != '') && empty($item['protocol'])) { - self::fetchSelf($self, $item); - } - - if (!empty($item['conversation-href'])) { - self::fetchConversation($item['conversation-href'], $item['conversation-uri']); - } - if (isset($item['thr-parent'])) { if (!Post::exists(['uid' => $importer['uid'], 'uri' => $item['thr-parent']])) { if ($related != '') { @@ -722,197 +715,12 @@ class OStatus } } else { $item['thr-parent'] = $item['uri']; - $item['gravity'] = GRAVITY_PARENT; - } - - if (($item['author-link'] != '') && !empty($item['protocol'])) { - $item = Conversation::insert($item); + $item['gravity'] = Item::GRAVITY_PARENT; } self::$itemlist[] = $item; } - /** - * Fetch the conversation for posts - * - * @param string $conversation The link to the conversation - * @param string $conversation_uri The conversation in "uri" format - * @return void - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function fetchConversation(string $conversation, string $conversation_uri) - { - // Ensure that we only store a conversation once in a process - if (isset(self::$conv_list[$conversation])) { - return; - } - - self::$conv_list[$conversation] = true; - - $curlResult = DI::httpClient()->get($conversation, HttpClientAccept::ATOM_XML); - - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { - return; - } - - $xml = ''; - - if ($curlResult->inHeader('Content-Type') && - in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) { - $xml = $curlResult->getBody(); - } - - if ($xml == '') { - $doc = new DOMDocument(); - if (!@$doc->loadHTML($curlResult->getBody())) { - return; - } - $xpath = new DOMXPath($doc); - - $links = $xpath->query('//link'); - if ($links) { - $file = ''; - foreach ($links as $link) { - $attribute = self::readAttributes($link); - if (($attribute['rel'] == 'alternate') && ($attribute['type'] == 'application/atom+xml')) { - $file = $attribute['href']; - } - } - if ($file != '') { - $conversation_atom = DI::httpClient()->get($attribute['href'], HttpClientAccept::ATOM_XML); - - if ($conversation_atom->isSuccess()) { - $xml = $conversation_atom->getBody(); - } - } - } - } - - if ($xml == '') { - return; - } - - self::storeConversation($xml, $conversation, $conversation_uri); - } - - /** - * Store a feed in several conversation entries - * - * @param string $xml The feed - * @param string $conversation conversation - * @param string $conversation_uri conversation uri - * @return void - * @throws \Exception - */ - private static function storeConversation(string $xml, string $conversation = '', string $conversation_uri = '') - { - $doc = new DOMDocument(); - @$doc->loadXML($xml); - - $xpath = new DOMXPath($doc); - $xpath->registerNamespace('atom', ActivityNamespace::ATOM1); - $xpath->registerNamespace('thr', ActivityNamespace::THREAD); - $xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS); - - $entries = $xpath->query('/atom:feed/atom:entry'); - - // Now store the entries - foreach ($entries as $entry) { - $doc2 = new DOMDocument(); - $doc2->preserveWhiteSpace = false; - $doc2->formatOutput = true; - - $conv_data = []; - - $conv_data['protocol'] = Conversation::PARCEL_SPLIT_CONVERSATION; - $conv_data['direction'] = Conversation::PULL; - $conv_data['network'] = Protocol::OSTATUS; - $conv_data['uri'] = XML::getFirstNodeValue($xpath, 'atom:id/text()', $entry); - - $inreplyto = $xpath->query('thr:in-reply-to', $entry); - if (is_object($inreplyto->item(0))) { - foreach ($inreplyto->item(0)->attributes as $attributes) { - if ($attributes->name == 'ref') { - $conv_data['reply-to-uri'] = $attributes->textContent; - } - } - } - - $conv_data['conversation-uri'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry); - - $conv = $xpath->query('ostatus:conversation', $entry); - if (is_object($conv->item(0))) { - foreach ($conv->item(0)->attributes as $attributes) { - if ($attributes->name == 'ref') { - $conv_data['conversation-uri'] = $attributes->textContent; - } - if ($attributes->name == 'href') { - $conv_data['conversation-href'] = $attributes->textContent; - } - } - } - - if ($conversation != '') { - $conv_data['conversation-uri'] = $conversation; - } - - if ($conversation_uri != '') { - $conv_data['conversation-uri'] = $conversation_uri; - } - - $entry = $doc2->importNode($entry, true); - - $doc2->appendChild($entry); - - $conv_data['source'] = $doc2->saveXML(); - - Logger::info('Store conversation data for uri '.$conv_data['uri']); - Conversation::insert($conv_data); - } - } - - /** - * Fetch the own post so that it can be stored later - * - * We want to store the original data for later processing. - * This function is meant for cases where we process a feed with multiple entries. - * In that case we need to fetch the single posts here. - * - * @param string $self The link to the self item - * @param array $item The item array - * @return void - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function fetchSelf(string $self, array &$item) - { - $condition = ['item-uri' => $self, 'protocol' => [Conversation::PARCEL_DFRN, - Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LOCAL_DFRN, - Conversation::PARCEL_DIRECT, Conversation::PARCEL_SALMON]]; - if (DBA::exists('conversation', $condition)) { - Logger::info('Conversation '.$item['uri'].' is already stored.'); - return; - } - - $curlResult = DI::httpClient()->get($self, HttpClientAccept::ATOM_XML); - - if (!$curlResult->isSuccess()) { - return; - } - - // We reformat the XML to make it better readable - $doc = new DOMDocument(); - $doc->loadXML($curlResult->getBody()); - $doc->preserveWhiteSpace = false; - $doc->formatOutput = true; - $xml = $doc->saveXML(); - - $item['protocol'] = Conversation::PARCEL_SALMON; - $item['source'] = $xml; - $item['direction'] = Conversation::PULL; - - Logger::info('Conversation '.$item['uri'].' is now fetched.'); - } - /** * Fetch related posts and processes them * @@ -925,30 +733,6 @@ class OStatus */ private static function fetchRelated(string $related, string $related_uri, array $importer) { - $condition = [ - 'item-uri' => $related_uri, - 'protocol' => [ - Conversation::PARCEL_DFRN, - Conversation::PARCEL_DIASPORA_DFRN, - Conversation::PARCEL_LOCAL_DFRN, - Conversation::PARCEL_DIRECT, - Conversation::PARCEL_SALMON, - ], - ]; - $conversation = DBA::selectFirst('conversation', ['source', 'protocol'], $condition); - if (DBA::isResult($conversation)) { - $stored = true; - $xml = $conversation['source']; - if (self::process($xml, $importer, $contact, $hub, $stored, false, Conversation::PULL)) { - Logger::info('Got valid cached XML for URI '.$related_uri); - return; - } - if ($conversation['protocol'] == Conversation::PARCEL_SALMON) { - Logger::info('Delete invalid cached XML for URI '.$related_uri); - DBA::delete('conversation', ['item-uri' => $related_uri]); - } - } - $stored = false; $curlResult = DI::httpClient()->get($related, HttpClientAccept::ATOM_XML); @@ -1013,18 +797,8 @@ class OStatus } } - // Finally we take the data that we fetched from "ostatus:conversation" - if ($xml == '') { - $condition = ['item-uri' => $related_uri, 'protocol' => Conversation::PARCEL_SPLIT_CONVERSATION]; - $conversation = DBA::selectFirst('conversation', ['source'], $condition); - if (DBA::isResult($conversation)) { - $stored = true; - Logger::info('Got cached XML from conversation for URI ' . $related_uri); - $xml = $conversation['source']; - } - } - if ($xml != '') { + $hub = ''; self::process($xml, $importer, $contact, $hub, $stored, false, Conversation::PULL); } else { Logger::info('XML could not be fetched for URI: ' . $related_uri . ' - href: ' . $related); @@ -1130,10 +904,7 @@ class OStatus case 'ostatus:conversation': $link_data['conversation'] = $attribute['href']; - $item['conversation-href'] = $link_data['conversation']; - if (!isset($item['conversation-uri'])) { - $item['conversation-uri'] = $item['conversation-href']; - } + $item['conversation'] = $link_data['conversation']; break; case 'enclosure': @@ -1168,7 +939,7 @@ class OStatus break; default: - Logger::warning('Unsupported rel=' . $attribute['rel'] . ', href=' . $attribute['href'] . ', object-type=' . $item['object-type']); + Logger::notice('Unsupported rel=' . $attribute['rel'] . ', href=' . $attribute['href'] . ', object-type=' . $item['object-type']); } } } @@ -1207,44 +978,6 @@ class OStatus } } - /** - * Cleans the body of a post if it contains picture links - * - * @param string $body The body - * @param integer $uriId - * @return string The cleaned body - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - public static function formatPicturePost(string $body, int $uriid): string - { - $siteinfo = BBCode::getAttachedData($body); - - if (($siteinfo['type'] == 'photo') && (!empty($siteinfo['preview']) || !empty($siteinfo['image']))) { - if (isset($siteinfo['preview'])) { - $preview = $siteinfo['preview']; - } else { - $preview = $siteinfo['image']; - } - - // Is it a remote picture? Then make a smaller preview here - $preview = Post\Link::getByLink($uriid, $preview, Proxy::SIZE_SMALL); - - // Is it a local picture? Then make it smaller here - $preview = str_replace(['-0.jpg', '-0.png'], ['-2.jpg', '-2.png'], $preview); - $preview = str_replace(['-1.jpg', '-1.png'], ['-2.jpg', '-2.png'], $preview); - - if (isset($siteinfo['url'])) { - $url = $siteinfo['url']; - } else { - $url = $siteinfo['image']; - } - - $body = trim($siteinfo['text']) . ' [url]' . $url . "[/url]\n[img]" . $preview . '[/img]'; - } - - return $body; - } - /** * Adds the header elements to the XML document * @@ -1291,9 +1024,9 @@ class OStatus $attributes = [ 'uri' => 'https://friendi.ca', - 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, + 'version' => App::VERSION . '-' . DB_UPDATE_VERSION, ]; - XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes); + XML::addElement($doc, $root, 'generator', App::PLATFORM, $attributes); XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']); XML::addElement($doc, $root, 'title', $title); XML::addElement($doc, $root, 'subtitle', sprintf("Updates from %s on %s", $owner['name'], DI::config()->get('config', 'sitename'))); @@ -1371,55 +1104,7 @@ class OStatus */ public static function getAttachment(DOMDocument $doc, DOMElement $root, array $item) { - $siteinfo = BBCode::getAttachedData($item['body']); - - switch ($siteinfo['type']) { - case 'photo': - if (!empty($siteinfo['image'])) { - $imgdata = Images::getInfoFromURLCached($siteinfo['image']); - if ($imgdata) { - $attributes = [ - 'rel' => 'enclosure', - 'href' => $siteinfo['image'], - 'type' => $imgdata['mime'], - 'length' => intval($imgdata['size']), - ]; - XML::addElement($doc, $root, 'link', '', $attributes); - } - } - break; - - case 'video': - $attributes = [ - 'rel' => 'enclosure', - 'href' => $siteinfo['url'], - 'type' => 'text/html; charset=UTF-8', - 'length' => '0', - 'title' => ($siteinfo['title'] ?? '') ?: $siteinfo['url'], - ]; - XML::addElement($doc, $root, 'link', '', $attributes); - break; - - default: - Logger::warning('Unsupported type', ['type' => $siteinfo['type'], 'url' => $siteinfo['url'] ?? '']); - break; - } - - if (!DI::config()->get('system', 'ostatus_not_attach_preview') && ($siteinfo['type'] != 'photo') && isset($siteinfo['image'])) { - $imgdata = Images::getInfoFromURLCached($siteinfo['image']); - if ($imgdata) { - $attributes = [ - 'rel' => 'enclosure', - 'href' => $siteinfo['image'], - 'type' => $imgdata['mime'], - 'length' => intval($imgdata['size']), - ]; - - XML::addElement($doc, $root, 'link', '', $attributes); - } - } - - foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT, Post\Media::UNKNOWN]) as $attachment) { + foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO, Post\Media::DOCUMENT, Post\Media::TORRENT]) as $attachment) { $attributes = ['rel' => 'enclosure', 'href' => $attachment['url'], 'type' => $attachment['mimetype']]; @@ -1593,7 +1278,7 @@ class OStatus */ private static function likeEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement { - if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { + if (($item['gravity'] != Item::GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.'); } @@ -1712,8 +1397,8 @@ class OStatus } $item['uri'] = $item['parent-uri'] = $item['thr-parent'] - = 'tag:' . DI::baseUrl()->getHostname(). - ','.date('Y-m-d').':'.$action.':'.$owner['uid']. + = 'tag:' . DI::baseUrl()->getHost() . + ','.date('Y-m-d').':'.$action.':'.$owner['uid']. ':person:'.$connect_id.':'.$item['created']; $item['body'] = sprintf($message, $owner['nick'], $contact['nick']); @@ -1743,7 +1428,7 @@ class OStatus */ private static function noteEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement { - if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { + if (($item['gravity'] != Item::GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.'); } @@ -1785,8 +1470,10 @@ class OStatus $entry = $doc->createElement('entry'); if ($owner['contact-type'] == Contact::TYPE_COMMUNITY) { + $entry->setAttribute('xmlns:activity', ActivityNamespace::ACTIVITY); + $contact = Contact::getByURL($item['author-link']) ?: $owner; - $contact['nickname'] = $contact['nickname'] ?? $contact['nick']; + $contact['nickname'] = $contact['nickname'] ?? $contact['nick']; $author = self::addAuthor($doc, $contact, false); $entry->appendChild($author); } @@ -1831,8 +1518,8 @@ class OStatus XML::addElement($doc, $entry, 'id', $item['uri']); XML::addElement($doc, $entry, 'title', html_entity_decode($title, ENT_QUOTES, 'UTF-8')); - $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); - $body = self::formatPicturePost($body, $item['uri-id']); + $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item)); + $body = Post\Media::addHTMLLinkToBody($item['uri-id'], $body); if (!empty($item['title'])) { $body = '[b]' . $item['title'] . "[/b]\n\n" . $body; @@ -1873,7 +1560,7 @@ class OStatus { $mentioned = []; - if ($item['gravity'] != GRAVITY_PARENT) { + if ($item['gravity'] != Item::GRAVITY_PARENT) { $parent = Post::selectFirst(['guid', 'author-link', 'owner-link'], ['id' => $item['parent']]); $thrparent = Post::selectFirst(['guid', 'author-link', 'owner-link', 'plink'], ['uid' => $owner['uid'], 'uri' => $item['thr-parent']]); @@ -1904,19 +1591,7 @@ class OStatus } if (intval($item['parent']) > 0) { - $conversation_href = $conversation_uri = str_replace('/objects/', '/context/', $item['thr-parent']); - - if (isset($parent_item)) { - $conversation = DBA::selectFirst('conversation', ['conversation-uri', 'conversation-href'], ['item-uri' => $parent_item]); - if (DBA::isResult($conversation)) { - if ($conversation['conversation-uri'] != '') { - $conversation_uri = $conversation['conversation-uri']; - } - if ($conversation['conversation-href'] != '') { - $conversation_href = $conversation['conversation-href']; - } - } - } + $conversation_href = $conversation_uri = $item['conversation']; XML::addElement($doc, $entry, 'link', '', ['rel' => 'ostatus:conversation', 'href' => $conversation_href]); @@ -2038,7 +1713,7 @@ class OStatus $previous_created = $last_update; - // Don't cache when the last item was posted less then 15 minutes ago (Cache duration) + // Don't cache when the last item was posted less than 15 minutes ago (Cache duration) if ((time() - strtotime($owner['last-item'])) < 15*60) { $result = DI::cache()->get($cachekey); if (!$nocache && !is_null($result)) {