X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fsocgraph.php;h=4b4b3587879cc6e2bd11fc4ba09710d5d98fa75b;hb=1811ccc43de3ecd10df7c97e7d34574c3f4fff2b;hp=002623c16ef6ce2c27d19cf92da0fa43a866eca6;hpb=c67fbc89c426255ffebe940e47435cc149254db8;p=friendica.git diff --git a/include/socgraph.php b/include/socgraph.php index 002623c16e..4b4b358787 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -1,15 +1,16 @@ 0)) $generation = $x[0]['generation']; if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo || $x[0]['updated'] < $updated) { - q("UPDATE `gcontact` SET `name` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s', `server_url` = '%s', - `updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s', `generation` = %d + q("UPDATE `gcontact` SET `name` = '%s', `addr` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s', `server_url` = '%s', + `updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s', `generation` = %d, + `alias` = '$s', `notify` = '%s' WHERE (`generation` >= %d OR `generation` = 0) AND `nurl` = '%s'", dbesc($name), + dbesc($addr), dbesc($network), dbesc($profile_photo), dbesc($connect_url), @@ -312,33 +333,44 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca dbesc($about), dbesc($keywords), dbesc($gender), + dbesc($alias), + dbesc($notify), intval($generation), intval($generation), dbesc(normalise_link($profile_url)) ); } } else { - q("INSERT INTO `gcontact` (`name`, `nick`, `network`, `url`, `nurl`, `photo`, `connect`, `server_url`, `created`, `updated`, `location`, `about`, `keywords`, `gender`, `generation`) - VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", - dbesc($name), - dbesc($nick), - dbesc($network), - dbesc($profile_url), - dbesc(normalise_link($profile_url)), - dbesc($profile_photo), - dbesc($connect_url), - dbesc($server_url), - dbesc(datetime_convert()), - dbesc($updated), - dbesc($location), - dbesc($about), - dbesc($keywords), - dbesc($gender), - intval($generation) - ); - $x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", + // Maybe another process had inserted the entry after the first check, so it again + $x = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", dbesc(normalise_link($profile_url)) ); + if(!$x) { + q("INSERT INTO `gcontact` (`name`, `nick`, `addr`, `network`, `url`, `nurl`, `photo`, `connect`, `server_url`, `created`, `updated`, `location`, `about`, `keywords`, `gender`, `alias`, `notify`, `generation`) + VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", + dbesc($name), + dbesc($nick), + dbesc($addr), + dbesc($network), + dbesc($profile_url), + dbesc(normalise_link($profile_url)), + dbesc($profile_photo), + dbesc($connect_url), + dbesc($server_url), + dbesc(datetime_convert()), + dbesc($updated), + dbesc($location), + dbesc($about), + dbesc($keywords), + dbesc($gender), + dbesc($alias), + dbesc($notify), + intval($generation) + ); + $x = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", + dbesc(normalise_link($profile_url)) + ); + } if(count($x)) $gcid = $x[0]['id']; } @@ -371,11 +403,11 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca } // For unknown reasons there are sometimes duplicates - q("DELETE FROM `gcontact` WHERE `nurl` = '%s' AND `id` != %d AND - NOT EXISTS (SELECT `gcid` FROM `glink` WHERE `gcid` = `gcontact`.`id`)", - dbesc(normalise_link($profile_url)), - intval($gcid) - ); + //q("DELETE FROM `gcontact` WHERE `nurl` = '%s' AND `id` != %d AND + // NOT EXISTS (SELECT `gcid` FROM `glink` WHERE `gcid` = `gcontact`.`id`)", + // dbesc(normalise_link($profile_url)), + // intval($gcid) + //); return $gcid; } @@ -570,7 +602,7 @@ function poco_last_updated($profile, $force = false) { return false; } - if (($data["poll"] == "") OR ($data["network"] == NETWORK_FEED)) { + if (($data["poll"] == "") OR (in_array($data["network"], array(NETWORK_FEED, NETWORK_PHANTOM)))) { q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc(normalise_link($profile))); return false; @@ -689,6 +721,10 @@ function poco_to_boolean($val) { function poco_check_server($server_url, $network = "", $force = false) { + // Unify the server address + $server_url = trim($server_url, "/"); + $server_url = str_replace("/index.php", "", $server_url); + if ($server_url == "") return false; @@ -748,8 +784,11 @@ function poco_check_server($server_url, $network = "", $force = false) { } if (!$serverret["success"] OR ($serverret["body"] == "") OR (sizeof($xmlobj) == 0) OR !is_object($xmlobj)) { - $last_failure = datetime_convert(); - $failure = true; + // Workaround for bad configured servers (known nginx problem) + if ($serverret["debug"]["http_code"] != "403") { + $last_failure = datetime_convert(); + $failure = true; + } } elseif ($network == NETWORK_DIASPORA) $last_contact = datetime_convert(); @@ -766,6 +805,8 @@ function poco_check_server($server_url, $network = "", $force = false) { $version = trim(str_replace("X-Diaspora-Version:", "", $line)); $version = trim(str_replace("x-diaspora-version:", "", $version)); $network = NETWORK_DIASPORA; + $versionparts = explode("-", $version); + $version = $versionparts[0]; } } } @@ -1036,15 +1077,16 @@ function count_common_friends($uid,$cid) { $r = q("SELECT count(*) as `total` FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` - where `glink`.`cid` = %d and `glink`.`uid` = %d - and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ", + WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND + ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)) + AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ", intval($cid), intval($uid), intval($uid), intval($cid) ); -// logger("count_common_friends: $uid $cid {$r[0]['total']}"); +// logger("count_common_friends: $uid $cid {$r[0]['total']}"); if(count($r)) return $r[0]['total']; return 0; @@ -1059,11 +1101,15 @@ function common_friends($uid,$cid,$start = 0,$limit=9999,$shuffle = false) { else $sql_extra = " order by `gcontact`.`name` asc "; - $r = q("SELECT `gcontact`.* - FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` - where `glink`.`cid` = %d and `glink`.`uid` = %d - and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) - $sql_extra limit %d, %d", + $r = q("SELECT `gcontact`.*, `contact`.`id` AS `cid` + FROM `glink` + INNER JOIN `gcontact` ON `glink`.`gcid` = `gcontact`.`id` + INNER JOIN `contact` ON `gcontact`.`nurl` = `contact`.`nurl` + WHERE `glink`.`cid` = %d and `glink`.`uid` = %d + AND `contact`.`uid` = %d AND `contact`.`self` = 0 AND `contact`.`blocked` = 0 + AND `contact`.`hidden` = 0 AND `contact`.`id` != %d + AND ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)) + $sql_extra LIMIT %d, %d", intval($cid), intval($uid), intval($uid), @@ -1120,7 +1166,8 @@ function count_all_friends($uid,$cid) { $r = q("SELECT count(*) as `total` FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` - where `glink`.`cid` = %d and `glink`.`uid` = %d ", + where `glink`.`cid` = %d and `glink`.`uid` = %d AND + ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))", intval($cid), intval($uid) ); @@ -1134,10 +1181,14 @@ function count_all_friends($uid,$cid) { function all_friends($uid,$cid,$start = 0, $limit = 80) { - $r = q("SELECT `gcontact`.* - FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` - where `glink`.`cid` = %d and `glink`.`uid` = %d - order by `gcontact`.`name` asc LIMIT %d, %d ", + $r = q("SELECT `gcontact`.*, `contact`.`id` AS `cid` + FROM `glink` + INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` + LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` AND `contact`.`uid` = %d + WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND + ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)) + ORDER BY `gcontact`.`name` ASC LIMIT %d, %d ", + intval($uid), intval($cid), intval($uid), intval($start), @@ -1167,14 +1218,14 @@ function suggestion_query($uid, $start = 0, $limit = 80) { $sql_network = "'".$sql_network."'"; $r = q("SELECT count(glink.gcid) as `total`, gcontact.* from gcontact - INNER JOIN glink on glink.gcid = gcontact.id + INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id` where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d ) - and not gcontact.name in ( select name from contact where uid = %d ) - and not gcontact.id in ( select gcid from gcign where uid = %d ) + AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d) + AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d) AND `gcontact`.`updated` != '0000-00-00 00:00:00' AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`network` IN (%s) - group by glink.gcid order by gcontact.updated desc,total desc limit %d, %d ", + GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d", intval($uid), intval($uid), intval($uid), @@ -1187,14 +1238,15 @@ function suggestion_query($uid, $start = 0, $limit = 80) { if(count($r) && count($r) >= ($limit -1)) return $r; - $r2 = q("SELECT gcontact.* from gcontact - INNER JOIN glink on glink.gcid = gcontact.id - where glink.uid = 0 and glink.cid = 0 and glink.zcid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d ) - and not gcontact.name in ( select name from contact where uid = %d ) - and not gcontact.id in ( select gcid from gcign where uid = %d ) + $r2 = q("SELECT gcontact.* FROM gcontact + INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id` + WHERE `glink`.`uid` = 0 AND `glink`.`cid` = 0 AND `glink`.`zcid` = 0 AND NOT `gcontact`.`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = %d) + AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d) + AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d) AND `gcontact`.`updated` != '0000-00-00 00:00:00' + AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`network` IN (%s) - order by rand() limit %d, %d ", + ORDER BY rand() LIMIT %d, %d", intval($uid), intval($uid), intval($uid), @@ -1210,6 +1262,9 @@ function suggestion_query($uid, $start = 0, $limit = 80) { foreach ($r AS $suggestion) $list[$suggestion["nurl"]] = $suggestion; + while (sizeof($list) > ($limit)) + array_pop($list); + return $list; } @@ -1219,12 +1274,12 @@ function update_suggestions() { $done = array(); - // To-Do: Check if it is really neccessary to poll the own server + /// TODO Check if it is really neccessary to poll the own server poco_load(0,0,0,$a->get_baseurl() . '/poco'); $done[] = $a->get_baseurl() . '/poco'; - if(strlen(get_config('system','directory_submit_url'))) { + if(strlen(get_config('system','directory'))) { $x = fetch_url(get_server()."/pubsites"); if($x) { $j = json_decode($x); @@ -1255,8 +1310,46 @@ function update_suggestions() { } } +function poco_discover_federation() { + $last = get_config('poco','last_federation_discovery'); + + if($last) { + $next = $last + (24 * 60 * 60); + if($next > time()) + return; + } + + // Discover Friendica, Hubzilla and Diaspora servers + $serverdata = fetch_url("http://the-federation.info/pods.json"); + + if ($serverdata) { + $servers = json_decode($serverdata); + + foreach($servers->pods AS $server) + poco_check_server("https://".$server->host); + } + + // Discover GNU Social Servers + if (!get_config('system','ostatus_disabled')) { + $serverdata = "http://gstools.org/api/get_open_instances/"; + + $result = z_fetch_url($serverdata); + if ($result["success"]) { + $servers = json_decode($result["body"]); + + foreach($servers->data AS $server) + poco_check_server($server->instance_address); + } + } + + set_config('poco','last_federation_discovery', time()); +} + function poco_discover($complete = false) { + // Update the server list + poco_discover_federation(); + $no_of_queries = 5; $requery_days = intval(get_config("system", "poco_requery_days")); @@ -1270,8 +1363,11 @@ function poco_discover($complete = false) { if ($r) foreach ($r AS $server) { - if (!poco_check_server($server["url"], $server["network"])) + if (!poco_check_server($server["url"], $server["network"])) { + // The server is not reachable? Okay, then we will try it later + q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); continue; + } // Fetch all users from the other server $url = $server["poco"]."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation"; @@ -1312,8 +1408,13 @@ function poco_discover($complete = false) { q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); if (!$complete AND (--$no_of_queries == 0)) break; - } else // If the server hadn't replied correctly, then force a sanity check + } else { + // If the server hadn't replied correctly, then force a sanity check poco_check_server($server["url"], $server["network"], true); + + // If we couldn't reach the server, we will try it some time later + q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); + } } } @@ -1421,4 +1522,231 @@ function poco_discover_server($data, $default_generation = 0) { } return $success; } + +/** + * @brief Fetch the gcontact id, add an entry if not existed + * + * @param arr $contact contact array + * @return bool|int Returns false if not found, integer if contact was found + */ +function get_gcontact_id($contact) { + + $gcontact_id = 0; + + if ($contact["network"] == NETWORK_STATUSNET) + $contact["network"] = NETWORK_OSTATUS; + + $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", + dbesc(normalise_link($contact["url"]))); + + if ($r) + $gcontact_id = $r[0]["id"]; + else { + q("INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `generation`) + VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", + dbesc($contact["name"]), + dbesc($contact["nick"]), + dbesc($contact["addr"]), + dbesc($contact["network"]), + dbesc($contact["url"]), + dbesc(normalise_link($contact["url"])), + dbesc($contact["photo"]), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($contact["location"]), + dbesc($contact["about"]), + intval($contact["generation"]) + ); + + $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", + dbesc(normalise_link($contact["url"]))); + + if ($r) + $gcontact_id = $r[0]["id"]; + } + + return $gcontact_id; +} + +/** + * @brief Updates the gcontact table from a given array + * + * @param arr $contact contact array + * @return bool|int Returns false if not found, integer if contact was found + */ +function update_gcontact($contact) { + + /// @todo update contact table as well + + $gcontact_id = get_gcontact_id($contact); + + if (!$gcontact_id) + return false; + + $r = q("SELECT `name`, `nick`, `photo`, `location`, `about`, `addr`, `generation`, `birthday`, `gender`, `keywords`, `hide`, `nsfw`, `network`, `alias`, `notify`, `url` + FROM `gcontact` WHERE `id` = %d LIMIT 1", + intval($gcontact_id)); + + if ($contact["generation"] == 0) + $contact["generation"] = $r[0]["generation"]; + + if ($contact["photo"] == "") + $contact["photo"] = $r[0]["photo"]; + + if ($contact["name"] == "") + $contact["name"] = $r[0]["name"]; + + if ($contact["nick"] == "") + $contact["nick"] = $r[0]["nick"]; + + if ($contact["addr"] == "") + $contact["addr"] = $r[0]["addr"]; + + if ($contact["location"] =="") + $contact["location"] = $r[0]["location"]; + + if ($contact["about"] =="") + $contact["about"] = $r[0]["about"]; + + if ($contact["birthday"] =="") + $contact["birthday"] = $r[0]["birthday"]; + + if ($contact["gender"] =="") + $contact["gender"] = $r[0]["gender"]; + + if ($contact["keywords"] =="") + $contact["keywords"] = $r[0]["keywords"]; + + if (!isset($contact["hide"])) + $contact["hide"] = $r[0]["hide"]; + + if (!isset($contact["nsfw"])) + $contact["nsfw"] = $r[0]["nsfw"]; + + if ($contact["network"] =="") + $contact["network"] = $r[0]["network"]; + + if ($contact["alias"] =="") + $contact["alias"] = $r[0]["alias"]; + + if ($contact["url"] =="") + $contact["url"] = $r[0]["url"]; + + if ($contact["notify"] =="") + $contact["notify"] = $r[0]["notify"]; + + if ($contact["network"] == NETWORK_STATUSNET) + $contact["network"] = NETWORK_OSTATUS; + + if (($contact["photo"] != $r[0]["photo"]) OR ($contact["name"] != $r[0]["name"]) OR ($contact["nick"] != $r[0]["nick"]) OR ($contact["addr"] != $r[0]["addr"]) OR + ($contact["birthday"] != $r[0]["birthday"]) OR ($contact["gender"] != $r[0]["gender"]) OR ($contact["keywords"] != $r[0]["keywords"]) OR + ($contact["hide"] != $r[0]["hide"]) OR ($contact["nsfw"] != $r[0]["nsfw"]) OR ($contact["network"] != $r[0]["network"]) OR + ($contact["alias"] != $r[0]["alias"]) OR ($contact["notify"] != $r[0]["notify"]) OR ($contact["url"] != $r[0]["url"]) OR + ($contact["location"] != $r[0]["location"]) OR ($contact["about"] != $r[0]["about"]) OR ($contact["generation"] < $r[0]["generation"])) { + + q("UPDATE `gcontact` SET `photo` = '%s', `name` = '%s', `nick` = '%s', `addr` = '%s', `network` = '%s', + `birthday` = '%s', `gender` = '%s', `keywords` = %d, `hide` = %d, `nsfw` = %d, + `alias` = '%s', `notify` = '%s', `url` = '%s', + `location` = '%s', `about` = '%s', `generation` = %d, `updated` = '%s' + WHERE `nurl` = '%s' AND (`generation` = 0 OR `generation` >= %d)", + dbesc($contact["photo"]), dbesc($contact["name"]), dbesc($contact["nick"]), + dbesc($contact["addr"]), dbesc($contact["network"]), dbesc($contact["birthday"]), + dbesc($contact["gender"]), dbesc($contact["keywords"]), intval($contact["hide"]), + intval($contact["nsfw"]), dbesc($contact["alias"]), dbesc($contact["notify"]), + dbesc($contact["url"]), dbesc($contact["location"]), dbesc($contact["about"]), + intval($contact["generation"]), dbesc(datetime_convert()), + dbesc(normalise_link($contact["url"])), intval($contact["generation"])); + } + + return $gcontact_id; +} + +/** + * @brief Updates the gcontact entry from probe + * + * @param str $url profile link + */ +function update_gcontact_from_probe($url) { + $data = probe_url($url); + + if ($data["network"] != NETWORK_PHANTOM) + update_gcontact($data); +} + +/** + * @brief Fetches users of given GNU Social server + * + * If the "Statistics" plugin is enabled (See http://gstools.org/ for details) we query user data with this. + * + * @param str $server Server address + */ +function gs_fetch_users($server) { + + logger("Fetching users from GNU Social server ".$server, LOGGER_DEBUG); + + $a = get_app(); + + $url = $server."/main/statistics"; + + $result = z_fetch_url($url); + if (!$result["success"]) + return false; + + $statistics = json_decode($result["body"]); + + if (is_object($statistics->config)) { + if ($statistics->config->instance_with_ssl) + $server = "https://"; + else + $server = "http://"; + + $server .= $statistics->config->instance_address; + + $hostname = $statistics->config->instance_address; + } else { + if ($statistics->instance_with_ssl) + $server = "https://"; + else + $server = "http://"; + + $server .= $statistics->instance_address; + + $hostname = $statistics->instance_address; + } + + foreach ($statistics->users AS $nick => $user) { + $profile_url = $server."/".$user->nickname; + + $contact = array("url" => $profile_url, + "name" => $user->fullname, + "addr" => $user->nickname."@".$hostname, + "nick" => $user->nickname, + "about" => $user->bio, + "network" => NETWORK_OSTATUS, + "photo" => $a->get_baseurl()."/images/person-175.jpg"); + get_gcontact_id($contact); + } +} + +/** + * @brief Asking GNU Social server on a regular base for their user data + * + */ +function gs_discover() { + + $requery_days = intval(get_config("system", "poco_requery_days")); + + $last_update = date("c", time() - (60 * 60 * 24 * $requery_days)); + + $r = q("SELECT `nurl`, `url` FROM `gserver` WHERE `last_contact` >= `last_failure` AND `network` = '%s' AND `last_poco_query` < '%s' ORDER BY RAND() LIMIT 5", + dbesc(NETWORK_OSTATUS), dbesc($last_update)); + + if (!$r) + return; + + foreach ($r AS $server) { + gs_fetch_users($server["url"]); + q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); + } +} ?>