From b1029869295e50040dba2cdc33c9ca797ca76ffb Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 04:38:17 -0700 Subject: greatly simplify consume_feed() - a lot of this was friendica specific and somebody may want to put some of it back in, but we'd be much better off building a zot compatible feed for friendica (hint,hint) - even if it didn't support the other protocol bits. Special purpose feed handlers for things like likes, dislikes, events, and community tags are better handled as zot arrays. We have all those handlers. We just need to pass them a JSON message instead of an XML/Atom message. Handlers for statusnet follow messages are another casualty. That's easy to bring back - but we need to keep driving nails into the XML coffin or the damn zombies will get out. --- include/items.php | 244 +++++++++++------------------------------------------- version.inc | 2 +- 2 files changed, 50 insertions(+), 196 deletions(-) diff --git a/include/items.php b/include/items.php index 30a685ed3..03b493bc3 100755 --- a/include/items.php +++ b/include/items.php @@ -3019,10 +3019,6 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { $feed = new SimplePie(); $feed->set_raw_data($xml); - if($datedir) - $feed->enable_order_by_date(true); - else - $feed->enable_order_by_date(false); $feed->init(); if($feed->error()) @@ -3032,7 +3028,6 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { // Check at the feed level for updated contact name and/or photo - // process any deleted entries $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry'); @@ -3052,41 +3047,18 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { if($deleted && is_array($contact)) { -/* - $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join `contact` on `item`.`contact-id` = `contact`.`id` - WHERE `mid` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", + $r = q("SELECT * from item where mid = '%s' and author_xchan = '%s' and uid = %d limit 1", dbesc($mid), - intval($importer['channel_id']), - intval($contact['id']) + dbesc($contact['xchan_hash']), + intval($importer['channel_id']) ); -*/ - if(count($r)) { + + if($r) { $item = $r[0]; - if(! $item['deleted']) + if(! ($item['item_restrict'] & ITEM_DELETED)) { logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . $item['mid'], LOGGER_DEBUG); - - if($item['mid'] == $item['parent_mid']) { - $r = q("UPDATE `item` SET item_restrict = (item_restrict | %d), `edited` = '%s', `changed` = '%s', - `body` = '', `title` = '' - WHERE `parent_mid` = '%s' AND `uid` = %d", - intval(ITEM_DELETED), - dbesc($when), - dbesc(datetime_convert()), - dbesc($item['mid']), - intval($importer['channel_id']) - ); - } - else { - $r = q("UPDATE `item` SET item_restrict = ( item_restrict | %d ), `edited` = '%s', `changed` = '%s', - `body` = '', `title` = '' - WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", - intval(ITEM_DELETED), - dbesc($when), - dbesc(datetime_convert()), - dbesc($mid), - intval($importer['channel_id']) - ); + drop_item($item['id'],false); } } } @@ -3097,21 +3069,16 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { if($feed->get_item_quantity()) { - logger('consume_feed: feed item count = ' . $feed->get_item_quantity()); - - // in inverse date order - if ($datedir) - $items = array_reverse($feed->get_items()); - else - $items = $feed->get_items(); + logger('consume_feed: feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); + $items = $feed->get_items(); foreach($items as $item) { $is_reply = false; $item_id = $item->get_id(); -logger('consume_feed: processing ' . $item_id); + logger('consume_feed: processing ' . $item_id, LOGGER_DEBUG); $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); if(isset($rawthread[0]['attribs']['']['ref'])) { @@ -3130,21 +3097,14 @@ logger('consume_feed: processing ' . $item_id); $item_id = $item->get_id(); $datarray = get_atom_elements($feed,$item); -/* - if((! x($datarray,'author-name')) && ($contact['network'] != NETWORK_DFRN)) - $datarray['author-name'] = $contact['name']; - if((! x($datarray,'author-link')) && ($contact['network'] != NETWORK_DFRN)) - $datarray['author-link'] = $contact['url']; - if((! x($datarray,'author-avatar')) && ($contact['network'] != NETWORK_DFRN)) - $datarray['author-avatar'] = $contact['thumb']; -*/ - if((! x($datarray,'author_name')) || (! x($datarray,'author_link'))) { - logger('consume_feed: no author information! ' . print_r($datarray,true)); - continue; - } + if(! x($datarray,'author_name')) + $datarray['author_name'] = $contact['xchan_name']; + if(! x($datarray,'author_link')) + $datarray['author_link'] = $contact['xchan_url']; + if(! x($datarray,'author_photo')) + $datarray['author_photo'] = $contact['xchan_photo_m']; - - $r = q("SELECT `uid`, `edited`, `body` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($item_id), intval($importer['channel_id']) ); @@ -3152,70 +3112,26 @@ logger('consume_feed: processing ' . $item_id); // Update content if 'updated' changes if($r) { - if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + if((x($datarray,'edited') !== false) + && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { // do not accept (ignore) an earlier edit than one we currently have. if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) continue; - $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `edited` = '%s' WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", - dbesc($datarray['title']), - dbesc($datarray['body']), - dbesc(datetime_convert('UTC','UTC',$datarray['edited'])), - dbesc($item_id), - intval($importer['channel_id']) - ); + update_feed_item($importer['channel_id'],$datarray); } - continue; } - $datarray['parent_mid'] = $parent_mid; $datarray['uid'] = $importer['channel_id']; -// $datarray['contact-id'] = $contact['id']; - - if((activity_match($datarray['verb'],ACTIVITY_LIKE)) || (activity_match($datarray['verb'],ACTIVITY_DISLIKE))) { - $datarray['type'] = 'activity'; - $datarray['gravity'] = GRAVITY_LIKE; - // only one like or dislike per person - $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`parent_mid` = '%s' OR `thr_parent` = '%s') limit 1", - intval($datarray['uid']), - intval($datarray['contact-id']), - dbesc($datarray['verb']), - dbesc($parent_mid), - dbesc($parent_mid) - ); - if($r && count($r)) - continue; - } - - if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['obj_type'] === ACTIVITY_OBJ_TAGTERM)) { - $xo = parse_xml_string($datarray['object'],false); - $xt = parse_xml_string($datarray['target'],false); + $datarray['author_xchan'] = $contact['xchan_hash']; - if($xt->type == ACTIVITY_OBJ_NOTE) { - $r = q("select * from item where `mid` = '%s' AND `uid` = %d limit 1", - dbesc($xt->id), - intval($importer['channel_id']) - ); - if(! count($r)) - continue; + // FIXME pull out the author and owner - // extract tag, if not duplicate, add to parent item - if($xo->id && $xo->content) { - $newtag = '#[zrl=' . $xo->id . ']'. $xo->content . '[/zrl]'; - if(! (stristr($r[0]['tag'],$newtag))) { - q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", - dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag), - intval($r[0]['id']) - ); - } - } - } - } -logger('consume_feed: ' . print_r($datarray,true)); + logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); // $xx = item_store($datarray); $r = $xx['item_id']; @@ -3231,43 +3147,21 @@ logger('consume_feed: ' . print_r($datarray,true)); $datarray = get_atom_elements($feed,$item); if(is_array($contact)) { - if((! x($datarray,'author-name')) && ($contact['network'] != NETWORK_DFRN)) - $datarray['author-name'] = $contact['name']; - if((! x($datarray,'author-link')) && ($contact['network'] != NETWORK_DFRN)) - $datarray['author-link'] = $contact['url']; - if((! x($datarray,'author-avatar')) && ($contact['network'] != NETWORK_DFRN)) - $datarray['author-avatar'] = $contact['thumb']; + if(! x($datarray,'author_name')) + $datarray['author_name'] = $contact['xchan_name']; + if(! x($datarray,'author_link')) + $datarray['author_link'] = $contact['xchan_url']; + if(! x($datarray,'author_photo')) + $datarray['author_photo'] = $contact['xchan_photo_m']; } - if((! x($datarray,'author-name')) || (! x($datarray,'author-link'))) { + if((! x($datarray,'author_name')) || (! x($datarray,'author_link'))) { logger('consume_feed: no author information! ' . print_r($datarray,true)); continue; } - // special handling for events - - if((x($datarray,'obj_type')) && ($datarray['obj_type'] === ACTIVITY_OBJ_EVENT)) { - $ev = bbtoevent($datarray['body']); - if(x($ev,'desc') && x($ev,'start')) { - $ev['uid'] = $importer['channel_id']; - $ev['mid'] = $item_id; - $ev['edited'] = $datarray['edited']; - $ev['private'] = $datarray['private']; - - if(is_array($contact)) - $ev['cid'] = $contact['id']; - $r = q("SELECT * FROM `event` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", - dbesc($item_id), - intval($importer['channel_id']) - ); - if(count($r)) - $ev['id'] = $r[0]['id']; -// $xyz = event_store($ev); - continue; - } - } - $r = q("SELECT `uid`, `edited`, `body` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($item_id), intval($importer['channel_id']) ); @@ -3275,79 +3169,32 @@ logger('consume_feed: ' . print_r($datarray,true)); // Update content if 'updated' changes if($r) { - if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + if((x($datarray,'edited') !== false) + && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { // do not accept (ignore) an earlier edit than one we currently have. if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) continue; - $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `edited` = '%s' WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", - dbesc($datarray['title']), - dbesc($datarray['body']), - dbesc(datetime_convert('UTC','UTC',$datarray['edited'])), - dbesc($item_id), - intval($importer['channel_id']) - ); + update_feed_item($importer['channel_id'],$datarray); } continue; } - if(activity_match($datarray['verb'],ACTIVITY_FOLLOW)) { - logger('consume-feed: New follower'); - new_follower($importer,$contact,$datarray,$item); - return; - } - if(activity_match($datarray['verb'],ACTIVITY_UNFOLLOW)) { - lose_follower($importer,$contact,$datarray,$item); - return; - } - - if(activity_match($datarray['verb'],ACTIVITY_REQ_FRIEND)) { - logger('consume-feed: New friend request'); - new_follower($importer,$contact,$datarray,$item,true); - return; - } - if(activity_match($datarray['verb'],ACTIVITY_UNFRIEND)) { - lose_sharer($importer,$contact,$datarray,$item); - return; - } - - -// if(! is_array($contact)) -// return; - - - // This is my contact on another system, but it's really me. - // Turn this into a wall post. - - if($contact['remote_self']) { - $datarray['wall'] = 1; - } $datarray['parent_mid'] = $item_id; $datarray['uid'] = $importer['channel_id']; - $datarray['contact-id'] = $contact['id']; - - if(! link_compare($datarray['owner-link'],$contact['url'])) { - // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery, - // but otherwise there's a possible data mixup on the sender's system. - // the tgroup delivery code called from item_store will correct it if it's a forum, - // but we're going to unconditionally correct it here so that the post will always be owned by our contact. - logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); - $datarray['owner-name'] = $contact['name']; - $datarray['owner-link'] = $contact['url']; - $datarray['owner-avatar'] = $contact['thumb']; - } + $datarray['author_xchan'] = $contact['author_xchan']; - // We've allowed "followers" to reach this point so we can decide if they are - // posting an @-tag delivery, which followers are allowed to do for certain - // page types. Now that we've parsed the post, let's check if it is legit. Otherwise ignore it. +// if(! link_compare($datarray['owner_link'],$contact['xchan_url'])) { +// logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); +// $datarray['owner-name'] = $contact['name']; +// $datarray['owner-link'] = $contact['url']; +// $datarray['owner-avatar'] = $contact['thumb']; +// } - if(($contact['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['channel_id'],$datarray))) - continue; - -logger('consume_feed: ' . print_r($datarray,true)); + logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); // $xx = item_store($datarray); $r = $xx['item_id']; @@ -3358,6 +3205,13 @@ logger('consume_feed: ' . print_r($datarray,true)); } +} + +function update_feed_item($uid,$datarray) { + + logger('update_feed_item: ' . $uid . ' ' . print_r($datarray,true), LOGGER_DATA); + + } diff --git a/version.inc b/version.inc index 6ca87b875..ed8a8be13 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -2014-08-19.772 +2014-08-20.773 -- cgit v1.2.3 From ecf8b707943351387720c39c0c67b056e070039e Mon Sep 17 00:00:00 2001 From: zottel Date: Wed, 20 Aug 2014 14:44:55 +0200 Subject: updated German main.bb doco file --- doc/de/main.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/de/main.bb b/doc/de/main.bb index 1c8031c3e..7a4c8ebe2 100644 --- a/doc/de/main.bb +++ b/doc/de/main.bb @@ -58,6 +58,7 @@ Zot ist das großartige neue Kommunikationsprotokoll, das extra für die Red-Mat [zrl=[baseurl]/help/developers]Entwickler[/zrl] [zrl=[baseurl]/help/intro_for_developers]Einführung für Entwickler[/zrl] [zrl=[baseurl]/help/api_functions]API-Funktionen[/zrl] +[zrl=[baseurl]/help/api_posting]Mit der API einen Beitrag erstellen[/zrl] [zrl=[baseurl]/help/developer_function_primer]Übersicht der wichtigsten Red-Funktionen[/zrl] [zrl=[baseurl]/doc/html/]Code-Referenz (mit doxygen generiert - setzt Cookies)[/zrl] [zrl=[baseurl]/help/to_do_doco]To-Do-Liste für das Projekt Red-Dokumentation[/zrl] -- cgit v1.2.3 From f7895d322e30ce3d69689c1646fd0056d195e5a8 Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 16:10:57 -0700 Subject: provide admin option for allowing rss/atom feed connections. Need to do this now before the feature is complete so that public sites don't get borked. We also will need a service class for this. --- mod/admin.php | 50 +++++-------------------------------------------- view/tpl/admin_site.tpl | 1 + 2 files changed, 6 insertions(+), 45 deletions(-) diff --git a/mod/admin.php b/mod/admin.php index 14657bd1a..5df63636a 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -265,50 +265,10 @@ function admin_page_site_post(&$a){ $delivery_interval = ((x($_POST,'delivery_interval'))? intval(trim($_POST['delivery_interval'])) : 0); $poll_interval = ((x($_POST,'poll_interval'))? intval(trim($_POST['poll_interval'])) : 0); $maxloadavg = ((x($_POST,'maxloadavg'))? intval(trim($_POST['maxloadavg'])) : 50); -// $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0); -/* - if($ssl_policy != intval(get_config('system','ssl_policy'))) { - if($ssl_policy == SSL_POLICY_FULL) { - q("update `contact` set - `url` = replace(`url` , 'http:' , 'https:'), - `photo` = replace(`photo` , 'http:' , 'https:'), - `thumb` = replace(`thumb` , 'http:' , 'https:'), - `micro` = replace(`micro` , 'http:' , 'https:'), - `request` = replace(`request`, 'http:' , 'https:'), - `notify` = replace(`notify` , 'http:' , 'https:'), - `poll` = replace(`poll` , 'http:' , 'https:'), - `confirm` = replace(`confirm`, 'http:' , 'https:'), - `poco` = replace(`poco` , 'http:' , 'https:') - where `self` = 1" - ); - q("update `profile` set - `photo` = replace(`photo` , 'http:' , 'https:'), - `thumb` = replace(`thumb` , 'http:' , 'https:') - where 1 " - ); - } - elseif($ssl_policy == SSL_POLICY_SELFSIGN) { - q("update `contact` set - `url` = replace(`url` , 'https:' , 'http:'), - `photo` = replace(`photo` , 'https:' , 'http:'), - `thumb` = replace(`thumb` , 'https:' , 'http:'), - `micro` = replace(`micro` , 'https:' , 'http:'), - `request` = replace(`request`, 'https:' , 'http:'), - `notify` = replace(`notify` , 'https:' , 'http:'), - `poll` = replace(`poll` , 'https:' , 'http:'), - `confirm` = replace(`confirm`, 'https:' , 'http:'), - `poco` = replace(`poco` , 'https:' , 'http:') - where `self` = 1" - ); - q("update `profile` set - `photo` = replace(`photo` , 'https:' , 'http:'), - `thumb` = replace(`thumb` , 'https:' , 'http:') - where 1 " - ); - } - } -*/ -// set_config('system','ssl_policy',$ssl_policy); + $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); + + + set_config('system','feed_contacts',$feed_contacts); set_config('system','delivery_interval',$delivery_interval); set_config('system','poll_interval',$poll_interval); set_config('system','maxloadavg',$maxloadavg); @@ -464,7 +424,7 @@ function admin_page_site(&$a) { '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), '$theme_accessibility' => array('theme_accessibility', t("Accessibility system theme"), get_config('system','accessibility_theme'), t("Accessibility theme"), $theme_choices_accessibility), '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")), -// '$ssl_policy' => array('ssl_policy', t("SSL link policy"), (string) intval(get_config('system','ssl_policy')), t("Determines whether generated links should be forced to use SSL"), $ssl_choices), + '$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')), '$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), '$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices), '$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), "This is displayed on the public server site list.", $access_choices), diff --git a/view/tpl/admin_site.tpl b/view/tpl/admin_site.tpl index c6c15cec4..2a7742a3e 100755 --- a/view/tpl/admin_site.tpl +++ b/view/tpl/admin_site.tpl @@ -65,6 +65,7 @@

{{$corporate}}

{{include file="field_checkbox.tpl" field=$block_public}} + {{include file="field_checkbox.tpl" field=$feed_contacts}} {{include file="field_checkbox.tpl" field=$force_publish}} {{include file="field_checkbox.tpl" field=$disable_discover_tab}} -- cgit v1.2.3 From a6829f7dcb6735ee0b2f003647cc168e55002a5f Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 17:15:13 -0700 Subject: move Friendica photo migrator to addons, bring back a few XML scraping functions that we're going to require (unfortunately) --- include/network.php | 166 ++++++++++++++++++++++++++++++++++++++++++++++++- mod/frphotos.php | 87 -------------------------- util/frphotohelper.php | 75 ---------------------- view/tpl/frphotos.tpl | 13 ---- 4 files changed, 165 insertions(+), 176 deletions(-) delete mode 100644 mod/frphotos.php delete mode 100644 util/frphotohelper.php delete mode 100644 view/tpl/frphotos.tpl diff --git a/include/network.php b/include/network.php index 1a974a681..614049299 100644 --- a/include/network.php +++ b/include/network.php @@ -965,4 +965,168 @@ logger('fetch_xrd_links: ' . $url); logger('fetch_xrd_links: ' . print_r($links,true), LOGGER_DATA); return $links; -} \ No newline at end of file +} + + +function scrape_vcard($url) { + + $a = get_app(); + + $ret = array(); + + logger('scrape_vcard: url=' . $url); + + $x = z_fetch_url($url); + if(! $x['success']) + return $ret; + + $s = $x['body']; + + if(! $s) + return $ret; + + $headers = $x['header']; + $lines = explode("\n",$headers); + if(count($lines)) { + foreach($lines as $line) { + // don't try and run feeds through the html5 parser + if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml')))) + return ret; + } + } + + try { + $dom = HTML5_Parser::parse($s); + } catch (DOMException $e) { + logger('scrape_vcard: parse error: ' . $e); + } + + if(! $dom) + return $ret; + + // Pull out hCard profile elements + + $largest_photo = 0; + + $items = $dom->getElementsByTagName('*'); + foreach($items as $item) { + if(attribute_contains($item->getAttribute('class'), 'vcard')) { + $level2 = $item->getElementsByTagName('*'); + foreach($level2 as $x) { + if(attribute_contains($x->getAttribute('class'),'fn')) + $ret['fn'] = $x->textContent; + if((attribute_contains($x->getAttribute('class'),'photo')) + || (attribute_contains($x->getAttribute('class'),'avatar'))) { + $size = intval($x->getAttribute('width')); + if(($size > $largest_photo) || (! $largest_photo)) { + $ret['photo'] = $x->getAttribute('src'); + $largest_photo = $size; + } + } + if((attribute_contains($x->getAttribute('class'),'nickname')) + || (attribute_contains($x->getAttribute('class'),'uid'))) { + $ret['nick'] = $x->textContent; + } + } + } + } + + return $ret; +} + + + +function scrape_feed($url) { + + $a = get_app(); + + $ret = array(); + $level = 0; + $x = z_fetch_url($url,false,$level,array('novalidate' => true)); + + if(! $x['success']) + return $ret; + + $headers = $x['header']; + $code = $x['return_code']; + $s = $x['body']; + + logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG); + + if(! $s) { + logger('scrape_feed: no data returned for ' . $url); + return $ret; + } + + + $lines = explode("\n",$headers); + if(count($lines)) { + foreach($lines as $line) { + if(stristr($line,'content-type:')) { + if(stristr($line,'application/atom+xml') || stristr($s,'')) { + $ret['feed_rss'] = $url; + return $ret; + } + } + + try { + $dom = HTML5_Parser::parse($s); + } catch (DOMException $e) { + logger('scrape_feed: parse error: ' . $e); + } + + if(! $dom) { + logger('scrape_feed: failed to parse.'); + return $ret; + } + + + $head = $dom->getElementsByTagName('base'); + if($head) { + foreach($head as $head0) { + $basename = $head0->getAttribute('href'); + break; + } + } + if(! $basename) + $basename = implode('/', array_slice(explode('/',$url),0,3)) . '/'; + + $items = $dom->getElementsByTagName('link'); + + // get Atom/RSS link elements, take the first one of either. + + if($items) { + foreach($items as $item) { + $x = $item->getAttribute('rel'); + if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml')) { + if(! x($ret,'feed_atom')) + $ret['feed_atom'] = $item->getAttribute('href'); + } + if(($x === 'alternate') && ($item->getAttribute('type') === 'application/rss+xml')) { + if(! x($ret,'feed_rss')) + $ret['feed_rss'] = $item->getAttribute('href'); + } + } + } + + // Drupal and perhaps others only provide relative URL's. Turn them into absolute. + + if(x($ret,'feed_atom') && (! strstr($ret['feed_atom'],'://'))) + $ret['feed_atom'] = $basename . $ret['feed_atom']; + if(x($ret,'feed_rss') && (! strstr($ret['feed_rss'],'://'))) + $ret['feed_rss'] = $basename . $ret['feed_rss']; + + return $ret; +} + diff --git a/mod/frphotos.php b/mod/frphotos.php deleted file mode 100644 index 8d6197fa3..000000000 --- a/mod/frphotos.php +++ /dev/null @@ -1,87 +0,0 @@ -get_channel(); - - $fr_server = $_REQUEST['fr_server']; - $fr_username = $_REQUEST['fr_username']; - $fr_password = $_REQUEST['fr_password']; - - $cookies = 'store/[data]/frphoto_cookie_' . $channel['channel_address']; - - if($fr_server && $fr_username && $fr_password) { - - $ch = curl_init($fr_server . '/api/friendica/photos/list'); - - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookies); - curl_setopt ($ch, CURLOPT_COOKIEJAR, $cookies); - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - curl_setopt($ch, CURLOPT_USERPWD, $fr_username . ':' . $fr_password); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_USERAGENT, 'RedMatrix'); - - $output = curl_exec($ch); - curl_close($ch); - - $j = json_decode($output,true); - -// echo print_r($j,true); - - $total = 0; - if(count($j)) { - foreach($j as $jj) { - - $r = q("select uid from photo where resource_id = '%s' and uid = %d limit 1", - dbesc($jj), - intval($channel['channel_id']) - ); - if($r) - continue; - - $total ++; - proc_run('php','util/frphotohelper.php',$jj, $channel['channel_address'], urlencode($fr_server)); - sleep(3); - } - } - if($total) { - set_pconfig(local_user(),'frphotos','complete','1'); - } - @unlink($cookies); - goaway(z_root() . '/photos/' . $channel['channel_address']); - } -} - - -function frphotos_content(&$a) { - - if(! local_user()) { - notice( t('Permission denied') . EOL); - return; - } - - if(intval(get_pconfig(local_user(),'frphotos','complete'))) { - info('Friendica photos have already been imported into this channel.'); - return; - } - - $o = replace_macros(get_markup_template('frphotos.tpl'),array( - '$header' => t('Friendica Photo Album Import'), - '$desc' => t('This will import all your Friendica photo albums to this Red channel.'), - '$fr_server' => array('fr_server', t('Friendica Server base URL'),'',''), - '$fr_username' => array('fr_username', t('Friendica Login Username'),'',''), - '$fr_password' => array('fr_password', t('Friendica Login Password'),'',''), - '$submit' => t('Submit'), - )); - return $o; -} diff --git a/util/frphotohelper.php b/util/frphotohelper.php deleted file mode 100644 index 484e7fcaf..000000000 --- a/util/frphotohelper.php +++ /dev/null @@ -1,75 +0,0 @@ -{{$header}} - -

{{$desc}}

- -
- -{{include file="field_input.tpl" field=$fr_server}} -{{include file="field_input.tpl" field=$fr_username}} -{{include file="field_password.tpl" field=$fr_password}} - - -
- -- cgit v1.2.3 From a169e5c4f3b54003a6a4dfaf61269eb18f34f17a Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 18:35:36 -0700 Subject: restructure the author and owner info from feeds --- include/items.php | 143 ++++++++++++++++++++++-------------------------------- 1 file changed, 58 insertions(+), 85 deletions(-) diff --git a/include/items.php b/include/items.php index 03b493bc3..e5c9549e2 100755 --- a/include/items.php +++ b/include/items.php @@ -1224,21 +1224,21 @@ function get_profile_elements($x) { -function get_atom_elements($feed,$item) { +function get_atom_elements($feed,$item,&$author) { $best_photo = array(); $res = array(); - $author = $item->get_author(); - if($author) { - $res['author_name'] = unxmlify($author->get_name()); - $res['author_link'] = unxmlify($author->get_link()); + $found_author = $item->get_author(); + if($found_author) { + $author['author_name'] = unxmlify($found_author->get_name()); + $author['author_link'] = unxmlify($found_author->get_link()); } else { - $res['author_name'] = unxmlify($feed->get_title()); - $res['author_link'] = unxmlify($feed->get_permalink()); + $author['author_name'] = unxmlify($feed->get_title()); + $author['author_link'] = unxmlify($feed->get_permalink()); } $res['mid'] = unxmlify($item->get_id()); @@ -1265,9 +1265,9 @@ function get_atom_elements($feed,$item) { 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($res, 'author_photo') || !$res['author_photo']) { + if(!x($author, 'author_photo') || ! $author['author_photo']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $res['author_photo'] = unxmlify($link['attribs']['']['href']); + $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } @@ -1279,10 +1279,10 @@ function get_atom_elements($feed,$item) { if($base && count($base)) { foreach($base as $link) { if($link['attribs']['']['rel'] === 'alternate' && (! $res['author_link'])) - $res['author_link'] = unxmlify($link['attribs']['']['href']); - if(!x($res, 'author_photo') || !$res['author_photo']) { + $author['author_link'] = unxmlify($link['attribs']['']['href']); + if(!x($author, 'author_photo') || ! $author['author_photo']) { if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') - $res['author_photo'] = unxmlify($link['attribs']['']['href']); + $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } @@ -1290,16 +1290,16 @@ function get_atom_elements($feed,$item) { // No photo/profile-link on the item - look at the feed level - if((! (x($res,'author_link'))) || (! (x($res,'author_photo')))) { + 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' && (! $res['author_link'])) - $res['author_link'] = unxmlify($link['attribs']['']['href']); - if(! $res['author_photo']) { + if($link['attribs']['']['rel'] === 'alternate' && (! $author['author_link'])) + $author['author_link'] = unxmlify($link['attribs']['']['href']); + if(! $author['author_photo']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $res['author_photo'] = unxmlify($link['attribs']['']['href']); + $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } @@ -1312,10 +1312,10 @@ function get_atom_elements($feed,$item) { if($base && count($base)) { foreach($base as $link) { if($link['attribs']['']['rel'] === 'alternate' && (! $res['author_link'])) - $res['author_link'] = unxmlify($link['attribs']['']['href']); - if(! (x($res,'author_photo'))) { + $author['author_link'] = unxmlify($link['attribs']['']['href']); + if(! (x($author,'author_photo'))) { if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') - $res['author_photo'] = unxmlify($link['attribs']['']['href']); + $author['author_photo'] = unxmlify($link['attribs']['']['href']); } } } @@ -1419,22 +1419,25 @@ function get_atom_elements($feed,$item) { $res['edited'] = datetime_convert(); $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); + if(! $rawowner) + $rawowner = $item->get_item_tags(NAMESPACE_ZOT,'owner'); + if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) - $res['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); + $author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) - $res['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); + $author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) - $res['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); + $author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) - $res['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); + $author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach($base as $link) { - if(!x($res, 'owner_photo') || !$res['owner_photo']) { + if(!x($author, 'owner_photo') || ! $author['owner_photo']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $res['owner_photo'] = unxmlify($link['attribs']['']['href']); + $author['owner_photo'] = unxmlify($link['attribs']['']['href']); } } } @@ -1579,39 +1582,11 @@ function get_atom_elements($feed,$item) { $res['target'] = $obj; } - // This is some experimental stuff. By now retweets are shown with "RT:" - // But: There is data so that the message could be shown similar to native retweets - // There is some better way to parse this array - but it didn't worked for me. - -/* - $child = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["entry"][0]["child"]["http://activitystrea.ms/spec/1.0/"][object][0]["child"]; - if (is_array($child)) { - $message = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["content"][0]["data"]; - $author = $child[SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]; - $uri = $author["uri"][0]["data"]; - $name = $author["name"][0]["data"]; - $avatar = @array_shift($author["link"][2]["attribs"]); - $avatar = $avatar["href"]; - - if (($name != "") and ($uri != "") and ($avatar != "") and ($message != "")) { - $res["owner-name"] = $res["author-name"]; - $res["owner-link"] = $res["author-link"]; - $res["owner-avatar"] = $res["author-avatar"]; - - $res["author-name"] = $name; - $res["author-link"] = $uri; - $res["author-avatar"] = $avatar; - - $res["body"] = html2bbcode($message); - } - } - -*/ - $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); call_hooks('parse_atom', $arr); - logger('get_atom_elements: ' . print_r($res,true)); + logger('get_atom_elements: author: ' . print_r($author,true),LOGGER_DATA); + logger('get_atom_elements: ' . print_r($res,true),LOGGER_DATA); return $res; } @@ -1621,9 +1596,6 @@ function encode_rel_links($links) { if(! ((is_array($links)) && (count($links)))) return $o; -//fixme - return ''; - foreach($links as $link) { $o .= 'set_raw_data($xml); $feed->init(); @@ -3095,14 +3064,15 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { // Have we seen it? If not, import it. $item_id = $item->get_id(); - $datarray = get_atom_elements($feed,$item); + $author = array(); + $datarray = get_atom_elements($feed,$item,$author); - if(! x($datarray,'author_name')) - $datarray['author_name'] = $contact['xchan_name']; - if(! x($datarray,'author_link')) - $datarray['author_link'] = $contact['xchan_url']; - if(! x($datarray,'author_photo')) - $datarray['author_photo'] = $contact['xchan_photo_m']; + if(! x($author,'author_name')) + $author['author_name'] = $contact['xchan_name']; + if(! x($author,'author_link')) + $author['author_link'] = $contact['xchan_url']; + if(! x($author,'author_photo')) + $author['author_photo'] = $contact['xchan_photo_m']; $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($item_id), @@ -3126,6 +3096,8 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { $datarray['parent_mid'] = $parent_mid; $datarray['uid'] = $importer['channel_id']; + +//FIXME $datarray['author_xchan'] = $contact['xchan_hash']; // FIXME pull out the author and owner @@ -3143,20 +3115,20 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { // Head post of a conversation. Have we seen it? If not, import it. $item_id = $item->get_id(); - - $datarray = get_atom_elements($feed,$item); + $author = array(); + $datarray = get_atom_elements($feed,$item,$author); if(is_array($contact)) { - if(! x($datarray,'author_name')) - $datarray['author_name'] = $contact['xchan_name']; - if(! x($datarray,'author_link')) - $datarray['author_link'] = $contact['xchan_url']; - if(! x($datarray,'author_photo')) - $datarray['author_photo'] = $contact['xchan_photo_m']; + if(! x($author,'author_name')) + $author['author_name'] = $contact['xchan_name']; + if(! x($author,'author_link')) + $author['author_link'] = $contact['xchan_url']; + if(! x($author,'author_photo')) + $author['author_photo'] = $contact['xchan_photo_m']; } - if((! x($datarray,'author_name')) || (! x($datarray,'author_link'))) { - logger('consume_feed: no author information! ' . print_r($datarray,true)); + if((! x($author,'author_name')) || (! x($author,'author_link'))) { + logger('consume_feed: no author information! ' . print_r($author,true)); continue; } @@ -3185,14 +3157,15 @@ function consume_feed($xml,$importer,&$contact,$pass = 0) { $datarray['parent_mid'] = $item_id; $datarray['uid'] = $importer['channel_id']; +//FIXME $datarray['author_xchan'] = $contact['author_xchan']; -// if(! link_compare($datarray['owner_link'],$contact['xchan_url'])) { -// logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); -// $datarray['owner-name'] = $contact['name']; -// $datarray['owner-link'] = $contact['url']; -// $datarray['owner-avatar'] = $contact['thumb']; -// } + if(! link_compare($author['owner_link'],$contact['xchan_url'])) { + logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); + $author['owner-name'] = $contact['name']; + $author['owner-link'] = $contact['url']; + $author['owner-avatar'] = $contact['thumb']; + } logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); -- cgit v1.2.3 From b8a5b7a610fa940297b4bd3f66c912c3f3e7e161 Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 19:36:01 -0700 Subject: restrict returned directory contents to xchans in the zot network. We could probably add other networks to this and create a distributed directory for the free web. It's highly unlikely we would do this but we *could*. --- mod/dirsearch.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mod/dirsearch.php b/mod/dirsearch.php index b72d303b7..96e576a19 100644 --- a/mod/dirsearch.php +++ b/mod/dirsearch.php @@ -154,7 +154,7 @@ function dirsearch_content(&$a) { else { $qlimit = " LIMIT " . intval($startrec) . " , " . intval($perpage); if($return_total) { - $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) $safesql ", + $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and xchan_network = 'zot' and not ( xchan_flags & %d) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) $safesql ", intval(XCHAN_FLAGS_HIDDEN), intval(XCHAN_FLAGS_ORPHAN), intval(XCHAN_FLAGS_DELETED) @@ -199,7 +199,7 @@ function dirsearch_content(&$a) { json_return_and_die($spkt); } else { - $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where ( $logic $sql_extra ) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) $safesql $order $qlimit ", + $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where ( $logic $sql_extra ) and xchan_network = 'zot' and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) $safesql $order $qlimit ", intval(XCHAN_FLAGS_HIDDEN), intval(XCHAN_FLAGS_ORPHAN), intval(XCHAN_FLAGS_DELETED) -- cgit v1.2.3 From af45b34ee044966210e6101585fe362acf1ca098 Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 20:49:03 -0700 Subject: verified that chatroom expire is working, so doing away with the second function to do the same thing. If you have a problem with chatroom expiration, check that it was created with cr_expire set to 120 (minutes). Chatrooms created during the first couple of days of the chat feature didn't have this. You can set the DB value manually. --- boot.php | 5 ----- include/chat.php | 23 ++++------------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/boot.php b/boot.php index 267999d07..f8bd29f37 100755 --- a/boot.php +++ b/boot.php @@ -358,11 +358,6 @@ define ( 'MAX_LIKERS', 10); define ( 'ZCURL_TIMEOUT' , (-1)); -/** - * Hours before chat lines are deleted - */ - -define ( 'MAX_CHATROOM_HOURS' , 36); /** * email notification options diff --git a/include/chat.php b/include/chat.php index 5f69853e7..b8fb185df 100644 --- a/include/chat.php +++ b/include/chat.php @@ -128,8 +128,10 @@ function chatroom_enter($observer_xchan,$room_id,$status,$client) { } } - if(intval($x[0]['cr_expire'])) - $r = q("delete from chat where created < UTC_TIMESTAMP() - INTERVAL " . intval($x[0]['cr_expire']) . " MINUTE and chat_room = " . intval($x[0]['cr_id'])); + if(intval($x[0]['cr_expire'])) { + $sql = "delete from chat where created < UTC_TIMESTAMP() - INTERVAL " . intval($x[0]['cr_expire']) . " MINUTE and chat_room = " . intval($x[0]['cr_id']); + $r = q($sql); + } $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1", dbesc($observer_xchan), @@ -153,7 +155,6 @@ function chatroom_enter($observer_xchan,$room_id,$status,$client) { dbesc($client) ); - chatroom_flush($room_id,$xchan); return $r; } @@ -226,21 +227,5 @@ function chat_message($uid,$room_id,$xchan,$text) { ); $ret['success'] = true; - chatroom_flush($room_id,$xchan); return $ret; } - -/** - * Reduces the number of lines shown in chat by removing those older than MAX_CHATROOM_HOURS - */ - -function chatroom_flush($room_id,$xchan) { - - - $date_limit = date('Y-m-d H:i:s', time() - 3600 * MAX_CHATROOM_HOURS); - $d = q("delete from chat where chat_room = %d and chat_xchan = '%s' and created < '%s'", - intval($room_id), - dbesc($xchan), - datetime_convert('','', $date_limit)); - return true; -} -- cgit v1.2.3 From b4aed1212930e40377665dc45271f2b1f428511f Mon Sep 17 00:00:00 2001 From: friendica Date: Wed, 20 Aug 2014 23:01:25 -0700 Subject: extensible profiles - add the input form elements. Still needs styling and we're not yet storing the results. And right now we're ignoring the type and only doing type=string. Oh yeah - and I split off starting the second delivery chain into its own function in tag_deliver since it was largely duplicate code. --- include/items.php | 234 ++++++++++++++++++++-------------------------- mod/profiles.php | 19 ++++ view/tpl/profile_edit.tpl | 5 + 3 files changed, 123 insertions(+), 135 deletions(-) diff --git a/include/items.php b/include/items.php index e5c9549e2..fbe67817d 100755 --- a/include/items.php +++ b/include/items.php @@ -1340,6 +1340,12 @@ function get_atom_elements($feed,$item,&$author) { $res['body'] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$res['body']); // make sure nobody is trying to sneak some html tags by us $res['body'] = notags(base64url_decode($res['body'])); + + // We could probably turn these old Friendica bbcode bookmarks into bookmark tags but we'd have to + // create a term table item for them. For now just make sure they stay as links. + + $res['body'] = preg_replace('/\[bookmark(.*?)\](.*?)\[\/bookmark\]','[url$1]$2[/url]',$res['body']); + } @@ -2346,8 +2352,9 @@ function tag_deliver($uid,$item_id) { $item = $i[0]; - if(($item['source_xchan']) && ($item['item_flags'] & ITEM_UPLINK) && ($item['item_flags'] & ITEM_THREAD_TOP) && ($item['edited'] != $item['created'])) { - // this is an update to a post which was already processed by us and has a second delivery chain + if(($item['source_xchan']) && ($item['item_flags'] & ITEM_UPLINK) + && ($item['item_flags'] & ITEM_THREAD_TOP) && ($item['edited'] != $item['created'])) { + // this is an update (edit) to a post which was already processed by us and has a second delivery chain // Just start the second delivery chain to deliver the updated post proc_run('php','include/notifier.php','tgroup',$item['id']); return; @@ -2444,78 +2451,14 @@ function tag_deliver($uid,$item_id) { // This might be a followup (e.g. comment) by the original post author to a tagged forum // If so setup a second delivery chain - $r = null; - if( ! ($item['item_flags'] & ITEM_THREAD_TOP)) { $x = q("select * from item where id = parent and parent = %d and uid = %d limit 1", intval($item['parent']), intval($uid) ); - if(($x) && ($x[0]['item_flags'] & ITEM_UPLINK)) { - - logger('tag_deliver: creating second delivery chain for comment to tagged post.'); - - // now change this copy of the post to a forum head message and deliver to all the tgroup members - // also reset all the privacy bits to the forum default permissions - - $private = (($u[0]['channel_allow_cid'] || $u[0]['channel_allow_gid'] || $u[0]['channel_deny_cid'] || $u[0]['channel_deny_gid']) ? 1 : 0); - - $new_public_policy = map_scope($u[0]['channel_r_stream'],true); - - if((! $private) && $new_public_policy) - $private = 1; - - $flag_bits = $item['item_flags'] | ITEM_WALL|ITEM_ORIGIN; - - // maintain the original source, which will be the original item owner and was stored in source_xchan - // when we created the delivery fork - - $r = q("update item set source_xchan = '%s' where id = %d limit 1", - dbesc($x[0]['source_xchan']), - intval($item_id) - ); - - $title = $item['title']; - $body = $item['body']; - - if($private) { - if(!($flag_bits & ITEM_OBSCURED)) { - $key = get_config('system','pubkey'); - $flag_bits = $flag_bits|ITEM_OBSCURED; - $title = json_encode(aes_encapsulate($title,$key)); - $body = json_encode(aes_encapsulate($body,$key)); - } - } - else { - if($flag_bits & ITEM_OBSCURED) { - $key = get_config('system','prvkey'); - $flag_bits = $flag_bits ^ ITEM_OBSCURED; - $title = json_encode(aes_unencapsulate($title,$key)); - $body = json_encode(aes_unencapsulate($body,$key)); - } - } - - $r = q("update item set item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s', - deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s' where id = %d limit 1", - intval($flag_bits), - dbesc($u[0]['channel_hash']), - dbesc($u[0]['channel_allow_cid']), - dbesc($u[0]['channel_allow_gid']), - dbesc($u[0]['channel_deny_cid']), - dbesc($u[0]['channel_deny_gid']), - intval($private), - dbesc($new_public_policy), - dbesc(map_scope($u[0]['channel_w_comment'])), - dbesc($title), - dbesc($body), - intval($item_id) - ); - if($r) - proc_run('php','include/notifier.php','tgroup',$item_id); - else - logger('tag_deliver: failed to update item'); + start_delivery_chain($u[0],$item,$item_id,$x[0]); } } @@ -2549,8 +2492,6 @@ function tag_deliver($uid,$item_id) { intval($item_id) ); - - // At this point we've determined that the person receiving this post was mentioned in it or it is a union. // Now let's check if this mention was inside a reshare so we don't spam a forum // If it's private we may have to unobscure it momentarily so that we can parse it. @@ -2622,81 +2563,20 @@ function tag_deliver($uid,$item_id) { return; } - // tgroup delivery - setup a second delivery chain // prevent delivery looping - only proceed // if the message originated elsewhere and is a top-level post - if(($item['item_flags'] & ITEM_WALL) || ($item['item_flags'] & ITEM_ORIGIN) || (!($item['item_flags'] & ITEM_THREAD_TOP)) || ($item['id'] != $item['parent'])) { + if(($item['item_flags'] & ITEM_WALL) + || ($item['item_flags'] & ITEM_ORIGIN) + || (!($item['item_flags'] & ITEM_THREAD_TOP)) + || ($item['id'] != $item['parent'])) { logger('tag_deliver: item was local or a comment. rejected.'); return; } - /** - * At this point we're committed to setting up a second delivery chain. We just have to mangle some bits first. - */ - logger('tag_deliver: creating second delivery chain.'); - - // now change this copy of the post to a forum head message and deliver to all the tgroup members - // also reset all the privacy bits to the forum default permissions - - $private = (($u[0]['channel_allow_cid'] || $u[0]['channel_allow_gid'] || $u[0]['channel_deny_cid'] || $u[0]['channel_deny_gid']) ? 1 : 0); - - $new_public_policy = map_scope($u[0]['channel_r_stream'],true); - - if((! $private) && $new_public_policy) - $private = 1; - - $flag_bits = $item['item_flags'] | ITEM_WALL|ITEM_ORIGIN|ITEM_UPLINK; - - // preserve the source - - $r = q("update item set source_xchan = owner_xchan where id = %d limit 1", - intval($item_id) - ); - - // make sure encryption matches the new scope - - $title = $item['title']; - $body = $item['body']; - - if($private) { - if(!($flag_bits & ITEM_OBSCURED)) { - $key = get_config('system','pubkey'); - $flag_bits = $flag_bits|ITEM_OBSCURED; - $title = json_encode(aes_encapsulate($title,$key)); - $body = json_encode(aes_encapsulate($body,$key)); - } - } - else { - if($flag_bits & ITEM_OBSCURED) { - $key = get_config('system','prvkey'); - $flag_bits = $flag_bits ^ ITEM_OBSCURED; - $title = json_encode(aes_unencapsulate($title,$key)); - $body = json_encode(aes_unencapsulate($body,$key)); - } - } - - $r = q("update item set item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s', - deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s' where id = %d limit 1", - intval($flag_bits), - dbesc($u[0]['channel_hash']), - dbesc($u[0]['channel_allow_cid']), - dbesc($u[0]['channel_allow_gid']), - dbesc($u[0]['channel_deny_cid']), - dbesc($u[0]['channel_deny_gid']), - intval($private), - dbesc($new_public_policy), - dbesc(map_scope($u[0]['channel_w_comment'])), - dbesc($title), - dbesc($body), - intval($item_id) - ); - if($r) - proc_run('php','include/notifier.php','tgroup',$item_id); - else - logger('tag_deliver: failed to update item'); + start_delivery_chain($u[0],$item,$item_id,null); } @@ -2780,6 +2660,90 @@ function tgroup_check($uid,$item) { } +/** + * Sourced and tag-delivered posts are re-targetted for delivery to the connections of the channel + * receiving the post. This starts the second delivery chain, by resetting permissions and ensuring + * that ITEM_UPLINK is set on the parent post, and storing the current owner_xchan as the source_xchan. + * We'll become the new owner. If called without $parent, this *is* the parent post. + */ + +function start_delivery_chain($channel,$item,$item_id,$parent) { + + + // Change this copy of the post to a forum head message and deliver to all the tgroup members + // also reset all the privacy bits to the forum default permissions + + $private = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] + || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + + $new_public_policy = map_scope($channel['channel_r_stream'],true); + + if((! $private) && $new_public_policy) + $private = 1; + + $flag_bits = $item['item_flags'] | ITEM_WALL|ITEM_ORIGIN; + + // maintain the original source, which will be the original item owner and was stored in source_xchan + // when we created the delivery fork + + if($parent) { + $r = q("update item set source_xchan = '%s' where id = %d limit 1", + dbesc($parent['source_xchan']), + intval($item_id) + ); + } + else { + $flag_bits = $flag_bits | ITEM_UPLINK; + $r = q("update item set source_xchan = owner_xchan where id = %d limit 1", + intval($item_id) + ); + } + + $title = $item['title']; + $body = $item['body']; + + if($private) { + if(!($flag_bits & ITEM_OBSCURED)) { + $key = get_config('system','pubkey'); + $flag_bits = $flag_bits|ITEM_OBSCURED; + $title = json_encode(aes_encapsulate($title,$key)); + $body = json_encode(aes_encapsulate($body,$key)); + } + } + else { + if($flag_bits & ITEM_OBSCURED) { + $key = get_config('system','prvkey'); + $flag_bits = $flag_bits ^ ITEM_OBSCURED; + $title = json_encode(aes_unencapsulate($title,$key)); + $body = json_encode(aes_unencapsulate($body,$key)); + } + } + + $r = q("update item set item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s', + deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s' where id = %d limit 1", + intval($flag_bits), + dbesc($channel['channel_hash']), + dbesc($channel['channel_allow_cid']), + dbesc($channel['channel_allow_gid']), + dbesc($channel['channel_deny_cid']), + dbesc($channel['channel_deny_gid']), + intval($private), + dbesc($new_public_policy), + dbesc(map_scope($channel['channel_w_comment'])), + dbesc($title), + dbesc($body), + intval($item_id) + ); + + if($r) + proc_run('php','include/notifier.php','tgroup',$item_id); + else + logger('start_delivery_chain: failed to update item'); + + return; +} + + /** * @function check_item_source($uid,$item) diff --git a/mod/profiles.php b/mod/profiles.php index b938e836b..d6df09e9a 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -568,6 +568,24 @@ function profiles_content(&$a) { '$no_selected' => (($r[0]['hide_friends'] == 0) ? " checked=\"checked\" " : "") )); + $q = q("select * from profdef where true"); + if($q) { + $extra_fields = array(); + + foreach($q as $qq) { + $mine = q("select v from profext where k = '%s' and hash = '%s' and channel_id = %d limit 1", + dbesc($qq['field_name']), + dbesc($r[0]['profile_guid']), + intval(local_user()) + ); + + if(array_key_exists($qq['field_name'],$fields)) { + $extra_fields[] = array($qq['field_name'],$qq['field_desc'],(($mine) ? $mine[0]['v'] : ''), $qq['field_help']); + } + } + } + +logger('extra_fields: ' . print_r($extra_fields,true)); $f = get_config('system','birthday_input_format'); if(! $f) @@ -674,6 +692,7 @@ function profiles_content(&$a) { '$education' => $r[0]['education'], '$contact' => $r[0]['contact'], '$channels' => $r[0]['channels'], + '$extra_fields' => $extra_fields, )); $arr = array('profile' => $r[0], 'entry' => $o); diff --git a/view/tpl/profile_edit.tpl b/view/tpl/profile_edit.tpl index 0e902e9e2..87582da56 100755 --- a/view/tpl/profile_edit.tpl +++ b/view/tpl/profile_edit.tpl @@ -349,6 +349,11 @@
{{/if}} +{{if $extra_fields}} +{{foreach $extra_fields as $field }} +{{include file="field_input.tpl" field=$field}} +{{/foreach}} +{{/if}}
-- cgit v1.2.3 From a59a6fbd90d115cf9e9836c986c81541a88697ee Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 01:41:15 -0700 Subject: abook-edit-me class lost during some edit - we need this to reset the permission fields --- version.inc | 2 +- view/tpl/field_acheckbox.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/version.inc b/version.inc index ed8a8be13..8936c7bc8 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -2014-08-20.773 +2014-08-21.774 diff --git a/view/tpl/field_acheckbox.tpl b/view/tpl/field_acheckbox.tpl index 342491ded..89de170b7 100755 --- a/view/tpl/field_acheckbox.tpl +++ b/view/tpl/field_acheckbox.tpl @@ -6,7 +6,7 @@ - + {{if $field.5}}{{$inherited}} {{/if}} -- cgit v1.2.3 From 831714f0f0e5bd9a17c760a2476a12603be5d089 Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 16:46:24 -0700 Subject: profile edit - missing visibility and drop link on non-default profiles, re-arrange order of replacing red#matrix smilie so it works correctly, accept a post with body content of '0' which was interpreted by x() as nothing (was treated as integer). --- include/items.php | 8 ++++---- include/text.php | 8 ++++---- mod/item.php | 1 - view/tpl/profile_edit.tpl | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/items.php b/include/items.php index fbe67817d..783c67752 100755 --- a/include/items.php +++ b/include/items.php @@ -1664,8 +1664,8 @@ function item_store($arr,$allow_exec = false) { } - $arr['title'] = ((x($arr,'title')) ? trim($arr['title']) : ''); - $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); + $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : ''); + $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); $arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : ''); $arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : ''); @@ -2136,7 +2136,6 @@ function item_store_update($arr,$allow_exec = false) { $arr['commented'] = $orig[0]['commented']; $arr['received'] = datetime_convert(); $arr['changed'] = datetime_convert(); - $arr['title'] = ((x($arr,'title')) ? notags(trim($arr['title'])) : ''); $arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : $orig[0]['location']); $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']); $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']); @@ -2152,7 +2151,8 @@ function item_store_update($arr,$allow_exec = false) { $arr['deny_gid'] = ((array_key_exists('deny_gid',$arr)) ? trim($arr['deny_gid']) : $orig[0]['deny_gid']); $arr['item_private'] = ((array_key_exists('item_private',$arr)) ? intval($arr['item_private']) : $orig[0]['item_private']); - $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); + $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : ''); + $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : ''); $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : $orig[0]['attach']); $arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : $orig[0]['app']); // $arr['item_restrict'] = ((x($arr,'item_restrict')) ? intval($arr['item_restrict']) : $orig[0]['item_restrict'] ); diff --git a/include/text.php b/include/text.php index 680e6fe95..d3d8b84a6 100755 --- a/include/text.php +++ b/include/text.php @@ -1002,9 +1002,9 @@ function smilies($s, $sample = false) { ':facepalm', ':like', ':dislike', + 'red#matrix', 'red#', - 'r#', - 'red#matrix' + 'r#' ); $icons = array( @@ -1040,9 +1040,9 @@ function smilies($s, $sample = false) { ':facepalm', ':like', ':dislike', + 'redred#matrixmatrix', 'redred#matrix', - 'redr#matrix', - 'redred#matrixmatrix' + 'redr#matrix' ); diff --git a/mod/item.php b/mod/item.php index 92dc3e7c6..27691eb4f 100644 --- a/mod/item.php +++ b/mod/item.php @@ -790,7 +790,6 @@ function item_post(&$a) { else $post_id = 0; - $post = item_store($datarray,$execflag); $post_id = $post['item_id']; diff --git a/view/tpl/profile_edit.tpl b/view/tpl/profile_edit.tpl index 87582da56..b453b1cfa 100755 --- a/view/tpl/profile_edit.tpl +++ b/view/tpl/profile_edit.tpl @@ -9,12 +9,12 @@ -- cgit v1.2.3 From 921799b045c376c2ffe80a0c4fe0dc6c2c78e854 Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 17:42:19 -0700 Subject: make the old personal xrd interface (old webfinger) work again --- include/crypto.php | 5 +++-- mod/xrd.php | 21 +++++++++++++++++---- view/tpl/xrd_diaspora.tpl | 8 ++++++++ view/tpl/xrd_person.tpl | 10 +++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 view/tpl/xrd_diaspora.tpl diff --git a/include/crypto.php b/include/crypto.php index c053dfae2..07655e24f 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -1,5 +1,8 @@ $a->get_baseurl(), + '$dspr_guid' => $r[0]['channel_guid'], + '$dspr_key' => base64_encode(pemtorsa($r[0]['channel_pubkey'])) + )); + } + else + $dspr = ''; + + + + $salmon_key = salmon_key($r[0]['channel_pubkey']); header('Access-Control-Allow-Origin: *'); header("Content-type: text/xml"); @@ -34,15 +47,15 @@ function xrd_init(&$a) { '$nick' => $r[0]['channel_address'], '$accturi' => $uri, '$profile_url' => $a->get_baseurl() . '/channel/' . $r[0]['channel_address'], -// '$hcard_url' => $a->get_baseurl() . '/hcard/' . $r[0]['channel_address'], + '$hcard_url' => $a->get_baseurl() . '/hcard/' . $r[0]['channel_address'], '$atom' => $a->get_baseurl() . '/feed/' . $r[0]['channel_address'], '$zot_post' => $a->get_baseurl() . '/post/' . $r[0]['channel_address'], '$poco_url' => $a->get_baseurl() . '/poco/' . $r[0]['channel_address'], '$photo' => $a->get_baseurl() . '/photo/profile/l/' . $r[0]['channel_id'], -// '$dspr' => $dspr, + '$dspr' => $dspr, // '$salmon' => $a->get_baseurl() . '/salmon/' . $r[0]['channel_address'], // '$salmen' => $a->get_baseurl() . '/salmon/' . $r[0]['channel_address'] . '/mention', -// '$modexp' => 'data:application/magic-public-key,' . $salmon_key, + '$modexp' => 'data:application/magic-public-key,' . $salmon_key, // '$bigkey' => salmon_key($r[0]['pubkey']) )); diff --git a/view/tpl/xrd_diaspora.tpl b/view/tpl/xrd_diaspora.tpl new file mode 100644 index 000000000..143980bcc --- /dev/null +++ b/view/tpl/xrd_diaspora.tpl @@ -0,0 +1,8 @@ +{{* + * AUTOMATICALLY GENERATED TEMPLATE + * DO NOT EDIT THIS FILE, CHANGES WILL BE OVERWRITTEN + * + *}} + + + diff --git a/view/tpl/xrd_person.tpl b/view/tpl/xrd_person.tpl index 20d438dd5..631ed3f18 100755 --- a/view/tpl/xrd_person.tpl +++ b/view/tpl/xrd_person.tpl @@ -14,5 +14,13 @@ - + + + + + {{$dspr}} + -- cgit v1.2.3 From e524835463fa0411723d2ec57276d1ac13c3aca6 Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 20:31:55 -0700 Subject: the rest of the diaspora local discovery stuff --- include/identity.php | 24 +++++++++++++++++++++--- view/tpl/profile_vcard.tpl | 3 +++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/identity.php b/include/identity.php index 9335673a0..8b742f53e 100644 --- a/include/identity.php +++ b/include/identity.php @@ -770,9 +770,26 @@ logger('online: ' . $profile['online']); $location = $pdesc = $gender = $marital = $homepage = $online = False; } - $firstname = ((strpos($profile['name'],' ')) - ? trim(substr($profile['name'],0,strpos($profile['name'],' '))) : $profile['name']); - $lastname = (($firstname === $profile['name']) ? '' : trim(substr($profile['name'],strlen($firstname)))); + $firstname = ((strpos($profile['channel_name'],' ')) + ? trim(substr($profile['channel_name'],0,strpos($profile['channel_name'],' '))) : $profile['channel_name']); + $lastname = (($firstname === $profile['channel_name']) ? '' : trim(substr($profile['channel_name'],strlen($firstname)))); + + if(get_config('system','diaspora_enabled')) { + $diaspora = array( + 'podloc' => z_root(), + 'searchable' => (($block) ? 'false' : 'true'), + 'nickname' => $profile['channel_address'], + 'fullname' => $profile['channel_name'], + 'firstname' => $firstname, + 'lastname' => $lastname, + 'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg', + 'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg', + 'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg', + ); + } + else + $diaspora = null; + $contact_block = contact_block(); @@ -802,6 +819,7 @@ logger('online: ' . $profile['online']); '$marital' => $marital, '$homepage' => $homepage, '$chanmenu' => $channel_menu, + '$diaspora' => $diaspora, '$contact_block' => $contact_block, )); diff --git a/view/tpl/profile_vcard.tpl b/view/tpl/profile_vcard.tpl index a653dca7d..7dff8fdeb 100755 --- a/view/tpl/profile_vcard.tpl +++ b/view/tpl/profile_vcard.tpl @@ -43,6 +43,9 @@ {{if $homepage}}
{{$homepage}}
{{$profile.homepage}}
{{/if}} + {{if $diaspora}} + {{include file="diaspora_vcard.tpl"}} + {{/if}} {{if $connect}} {{$connect}} -- cgit v1.2.3 From 05515e3b10d2dcc6cf306e1749c1717e96dfcff2 Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 20:42:55 -0700 Subject: D* receive endpoint is receive/users/$guid - where $guid is really the channel_guid, not the channel_hash. We'll allow this to be truncated for older D* sites or those that can't process our 64 character guids. --- mod/receive.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mod/receive.php b/mod/receive.php index c5a2dc4e0..4071b169b 100644 --- a/mod/receive.php +++ b/mod/receive.php @@ -4,8 +4,6 @@ * Diaspora endpoint */ - -//require_once('include/salmon.php'); require_once('include/crypto.php'); require_once('include/diaspora.php'); @@ -31,8 +29,11 @@ function receive_post(&$a) { $guid = argv(2); - $r = q("SELECT * FROM channel left join account on account_id = channel_account_id WHERE channel_guid = '%s' AND account_flags = 0 LIMIT 1", - dbesc($guid) + // Diaspora sites *may* provide a truncated guid. + + $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_guid like '%s' AND NOT (channel_pageflags & %d ) LIMIT 1", + dbesc($guid . '%'), + intval(PAGE_REMOVED) ); if(! $r) http_status_exit(500); -- cgit v1.2.3 From 72a766432d90f6eec44641466e77567808f61aca Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 20:45:15 -0700 Subject: missing template file --- view/tpl/diaspora_vcard.tpl | 57 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 view/tpl/diaspora_vcard.tpl diff --git a/view/tpl/diaspora_vcard.tpl b/view/tpl/diaspora_vcard.tpl new file mode 100644 index 000000000..9d234a398 --- /dev/null +++ b/view/tpl/diaspora_vcard.tpl @@ -0,0 +1,57 @@ +
+
+
Nickname
+
+ {{$diaspora.nickname}} +
+
+
+
Full name
+
+ {{$diaspora.fullname}} +
+
+ +
+
First name
+
+ {{$diaspora.firstname}} +
+
+
+
Family name
+
+ {{$diaspora.lastname}} +
+
+
+
URL
+
+ {{$diaspora.podloc}}/ +
+
+
+
Photo
+
+ +
+
+
+
Photo
+
+ +
+
+
+
Photo
+
+ +
+
+
+
Searchable
+
+ {{$diaspora.searchable}} +
+
+
-- cgit v1.2.3 From 69d3e5468d970633412cbdc731a4e477181dbc8c Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 21:07:32 -0700 Subject: provide the site blacklist everywhere it is needed --- include/diaspora.php | 26 ++++++++++++++++++++++++++ include/externals.php | 2 +- include/zot.php | 16 ++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/diaspora.php b/include/diaspora.php index dda552536..2010b1494 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -106,6 +106,26 @@ function diaspora_dispatch($importer,$msg,$attempt=1) { return $ret; } + +function diaspora_is_blacklisted($s) { + + $bl1 = get_config('system','blacklisted_sites'); + if(is_array($bl1) && $bl1) { + foreach($bl1 as $bl) { + if($bl && strpos($s,$bl) !== false) { + logger('diaspora_is_blacklisted: blacklisted ' . $s); + return true; + } + } + } + return false; +} + + + + + + function diaspora_handle_from_contact($contact_id) { $handle = false; @@ -122,6 +142,10 @@ function diaspora_handle_from_contact($contact_id) { } function diaspora_get_contact_by_handle($uid,$handle) { + + if(diaspora_is_blacklisted($handle)) + return false; + $r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan where xchan_addr = '%s' and abook_channel = %d limit 1", dbesc($handle), intval($uid) @@ -140,6 +164,8 @@ function find_diaspora_person_by_handle($handle) { $endlessloop = 0; $maxloops = 10; + if(diaspora_is_blacklisted($handle)) + return false; $r = q("select * from xchan where xchan_addr = '%s' limit 1", dbesc($handle) diff --git a/include/externals.php b/include/externals.php index a96bf7c97..8944524b7 100644 --- a/include/externals.php +++ b/include/externals.php @@ -41,7 +41,7 @@ function externals_run($argv, $argc){ $bl1 = get_config('system','blacklisted_sites'); if(is_array($bl1) && $bl1) { foreach($bl1 as $bl) { - if(strpos($url,$bl) !== false) { + if($bl && strpos($url,$bl) !== false) { $blacklisted = true; break; } diff --git a/include/zot.php b/include/zot.php index 8b0efe09d..41d0bc1eb 100644 --- a/include/zot.php +++ b/include/zot.php @@ -507,6 +507,22 @@ function zot_refresh($them,$channel = null, $force = false) { function zot_gethub($arr) { if($arr['guid'] && $arr['guid_sig'] && $arr['url'] && $arr['url_sig']) { + + $blacklisted = false; + $bl1 = get_config('system','blacklisted_sites'); + if(is_array($bl1) && $bl1) { + foreach($bl1 as $bl) { + if($bl && strpos($arr['url'],$bl) !== false) { + $blacklisted = true; + break; + } + } + } + if($blacklisted) { + logger('zot_gethub: blacklisted site: ' . $arr['url']); + return null; + } + $r = q("select * from hubloc where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' -- cgit v1.2.3 From 1abd2a2917504d102a6e4c6a9c34fa4a5fba4937 Mon Sep 17 00:00:00 2001 From: friendica Date: Thu, 21 Aug 2014 22:28:09 -0700 Subject: another round of heavy lifting --- include/diaspora.php | 211 ++++++++++++++++++++++++--------------------------- 1 file changed, 99 insertions(+), 112 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 2010b1494..982e40f2f 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -126,19 +126,17 @@ function diaspora_is_blacklisted($s) { -function diaspora_handle_from_contact($contact_id) { - $handle = false; +function diaspora_handle_from_contact($contact_hash) { - logger("diaspora_handle_from_contact: contact id is " . $contact_id, LOGGER_DEBUG); + logger("diaspora_handle_from_contact: contact id is " . $contact_hash, LOGGER_DEBUG); - $r = q("SELECT * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d", - intval($contact_id) + $r = q("SELECT * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' limit 1", + intval($contact_hash) ); if($r) { - $contact = $r[0]; + return $r[0]['xchan_addr']; } - $handle = $contact['xchan_addr']; - return $handle; + return false; } function diaspora_get_contact_by_handle($uid,$handle) { @@ -150,9 +148,7 @@ function diaspora_get_contact_by_handle($uid,$handle) { dbesc($handle), intval($uid) ); - if($r) - return $r[0]; - return false; + return (($r) ? $r[0] : false); } function find_diaspora_person_by_handle($handle) { @@ -188,6 +184,7 @@ function find_diaspora_person_by_handle($handle) { $result = discover_by_webbie($handle); + } @@ -195,13 +192,10 @@ function find_diaspora_person_by_handle($handle) { } -function get_diaspora_key($uri) { - logger('Fetching diaspora key for: ' . $uri); - - $r = find_diaspora_person_by_handle($uri); - if($r) - return $r['pubkey']; - return ''; +function get_diaspora_key($handle) { + logger('Fetching diaspora key for: ' . $handle, LOGGER_DEBUG); + $r = find_diaspora_person_by_handle($handle); + return(($r) ? $r['xchan_pubkey'] : ''); } @@ -376,7 +370,7 @@ function diaspora_decode($importer,$xml) { $ciphertext = base64_decode($encrypted_header->ciphertext); $outer_key_bundle = ''; - openssl_private_decrypt($encrypted_aes_key_bundle,$outer_key_bundle,$importer['prvkey']); + openssl_private_decrypt($encrypted_aes_key_bundle,$outer_key_bundle,$importer['channel_prvkey']); $j_outer_key_bundle = json_decode($outer_key_bundle); @@ -454,7 +448,6 @@ function diaspora_decode($importer,$xml) { $encoding = $base->encoding; $alg = $base->alg; - $signed_data = $data . '.' . base64url_encode($type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($alg); @@ -606,15 +599,14 @@ function diaspora_request($importer,$xml) { return; } -//FIXME -// $g = q("select def_gid from user where uid = %d limit 1", -// intval($importer['channel_id']) -// ); -// if($g && intval($g[0]['def_gid'])) { -// require_once('include/group.php'); -// group_add_member($importer['channel_id'],'',$contact_record['id'],$g[0]['def_gid']); -// } + /** If there is a default group for this channel, add this member to it */ + if($importer['channel_default_group']) { + require_once('include/group.php'); + $g = group_rec_byhash($importer['channel_id'],$importer['channel_default_group']); + if($g) + group_add_member($importer['channel_id'],'',$contact_record['xchan_hash'],$g['id']); + } return; } @@ -706,9 +698,6 @@ function diaspora_post($importer,$xml,$msg) { $datarray['uid'] = $importer['channel_id']; // FIXME - $datarray['contact-id'] = $contact['id']; - $datarray['wall'] = 0; - $datarray['network'] = NETWORK_DIASPORA; $datarray['verb'] = ACTIVITY_POST; @@ -717,7 +706,6 @@ function diaspora_post($importer,$xml,$msg) { $datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert('UTC','UTC',$created); $datarray['item_private'] = $private; - $datarray['plink'] = $plink; $datarray['author_xchan'] = $contact['xchan_hash']; @@ -2055,8 +2043,8 @@ function diaspora_profile($importer,$xml,$msg) { function diaspora_share($me,$contact) { $a = get_app(); - $myaddr = $me['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); - $theiraddr = $contact['addr']; + $myaddr = $me['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $theiraddr = $contact['xchan_addr']; $tpl = get_markup_template('diaspora_share.tpl'); $msg = replace_macros($tpl, array( @@ -2093,8 +2081,8 @@ function diaspora_unshare($me,$contact) { function diaspora_send_status($item,$owner,$contact,$public_batch = false) { $a = get_app(); - $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); - $theiraddr = $contact['addr']; + $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $theiraddr = $contact['xchan_addr']; $images = array(); @@ -2146,44 +2134,44 @@ function diaspora_send_status($item,$owner,$contact,$public_batch = false) { } - $public = (($item['private']) ? 'false' : 'true'); + $public = (($item['item_private']) ? 'false' : 'true'); require_once('include/datetime.php'); $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C'); // Detect a share element and do a reshare // see: https://github.com/Raven24/diaspora-federation/blob/master/lib/diaspora-federation/entities/reshare.rb - if (!$item['private'] AND ($ret = diaspora_is_reshare($item["body"]))) { + if (!$item['item_private'] AND ($ret = diaspora_is_reshare($item["body"]))) { $tpl = get_markup_template('diaspora_reshare.tpl'); $msg = replace_macros($tpl, array( '$root_handle' => xmlify($ret['root_handle']), '$root_guid' => $ret['root_guid'], - '$guid' => $item['guid'], + '$guid' => $item['mid'], '$handle' => xmlify($myaddr), '$public' => $public, '$created' => $created, - '$provider' => $item["app"] + '$provider' => $item['app'] )); } else { $tpl = get_markup_template('diaspora_post.tpl'); $msg = replace_macros($tpl, array( '$body' => $body, - '$guid' => $item['guid'], + '$guid' => $item['mid'], '$handle' => xmlify($myaddr), '$public' => $public, '$created' => $created, - '$provider' => $item["app"] + '$provider' => $item['app'] )); } - logger('diaspora_send_status: '.$owner['username'].' -> '.$contact['name'].' base message: '.$msg, LOGGER_DATA); + logger('diaspora_send_status: '.$owner['channel_name'].' -> '.$contact['xchan_name'].' base message: '.$msg, LOGGER_DATA); - $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch))); + $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch))); //$slap = 'xml=' . urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch)); $return_code = diaspora_transmit($owner,$contact,$slap,$public_batch); - logger('diaspora_send_status: guid: '.$item['guid'].' result '.$return_code, LOGGER_DEBUG); + logger('diaspora_send_status: guid: '.$item['mid'].' result '.$return_code, LOGGER_DEBUG); if(count($images)) { diaspora_send_images($item,$owner,$contact,$images,$public_batch); @@ -2193,51 +2181,52 @@ function diaspora_send_status($item,$owner,$contact,$public_batch = false) { } function diaspora_is_reshare($body) { + $body = trim($body); - // Skip if it isn't a pure repeated messages - // Does it start with a share? - if (strpos($body, "[share") > 0) - return(false); + // Skip if it isn't a pure repeated messages + // Does it start with a share? + if(strpos($body, "[share") > 0) + return(false); - // Does it end with a share? - if (strlen($body) > (strrpos($body, "[/share]") + 8)) - return(false); + // Does it end with a share? + if(strlen($body) > (strrpos($body, "[/share]") + 8)) + return(false); - $attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","$1",$body); - // Skip if there is no shared message in there - if ($body == $attributes) - return(false); + $attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","$1",$body); + // Skip if there is no shared message in there + if ($body == $attributes) + return(false); - $profile = ""; - preg_match("/profile='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $profile = $matches[1]; + $profile = ""; + preg_match("/profile='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") + $profile = $matches[1]; - preg_match('/profile="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") - $profile = $matches[1]; + preg_match('/profile="(.*?)"/ism', $attributes, $matches); + if ($matches[1] != "") + $profile = $matches[1]; - $ret= array(); + $ret= array(); - $ret["root_handle"] = preg_replace("=https?://(.*)/u/(.*)=ism", "$2@$1", $profile); - if (($ret["root_handle"] == $profile) OR ($ret["root_handle"] == "")) - return(false); + $ret["root_handle"] = preg_replace("=https?://(.*)/u/(.*)=ism", "$2@$1", $profile); + if (($ret["root_handle"] == $profile) OR ($ret["root_handle"] == "")) + return(false); - $link = ""; - preg_match("/link='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") - $link = $matches[1]; + $link = ""; + preg_match("/link='(.*?)'/ism", $attributes, $matches); + if ($matches[1] != "") + $link = $matches[1]; - preg_match('/link="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") - $link = $matches[1]; + preg_match('/link="(.*?)"/ism', $attributes, $matches); + if ($matches[1] != "") + $link = $matches[1]; - $ret["root_guid"] = preg_replace("=https?://(.*)/posts/(.*)=ism", "$2", $link); - if (($ret["root_guid"] == $link) OR ($ret["root_guid"] == "")) - return(false); + $ret["root_guid"] = preg_replace("=https?://(.*)/posts/(.*)=ism", "$2", $link); + if (($ret["root_guid"] == $link) OR ($ret["root_guid"] == "")) + return(false); - return($ret); + return($ret); } function diaspora_send_images($item,$owner,$contact,$images,$public_batch = false) { @@ -2253,18 +2242,18 @@ function diaspora_send_images($item,$owner,$contact,$images,$public_batch = fals $resource = str_replace('.jpg','',$image['file']); $resource = substr($resource,0,strpos($resource,'-')); - $r = q("select * from photo where `resource-id` = '%s' and `uid` = %d limit 1", + $r = q("select * from photo where `resource_id` = '%s' and `uid` = %d limit 1", dbesc($resource), intval($owner['uid']) ); - if(! count($r)) + if(! $r) continue; $public = (($r[0]['allow_cid'] || $r[0]['allow_gid'] || $r[0]['deny_cid'] || $r[0]['deny_gid']) ? 'false' : 'true' ); $msg = replace_macros($tpl,array( '$path' => xmlify($image['path']), '$filename' => xmlify($image['file']), '$msg_guid' => xmlify($image['guid']), - '$guid' => xmlify($r[0]['guid']), + '$guid' => xmlify($r[0]['resource_id']), '$handle' => xmlify($image['handle']), '$public' => xmlify($public), '$created_at' => xmlify(datetime_convert('UTC','UTC',$r[0]['created'],'Y-m-d H:i:s \U\T\C')) @@ -2272,7 +2261,7 @@ function diaspora_send_images($item,$owner,$contact,$images,$public_batch = fals logger('diaspora_send_photo: base message: ' . $msg, LOGGER_DATA); - $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch))); + $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch))); //$slap = 'xml=' . urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch)); diaspora_transmit($owner,$contact,$slap,$public_batch); @@ -2283,27 +2272,27 @@ function diaspora_send_images($item,$owner,$contact,$images,$public_batch = fals function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { $a = get_app(); - $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); -// $theiraddr = $contact['addr']; + $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $theiraddr = $contact['xchan_addr']; // Diaspora doesn't support threaded comments, but some // versions of Diaspora (i.e. Diaspora-pistos) support // likes on comments - if($item['verb'] === ACTIVITY_LIKE && $item['thr-parent']) { - $p = q("select guid, type, uri, `parent-uri` from item where uri = '%s' limit 1", - dbesc($item['thr-parent']) - ); + if($item['verb'] === ACTIVITY_LIKE && $item['thr_parent']) { + $p = q("select mid, parent_mid from item where mid = '%s' limit 1", + dbesc($item['thr_parent']) + ); } else { // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent. // The only item with `parent` and `id` as the parent id is the parent item. - $p = q("select guid, type, uri, `parent-uri` from item where parent = %d and id = %d limit 1", + $p = q("select * from item where parent = %d and id = %d limit 1", intval($item['parent']), intval($item['parent']) ); } - if(count($p)) + if($p) $parent = $p[0]; else return; @@ -2311,12 +2300,10 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { if($item['verb'] === ACTIVITY_LIKE) { $tpl = get_markup_template('diaspora_like.tpl'); $like = true; - $target_type = ( $parent['uri'] === $parent['parent-uri'] ? 'Post' : 'Comment'); -// $target_type = (strpos($parent['type'], 'comment') ? 'Comment' : 'Post'); -// $positive = (($item['deleted']) ? 'false' : 'true'); + $target_type = ( $parent['mid'] === $parent['parent_mid'] ? 'Post' : 'Comment'); $positive = 'true'; - if(($item['deleted'])) + if(($item_['item_restrict'] & ITEM_DELETED)) logger('diaspora_send_followup: received deleted "like". Those should go to diaspora_send_retraction'); } else { @@ -2329,15 +2316,15 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { // sign it if($like) - $signed_text = $item['guid'] . ';' . $target_type . ';' . $parent['guid'] . ';' . $positive . ';' . $myaddr; + $signed_text = $item['mid'] . ';' . $target_type . ';' . $parent['mid'] . ';' . $positive . ';' . $myaddr; else - $signed_text = $item['guid'] . ';' . $parent['guid'] . ';' . $text . ';' . $myaddr; + $signed_text = $item['mid'] . ';' . $parent['mid'] . ';' . $text . ';' . $myaddr; - $authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256')); + $authorsig = base64_encode(rsa_sign($signed_text,$owner['channel_prvkey'],'sha256')); $msg = replace_macros($tpl,array( - '$guid' => xmlify($item['guid']), - '$parent_guid' => xmlify($parent['guid']), + '$guid' => xmlify($item['mid']), + '$parent_guid' => xmlify($parent['mid']), '$target_type' =>xmlify($target_type), '$authorsig' => xmlify($authorsig), '$body' => xmlify($text), @@ -2347,8 +2334,8 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) { logger('diaspora_followup: base message: ' . $msg, LOGGER_DATA); - $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch))); - //$slap = 'xml=' . urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch)); + $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch))); + return(diaspora_transmit($owner,$contact,$slap,$public_batch)); } @@ -2358,7 +2345,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $a = get_app(); - $myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); // $theiraddr = $contact['addr']; $body = $item['body']; @@ -2367,21 +2354,21 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { // Diaspora doesn't support threaded comments, but some // versions of Diaspora (i.e. Diaspora-pistos) support // likes on comments - if($item['verb'] === ACTIVITY_LIKE && $item['thr-parent']) { - $p = q("select guid, type, uri, `parent-uri` from item where uri = '%s' limit 1", - dbesc($item['thr-parent']) - ); + if($item['verb'] === ACTIVITY_LIKE && $item['thr_parent']) { + $p = q("select * from item where mid = '%s' limit 1", + dbesc($item['thr_parent']) + ); } else { // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent. // The only item with `parent` and `id` as the parent id is the parent item. - $p = q("select guid, type, uri, `parent-uri` from item where parent = %d and id = %d limit 1", + $p = q("select * from item where parent = %d and id = %d limit 1", intval($item['parent']), intval($item['parent']) ); } - if(count($p)) + if($p) $parent = $p[0]; else return; @@ -2389,7 +2376,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $like = false; $relay_retract = false; $sql_sign_id = 'iid'; - if( $item['deleted']) { + if( $item['item_restrict'] & ITEM_DELETED) { $relay_retract = true; $target_type = ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment'); @@ -2400,8 +2387,8 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { elseif($item['verb'] === ACTIVITY_LIKE) { $like = true; - $target_type = ( $parent['uri'] === $parent['parent-uri'] ? 'Post' : 'Comment'); -// $positive = (($item['deleted']) ? 'false' : 'true'); + $target_type = ( $parent['mid'] === $parent['parent_mid'] ? 'Post' : 'Comment'); +// $positive = (($item['item_restrict'] & ITEM_DELETED) ? 'false' : 'true'); $positive = 'true'; $tpl = get_markup_template('diaspora_like_relay.tpl'); @@ -2445,7 +2432,7 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { * been done yet */ - $handle = diaspora_handle_from_contact($item['contact-id']); + $handle = diaspora_handle_from_contact($item['author_xchan']); if(! $handle) return; -- cgit v1.2.3