X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=include%2FScrape.php;h=629f7a063bf3ba409177495caa21a4cbcca3e582;hb=8b20af6ef536e34c3bc9c412cbffa4cf9c0cea53;hp=bf64c2243fedac734009bb6faa3aa561bb0c2f42;hpb=0283cbfcd35a29b5689ffbf16439d448de0c7254;p=friendica.git diff --git a/include/Scrape.php b/include/Scrape.php index bf64c2243f..629f7a063b 100644 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -14,7 +14,7 @@ function scrape_dfrn($url) { $s = fetch_url($url); - if(! $s) + if(! $s) return $ret; $headers = $a->get_curl_headers(); @@ -23,15 +23,18 @@ function scrape_dfrn($url) { $lines = explode("\n",$headers); if(count($lines)) { - foreach($lines as $line) { + 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; } } - - $dom = HTML5_Parser::parse($s); + try { + $dom = HTML5_Parser::parse($s); + } catch (DOMException $e) { + logger('scrape_dfrn: parse error: ' . $e); + } if(! $dom) return $ret; @@ -117,7 +120,7 @@ function scrape_meta($url) { $s = fetch_url($url); - if(! $s) + if(! $s) return $ret; $headers = $a->get_curl_headers(); @@ -125,16 +128,18 @@ function scrape_meta($url) { $lines = explode("\n",$headers); if(count($lines)) { - foreach($lines as $line) { + 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; } } - - - $dom = HTML5_Parser::parse($s); + try { + $dom = HTML5_Parser::parse($s); + } catch (DOMException $e) { + logger('scrape_meta: parse error: ' . $e); + } if(! $dom) return $ret; @@ -164,20 +169,24 @@ function scrape_vcard($url) { $s = fetch_url($url); - if(! $s) + if(! $s) return $ret; $headers = $a->get_curl_headers(); $lines = explode("\n",$headers); if(count($lines)) { - foreach($lines as $line) { + 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; } } - $dom = HTML5_Parser::parse($s); + try { + $dom = HTML5_Parser::parse($s); + } catch (DOMException $e) { + logger('scrape_vcard: parse error: ' . $e); + } if(! $dom) return $ret; @@ -221,15 +230,20 @@ function scrape_feed($url) { $ret = array(); $s = fetch_url($url); - if(! $s) + $headers = $a->get_curl_headers(); + $code = $a->get_curl_code(); + + logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG); + + if(! $s) { + logger('scrape_feed: no data returned for ' . $url); return $ret; + } - $headers = $a->get_curl_headers(); - logger('scrape_feed: headers=' . $headers, LOGGER_DEBUG); $lines = explode("\n",$headers); if(count($lines)) { - foreach($lines as $line) { + foreach($lines as $line) { if(stristr($line,'content-type:')) { if(stristr($line,'application/atom+xml') || stristr($s,'')) { + $ret['feed_rss'] = $url; + return $ret; + } } - $dom = HTML5_Parser::parse($s); + try { + $dom = HTML5_Parser::parse($s); + } catch (DOMException $e) { + logger('scrape_feed: parse error: ' . $e); + } - if(! $dom) + if(! $dom) { + logger('scrape_feed: failed to parse.'); return $ret; - - - $items = $dom->getElementsByTagName('img'); - - // get img elements (twitter) - - if($items) { - foreach($items as $item) { - $x = $item->getAttribute('id'); - if($x === 'profile-image') { - $ret['photo'] = $item->getAttribute('src'); - } - } } @@ -271,7 +282,7 @@ function scrape_feed($url) { } } if(! $basename) - $basename = substr($url,0,strrpos($url,'/')) . '/'; + $basename = implode('/', array_slice(explode('/',$url),0,3)) . '/'; $items = $dom->getElementsByTagName('link'); @@ -288,7 +299,7 @@ function scrape_feed($url) { if(! x($ret,'feed_rss')) $ret['feed_rss'] = $item->getAttribute('href'); } - } + } } // Drupal and perhaps others only provide relative URL's. Turn them into absolute. @@ -315,7 +326,7 @@ function scrape_feed($url) { * * PROBE_DIASPORA has a bias towards returning Diaspora information * while PROBE_NORMAL has a bias towards dfrn/zot - in the case where - * an address (such as a Friendika address) supports more than one type + * an address (such as a Friendica address) supports more than one type * of network. * */ @@ -335,16 +346,18 @@ function probe_url($url, $mode = PROBE_NORMAL) { $network = null; $diaspora = false; $diaspora_base = ''; - $diaspora_guid = ''; + $diaspora_guid = ''; $diaspora_key = ''; $has_lrdd = false; $email_conversant = false; - $twitter = ((strpos($url,'twitter.com') !== false) ? true : false); + // Twitter is deactivated since twitter closed its old API + //$twitter = ((strpos($url,'twitter.com') !== false) ? true : false); + $lastfm = ((strpos($url,'last.fm/user') !== false) ? true : false); $at_addr = ((strpos($url,'@') !== false) ? true : false); - if(! $twitter) { + if((! $twitter) && (! $lastfm)) { if(strpos($url,'mailto:') !== false && $at_addr) { $url = str_replace('mailto:','',$url); @@ -370,6 +383,8 @@ function probe_url($url, $mode = PROBE_NORMAL) { $hcard = unamp($link['@attributes']['href']); if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') $profile = unamp($link['@attributes']['href']); + if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') + $poco = unamp($link['@attributes']['href']); if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') { $diaspora_base = unamp($link['@attributes']['href']); $diaspora = true; @@ -380,7 +395,10 @@ function probe_url($url, $mode = PROBE_NORMAL) { } if($link['@attributes']['rel'] === 'diaspora-public-key') { $diaspora_key = base64_decode(unamp($link['@attributes']['href'])); - $pubkey = rsatopem($diaspora_key); + if(strstr($diaspora_key,'RSA ')) + $pubkey = rsatopem($diaspora_key); + else + $pubkey = $diaspora_key; $diaspora = true; } } @@ -418,37 +436,57 @@ function probe_url($url, $mode = PROBE_NORMAL) { intval(local_user()) ); if(count($x) && count($r)) { - $mailbox = construct_mailbox_name($r[0]); + $mailbox = construct_mailbox_name($r[0]); $password = ''; openssl_private_decrypt(hex2bin($r[0]['pass']),$password,$x[0]['prvkey']); $mbox = email_connect($mailbox,$r[0]['user'],$password); + if(! $mbox) + logger('probe_url: email_connect failed.'); unset($password); } if($mbox) { $msgs = email_poll($mbox,$orig_url); + logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG); if(count($msgs)) { $addr = $orig_url; $network = NETWORK_MAIL; $name = substr($url,0,strpos($url,'@')); - $profile = 'http://' . substr($url,strpos($url,'@')+1); + $phost = substr($url,strpos($url,'@')+1); + $profile = 'http://' . $phost; // fix nick character range - $vcard = array('fn' => $name, 'nick' => $name, 'photo' => gravatar_img($url)); + $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url)); $notify = 'smtp ' . random_string(); $poll = 'email ' . random_string(); $priority = 0; $x = email_msg_meta($mbox,$msgs[0]); - if(stristr($x->from,$orig_url)) - $adr = imap_rfc822_parse_adrlist($x->from,''); - elseif(stristr($x->to,$orig_url)) - $adr = imap_rfc822_parse_adrlist($x->to,''); - if(isset($adr) && strlen($adr[0]->personal)) - $vcard['fn'] = notags($adr[0]->personal); + if(stristr($x[0]->from,$orig_url)) + $adr = imap_rfc822_parse_adrlist($x[0]->from,''); + elseif(stristr($x[0]->to,$orig_url)) + $adr = imap_rfc822_parse_adrlist($x[0]->to,''); + if(isset($adr)) { + foreach($adr as $feadr) { + if((strcasecmp($feadr->mailbox,$name) == 0) + &&(strcasecmp($feadr->host,$phost) == 0) + && (strlen($feadr->personal))) { + + $personal = imap_mime_header_decode($feadr->personal); + $vcard['fn'] = ""; + foreach($personal as $perspart) + if ($perspart->charset != "default") + $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text); + else + $vcard['fn'] .= $perspart->text; + + $vcard['fn'] = notags($vcard['fn']); + } + } + } } imap_close($mbox); } } } - } + } if($mode == PROBE_NORMAL) { if(strlen($zot)) { @@ -471,7 +509,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { } if(strlen($dfrn)) { - $ret = scrape_dfrn($dfrn); + $ret = scrape_dfrn(($hcard) ? $hcard : $dfrn); if(is_array($ret) && x($ret,'dfrn-request')) { $network = NETWORK_DFRN; $request = $ret['dfrn-request']; @@ -488,11 +526,13 @@ function probe_url($url, $mode = PROBE_NORMAL) { } if($diaspora && $diaspora_base && $diaspora_guid) { - if($mode == PROBE_DIASPORA || ! $notify) + if($mode == PROBE_DIASPORA || ! $notify) { $notify = $diaspora_base . 'receive/users/' . $diaspora_guid; + $batch = $diaspora_base . 'receive/public' ; + } if(strpos($url,'@')) $addr = str_replace('acct:', '', $url); - } + } if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) { if($diaspora) @@ -505,17 +545,24 @@ function probe_url($url, $mode = PROBE_NORMAL) { $vcard = scrape_vcard($hcard); // Google doesn't use absolute url in profile photos - + if((x($vcard,'photo')) && substr($vcard['photo'],0,1) == '/') { $h = @parse_url($hcard); if($h) $vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo']; } - + logger('probe_url: scrape_vcard: ' . print_r($vcard,true), LOGGER_DATA); } - if($twitter) { + if($diaspora && $addr) { + // Diaspora returns the name as the nick. As the nick will never be updated, + // let's use the Diaspora nickname (the first part of the handle) as the nick instead + $addr_parts = explode('@', $addr); + $vcard['nick'] = $addr_parts[0]; + } + + /* if($twitter) { logger('twitter: setup'); $tid = basename($url); $tapi = 'https://api.twitter.com/1/statuses/user_timeline.rss'; @@ -524,6 +571,18 @@ function probe_url($url, $mode = PROBE_NORMAL) { else $poll = $tapi . '?screen_name=' . $tid; $profile = 'http://twitter.com/#!/' . $tid; + //$vcard['photo'] = 'https://api.twitter.com/1/users/profile_image/' . $tid; + $vcard['photo'] = 'https://api.twitter.com/1/users/profile_image?screen_name=' . $tid . '&size=bigger'; + $vcard['nick'] = $tid; + $vcard['fn'] = $tid; + } */ + + if($lastfm) { + $profile = $url; + $poll = str_replace(array('www.','last.fm/'),array('','ws.audioscrobbler.com/1.0/'),$url) . '/recenttracks.rss'; + $vcard['nick'] = basename($url); + $vcard['fn'] = $vcard['nick'] . t(' on Last.fm'); + $network = NETWORK_FEED; } if(! x($vcard,'fn')) @@ -532,9 +591,15 @@ function probe_url($url, $mode = PROBE_NORMAL) { $check_feed = false; + if(stristr($url,'tumblr.com') && (! stristr($url,'/rss'))) { + $poll = $url . '/rss'; + $check_feed = true; + // Will leave it to others to figure out how to grab the avatar, which is on the $url page in the open graph meta links + } + if($twitter || ! $poll) $check_feed = true; - if((! isset($vcard)) || (! $profile)) + if((! isset($vcard)) || (! x($vcard,'fn')) || (! $profile)) $check_feed = true; if(($at_addr) && (! count($links))) $check_feed = false; @@ -542,27 +607,28 @@ function probe_url($url, $mode = PROBE_NORMAL) { if($check_feed) { $feedret = scrape_feed(($poll) ? $poll : $url); - logger('probe_url: scrape_feed returns: ' . print_r($feedret,true), LOGGER_DATA); + logger('probe_url: scrape_feed ' . (($poll)? $poll : $url) . ' returns: ' . print_r($feedret,true), LOGGER_DATA); if(count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) { $poll = ((x($feedret,'feed_atom')) ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss'])); - if(! x($vcard)) + if(! x($vcard)) $vcard = array(); } if(x($feedret,'photo') && (! x($vcard,'photo'))) $vcard['photo'] = $feedret['photo']; require_once('library/simplepie/simplepie.inc'); - $feed = new SimplePie(); + $feed = new SimplePie(); $xml = fetch_url($poll); logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA); $a = get_app(); - logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), $LOGGER_DATA); + logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), LOGGER_DATA); - $feed->set_raw_data($xml); + // Don't try and parse an empty string + $feed->set_raw_data(($xml) ? $xml : ''); - $feed->init(); + $feed->init(); if($feed->error()) logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error()); @@ -571,7 +637,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { $vcard['photo'] = $feed->get_image_url(); $author = $feed->get_author(); - if($author) { + if($author) { $vcard['fn'] = unxmlify(trim($author->get_name())); if(! $vcard['fn']) $vcard['fn'] = trim(unxmlify($author->get_email())); @@ -582,18 +648,18 @@ function probe_url($url, $mode = PROBE_NORMAL) { $profile = trim(unxmlify($author->get_link())); if(! $vcard['photo']) { $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); - if($rawtags) { + if($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo')) $vcard['photo'] = $elems['link'][0]['attribs']['']['href']; - } + } } } else { $item = $feed->get_item(0); if($item) { $author = $item->get_author(); - if($author) { + if($author) { $vcard['fn'] = trim(unxmlify($author->get_name())); if(! $vcard['fn']) $vcard['fn'] = trim(unxmlify($author->get_email())); @@ -610,22 +676,27 @@ function probe_url($url, $mode = PROBE_NORMAL) { } if(! $vcard['photo']) { $rawtags = $item->get_item_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); - if($rawtags) { + if($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo')) $vcard['photo'] = $elems['link'][0]['attribs']['']['href']; - } + } } } } if((! $vcard['photo']) && strlen($email)) - $vcard['photo'] = gravatar_img($email); + $vcard['photo'] = avatar_img($email); if($poll === $profile) $lnk = $feed->get_permalink(); if(isset($lnk) && strlen($lnk)) - $profile = $lnk; + $profile = $lnk; + if(! $network) { + $network = NETWORK_FEED; + // If it is a feed, don't take the author name as feed name + unset($vcard['fn']); + } if(! (x($vcard,'fn'))) $vcard['fn'] = notags($feed->get_title()); if(! (x($vcard,'fn'))) @@ -640,8 +711,6 @@ function probe_url($url, $mode = PROBE_NORMAL) { if(strpos($vcard['nick'],' ')) $vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' '))); } - if(! $network) - $network = NETWORK_FEED; if(! $priority) $priority = 2; } @@ -649,7 +718,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { if(! x($vcard,'photo')) { $a = get_app(); - $vcard['photo'] = $a->get_baseurl() . '/images/default-profile.jpg' ; + $vcard['photo'] = $a->get_baseurl() . '/images/person-175.jpg' ; } if(! $profile) @@ -662,15 +731,17 @@ function probe_url($url, $mode = PROBE_NORMAL) { $vcard['fn'] = notags($vcard['fn']); $vcard['nick'] = str_replace(' ','',notags($vcard['nick'])); - + $result['name'] = $vcard['fn']; $result['nick'] = $vcard['nick']; $result['url'] = $profile; $result['addr'] = $addr; + $result['batch'] = $batch; $result['notify'] = $notify; $result['poll'] = $poll; $result['request'] = $request; $result['confirm'] = $confirm; + $result['poco'] = $poco; $result['photo'] = $vcard['photo']; $result['priority'] = $priority; $result['network'] = $network; @@ -679,5 +750,14 @@ function probe_url($url, $mode = PROBE_NORMAL) { logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG); + // Trying if it maybe a diaspora account + if ($result['network'] == NETWORK_FEED) { + require_once('include/bbcode.php'); + $address = GetProfileUsername($url, "", true); + $result2 = probe_url($address, $mode); + if ($result2['network'] != "") + $result = $result2; + } + return $result; }