]> git.mxchange.org Git - friendica.git/blobdiff - include/socgraph.php
Merge pull request #3355 from Hypolite/issue/fix-language-guess
[friendica.git] / include / socgraph.php
index cd971a7c71405bb40af6fa0c068d46fbc7a50123..a39eca5e86fe9ec39628a60b04cccb255ccec7b4 100644 (file)
@@ -7,6 +7,8 @@
  * @todo Detect if it is a forum
  */
 
+use \Friendica\Core\Config;
+
 require_once('include/datetime.php');
 require_once("include/Scrape.php");
 require_once("include/network.php");
@@ -172,10 +174,13 @@ function poco_load_worker($cid, $uid, $zcid, $url) {
                                "contact-type" => $contact_type,
                                "generation" => $generation);
 
-               if (sanitized_gcontact($gcontact)) {
+               try {
+                       $gcontact = sanitize_gcontact($gcontact);
                        $gcid = update_gcontact($gcontact);
 
                        link_gcontact($gcid, $uid, $cid, $zcid);
+               } catch (Exception $e) {
+                       logger($e->getMessage(), LOGGER_DEBUG);
                }
        }
        logger("poco_load: loaded $total entries",LOGGER_DEBUG);
@@ -191,6 +196,7 @@ function poco_load_worker($cid, $uid, $zcid, $url) {
  * @brief Sanitize the given gcontact data
  *
  * @param array $gcontact array with gcontact data
+ * @throw Exception
  *
  * Generation:
  *  0: No definition
@@ -200,20 +206,20 @@ function poco_load_worker($cid, $uid, $zcid, $url) {
  *  4: ...
  *
  */
-function sanitized_gcontact(&$gcontact) {
+function sanitize_gcontact($gcontact) {
 
        if ($gcontact['url'] == "") {
-               return false;
+               throw new Exception('URL is empty');
        }
 
        $urlparts = parse_url($gcontact['url']);
        if (!isset($urlparts["scheme"])) {
-               return false;
+               throw new Exception("This (".$gcontact['url'].") doesn't seem to be an url.");
        }
 
        if (in_array($urlparts["host"], array("www.facebook.com", "facebook.com", "twitter.com",
                                                "identi.ca", "alpha.app.net"))) {
-               return false;
+               throw new Exception('Contact from a non federated network ignored. ('.$gcontact['url'].')');
        }
 
        // Don't store the statusnet connector as network
@@ -252,6 +258,9 @@ function sanitized_gcontact(&$gcontact) {
                }
        }
 
+       $gcontact['server_url'] = '';
+       $gcontact['network'] = '';
+
        $x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
                dbesc(normalise_link($gcontact['url']))
        );
@@ -263,19 +272,12 @@ function sanitized_gcontact(&$gcontact) {
                if ($gcontact['updated'] <= NULL_DATE) {
                        $gcontact['updated'] = $x[0]["updated"];
                }
-               if (!isset($gcontact['server_url'])) {
+               if (!isset($gcontact['server_url']) AND (normalise_link($x[0]["server_url"]) != normalise_link($x[0]["url"]))) {
                        $gcontact['server_url'] = $x[0]["server_url"];
                }
                if (!isset($gcontact['addr'])) {
                        $gcontact['addr'] = $x[0]["addr"];
                }
-       } else {
-               if (!isset($gcontact['server_url'])) {
-                       $gcontact['server_url'] = '';
-               }
-               if (!isset($gcontact['network'])) {
-                       $gcontact['network'] = '';
-               }
        }
 
        if ((!isset($gcontact['network']) OR !isset($gcontact['name']) OR !isset($gcontact['addr']) OR !isset($gcontact['photo']) OR !isset($gcontact['server_url']) OR $alternate)
@@ -283,23 +285,13 @@ function sanitized_gcontact(&$gcontact) {
                $data = Probe::uri($gcontact['url']);
 
                if ($data["network"] == NETWORK_PHANTOM) {
-                       return false;
+                       throw new Exception('Probing for URL '.$gcontact['url'].' failed');
                }
 
                $orig_profile = $gcontact['url'];
 
                $gcontact["server_url"] = $data["baseurl"];
 
-               unset($data["guid"]);
-               unset($data["batch"]);
-               unset($data["poll"]);
-               unset($data["request"]);
-               unset($data["confirm"]);
-               unset($data["poco"]);
-               unset($data["priority"]);
-               unset($data["pubkey"]);
-               unset($data["baseurl"]);
-
                $gcontact = array_merge($gcontact, $data);
 
                if ($alternate AND ($gcontact['network'] == NETWORK_OSTATUS)) {
@@ -313,11 +305,11 @@ function sanitized_gcontact(&$gcontact) {
        }
 
        if (!isset($gcontact['name']) OR !isset($gcontact['photo'])) {
-               return false;
+               throw new Exception('No name and photo for URL '.$gcontact['url']);
        }
 
        if (!in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
-               return false;
+               throw new Exception('No federated network ('.$gcontact['network'].') detected for URL '.$gcontact['url']);
        }
 
        if (!isset($gcontact['server_url'])) {
@@ -335,7 +327,7 @@ function sanitized_gcontact(&$gcontact) {
                $gcontact['server_url'] = "";
        }
 
-       return true;
+       return $gcontact;
 }
 
 /**
@@ -473,15 +465,26 @@ function poco_last_updated($profile, $force = false) {
        $gcontacts = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s'",
                        dbesc(normalise_link($profile)));
 
+       if (!dbm::is_result($gcontacts)) {
+               return false;
+       }
+
+       $contact = array("url" => $profile);
+
        if ($gcontacts[0]["created"] <= NULL_DATE) {
-               q("UPDATE `gcontact` SET `created` = '%s' WHERE `nurl` = '%s'",
-                       dbesc(datetime_convert()), dbesc(normalise_link($profile)));
+               $contact['created'] = datetime_convert();
+       }
+
+       if ($force) {
+               $server_url = normalise_link(poco_detect_server($profile));
        }
-       if ($gcontacts[0]["server_url"] != "") {
+
+       if (($server_url == '') AND ($gcontacts[0]["server_url"] != "")) {
                $server_url = $gcontacts[0]["server_url"];
        }
-       if (($server_url == '') OR ($gcontacts[0]["server_url"] == $gcontacts[0]["nurl"])) {
-               $server_url = poco_detect_server($profile);
+
+       if (!$force AND (($server_url == '') OR ($gcontacts[0]["server_url"] == $gcontacts[0]["nurl"]))) {
+               $server_url = normalise_link(poco_detect_server($profile));
        }
 
        if (!in_array($gcontacts[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_FEED, NETWORK_OSTATUS, ""))) {
@@ -491,67 +494,64 @@ function poco_last_updated($profile, $force = false) {
 
        if ($server_url != "") {
                if (!poco_check_server($server_url, $gcontacts[0]["network"], $force)) {
-
-                       if ($force)
+                       if ($force) {
                                q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
                                        dbesc(datetime_convert()), dbesc(normalise_link($profile)));
+                       }
 
                        logger("Profile ".$profile.": Server ".$server_url." wasn't reachable.", LOGGER_DEBUG);
                        return false;
                }
-
-               q("UPDATE `gcontact` SET `server_url` = '%s' WHERE `nurl` = '%s'",
-                       dbesc($server_url), dbesc(normalise_link($profile)));
+               $contact['server_url'] = $server_url;
        }
 
        if (in_array($gcontacts[0]["network"], array("", NETWORK_FEED))) {
                $server = q("SELECT `network` FROM `gserver` WHERE `nurl` = '%s' AND `network` != ''",
                        dbesc(normalise_link($server_url)));
 
-               if ($server)
-                       q("UPDATE `gcontact` SET `network` = '%s' WHERE `nurl` = '%s'",
-                               dbesc($server[0]["network"]), dbesc(normalise_link($profile)));
-               else
+               if ($server) {
+                       $contact['network'] = $server[0]["network"];
+               } else {
                        return false;
+               }
        }
 
        // noscrape is really fast so we don't cache the call.
-       if (($gcontacts[0]["server_url"] != "") AND ($gcontacts[0]["nick"] != "")) {
+       if (($server_url != "") AND ($gcontacts[0]["nick"] != "")) {
 
                //  Use noscrape if possible
-               $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", dbesc(normalise_link($gcontacts[0]["server_url"])));
+               $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", dbesc(normalise_link($server_url)));
 
                if ($server) {
                        $noscraperet = z_fetch_url($server[0]["noscrape"]."/".$gcontacts[0]["nick"]);
 
-                        if ($noscraperet["success"] AND ($noscraperet["body"] != "")) {
+                       if ($noscraperet["success"] AND ($noscraperet["body"] != "")) {
 
                                $noscrape = json_decode($noscraperet["body"], true);
 
                                if (is_array($noscrape)) {
-                                       $contact = array("url" => $profile,
-                                                       "network" => $server[0]["network"],
-                                                       "generation" => $gcontacts[0]["generation"]);
+                                       $contact["network"] = $server[0]["network"];
 
-                                       if (isset($noscrape["fn"]))
+                                       if (isset($noscrape["fn"])) {
                                                $contact["name"] = $noscrape["fn"];
-
-                                       if (isset($noscrape["comm"]))
+                                       }
+                                       if (isset($noscrape["comm"])) {
                                                $contact["community"] = $noscrape["comm"];
-
+                                       }
                                        if (isset($noscrape["tags"])) {
                                                $keywords = implode(" ", $noscrape["tags"]);
-                                               if ($keywords != "")
+                                               if ($keywords != "") {
                                                        $contact["keywords"] = $keywords;
+                                               }
                                        }
 
                                        $location = formatted_location($noscrape);
-                                       if ($location)
+                                       if ($location) {
                                                $contact["location"] = $location;
-
-                                       if (isset($noscrape["dfrn-notify"]))
+                                       }
+                                       if (isset($noscrape["dfrn-notify"])) {
                                                $contact["notify"] = $noscrape["dfrn-notify"];
-
+                                       }
                                        // Remove all fields that are not present in the gcontact table
                                        unset($noscrape["fn"]);
                                        unset($noscrape["key"]);
@@ -589,8 +589,10 @@ function poco_last_updated($profile, $force = false) {
        }
 
        // If we only can poll the feed, then we only do this once a while
-       if (!$force AND !poco_do_update($gcontacts[0]["created"], $gcontacts[0]["updated"], $gcontacts[0]["last_failure"],  $gcontacts[0]["last_contact"])) {
+       if (!$force AND !poco_do_update($gcontacts[0]["created"], $gcontacts[0]["updated"], $gcontacts[0]["last_failure"], $gcontacts[0]["last_contact"])) {
                logger("Profile ".$profile." was last updated at ".$gcontacts[0]["updated"]." (cached)", LOGGER_DEBUG);
+
+               update_gcontact($contact);
                return $gcontacts[0]["updated"];
        }
 
@@ -608,20 +610,15 @@ function poco_last_updated($profile, $force = false) {
 
                $gcontact = array_merge($gcontacts[0], $data);
 
-               unset($gcontact["guid"]);
-               unset($gcontact["batch"]);
-               unset($gcontact["poll"]);
-               unset($gcontact["request"]);
-               unset($gcontact["confirm"]);
-               unset($gcontact["poco"]);
-               unset($gcontact["priority"]);
-               unset($gcontact["pubkey"]);
-               unset($gcontact["baseurl"]);
-
-               if (sanitized_gcontact($gcontact)) {
+               $gcontact["server_url"] = $data["baseurl"];
+
+               try {
+                       $gcontact = sanitize_gcontact($gcontact);
                        update_gcontact($gcontact);
 
                        poco_last_updated($data["url"], $force);
+               } catch (Exception $e) {
+                       logger($e->getMessage(), LOGGER_DEBUG);
                }
 
                logger("Profile ".$profile." was deleted", LOGGER_DEBUG);
@@ -636,22 +633,10 @@ function poco_last_updated($profile, $force = false) {
                return false;
        }
 
-       $contact = array("generation" => $gcontacts[0]["generation"]);
-
        $contact = array_merge($contact, $data);
 
        $contact["server_url"] = $data["baseurl"];
 
-       unset($contact["guid"]);
-       unset($contact["batch"]);
-       unset($contact["poll"]);
-       unset($contact["request"]);
-       unset($contact["confirm"]);
-       unset($contact["poco"]);
-       unset($contact["priority"]);
-       unset($contact["pubkey"]);
-       unset($contact["baseurl"]);
-
        update_gcontact($contact);
 
        $feedret = z_fetch_url($data["poll"]);
@@ -694,9 +679,10 @@ function poco_last_updated($profile, $force = false) {
        q("UPDATE `gcontact` SET `updated` = '%s', `last_contact` = '%s' WHERE `nurl` = '%s'",
                dbesc(dbm::date($last_updated)), dbesc(dbm::date()), dbesc(normalise_link($profile)));
 
-       if (($gcontacts[0]["generation"] == 0))
+       if (($gcontacts[0]["generation"] == 0)) {
                q("UPDATE `gcontact` SET `generation` = 9 WHERE `nurl` = '%s'",
                        dbesc(normalise_link($profile)));
+       }
 
        logger("Profile ".$profile." was last updated at ".$last_updated, LOGGER_DEBUG);
 
@@ -1672,6 +1658,20 @@ function poco_discover_federation() {
                }
        }
 
+       // Disvover Mastodon servers
+       if (!Config::get('system','ostatus_disabled')) {
+               $serverdata = fetch_url("https://instances.mastodon.xyz/instances.json");
+
+               if ($serverdata) {
+                       $servers = json_decode($serverdata);
+
+                       foreach ($servers AS $server) {
+                               $url = (is_null($server->https_score) ? 'http' : 'https').'://'.$server->name;
+                               proc_run(PRIORITY_LOW, "include/discover_poco.php", "server", base64_encode($url));
+                       }
+               }
+       }
+
        // Currently disabled, since the service isn't available anymore.
        // It is not removed since I hope that there will be a successor.
        // Discover GNU Social Servers.
@@ -1911,8 +1911,11 @@ function poco_discover_server($data, $default_generation = 0) {
                                        "contact-type" => $contact_type,
                                        "generation" => $generation);
 
-                       if (sanitized_gcontact($gcontact)) {
+                       try {
+                               $gcontact = sanitize_gcontact($gcontact);
                                update_gcontact($gcontact);
+                       } catch (Exception $e) {
+                               logger($e->getMessage(), LOGGER_DEBUG);
                        }
 
                        logger("Done for profile ".$profile_url, LOGGER_DEBUG);
@@ -2109,7 +2112,7 @@ function update_gcontact($contact) {
        fix_alternate_contact_address($contact);
 
        if (!isset($contact["updated"]))
-               $contact["updated"] = datetime_convert();
+               $contact["updated"] = dbm::date();
 
        if ($contact["server_url"] == "") {
                $server_url = $contact["url"];
@@ -2164,7 +2167,7 @@ function update_gcontact($contact) {
                        dbesc($contact["gender"]), dbesc($contact["keywords"]), intval($contact["hide"]),
                        intval($contact["nsfw"]), intval($contact["contact-type"]), dbesc($contact["alias"]),
                        dbesc($contact["notify"]), dbesc($contact["url"]), dbesc($contact["location"]),
-                       dbesc($contact["about"]), intval($contact["generation"]), dbesc($contact["updated"]),
+                       dbesc($contact["about"]), intval($contact["generation"]), dbesc(dbm::date($contact["updated"])),
                        dbesc($contact["server_url"]), dbesc($contact["connect"]),
                        dbesc(normalise_link($contact["url"])), intval($contact["generation"]));
 
@@ -2208,6 +2211,8 @@ function update_gcontact_from_probe($url) {
                return;
        }
 
+       $data["server_url"] = $data["baseurl"];
+
        update_gcontact($data);
 }