define ( 'FRIENDICA_CODENAME', 'Lily of the valley');
define ( 'FRIENDICA_VERSION', '3.4.1' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
-define ( 'DB_UPDATE_VERSION', 1185 );
+define ( 'DB_UPDATE_VERSION', 1186 );
define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
-- ------------------------------------------
--- Friendica 3.4.0 (Lily of the valley)
--- DB_UPDATE_VERSION 1185
+-- Friendica 3.4.1 (Lily of the valley)
+-- DB_UPDATE_VERSION 1186
-- ------------------------------------------
`hub-verify` varchar(255) NOT NULL DEFAULT '',
`last-update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`success_update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `failure_update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`name-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`uri-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`avatar-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`photo` varchar(255) NOT NULL DEFAULT '',
`connect` varchar(255) NOT NULL DEFAULT '',
`updated` datetime DEFAULT '0000-00-00 00:00:00',
+ `last_contact` datetime DEFAULT '0000-00-00 00:00:00',
+ `last_failure` datetime DEFAULT '0000-00-00 00:00:00',
`location` varchar(255) NOT NULL DEFAULT '',
`about` text NOT NULL,
`keywords` text NOT NULL,
`gender` varchar(32) NOT NULL DEFAULT '',
`network` varchar(255) NOT NULL DEFAULT '',
`generation` tinyint(3) NOT NULL DEFAULT 0,
+ `server_url` varchar(255) NOT NULL DEFAULT '',
INDEX `nurl` (`nurl`)
) DEFAULT CHARSET=utf8;
INDEX `uid_gid_contactid` (`uid`,`gid`,`contact-id`)
) DEFAULT CHARSET=utf8;
+--
+-- TABLE gserver
+--
+CREATE TABLE IF NOT EXISTS `gserver` (
+ `url` varchar(255) NOT NULL DEFAULT '',
+ `nurl` varchar(255) NOT NULL DEFAULT '',
+ `version` varchar(255) NOT NULL DEFAULT '',
+ `site_name` varchar(255) NOT NULL DEFAULT '',
+ `info` text NOT NULL,
+ `register_policy` tinyint(1) NOT NULL DEFAULT 0,
+ `poco` varchar(255) NOT NULL DEFAULT '',
+ `noscrape` varchar(255) NOT NULL DEFAULT '',
+ `network` varchar(32) NOT NULL DEFAULT '',
+ `platform` varchar(255) NOT NULL DEFAULT '',
+ `last_poco_query` datetime DEFAULT '0000-00-00 00:00:00',
+ `last_contact` datetime DEFAULT '0000-00-00 00:00:00',
+ `last_failure` datetime DEFAULT '0000-00-00 00:00:00'
+) DEFAULT CHARSET=utf8;
+
--
-- TABLE guid
--
"hub-verify" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"last-update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"success_update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+ "failure_update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"name-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"uri-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"avatar-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"connect" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"updated" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
+ "last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
+ "last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"about" => array("type" => "text", "not null" => "1"),
"keywords" => array("type" => "text", "not null" => "1"),
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
+ "server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
),
"indexes" => array(
"PRIMARY" => array("id"),
"uid_gid_contactid" => array("uid","gid","contact-id"),
)
);
+ $database["gserver"] = array(
+ "fields" => array(
+ "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "version" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "site_name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "info" => array("type" => "text", "not null" => "1"),
+ "register_policy" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+ "poco" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "noscrape" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
+ "platform" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+ "last_poco_query" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
+ "last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
+ "last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
+ ),
+ "indexes" => array(
+ "PRIMARY" => array("nurl"),
+ )
+ );
$database["guid"] = array(
"fields" => array(
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
--- /dev/null
+<?php
+
+require_once("boot.php");
+require_once("include/socgraph.php");
+
+
+function discover_poco_run(&$argv, &$argc){
+ global $a, $db;
+
+ if(is_null($a)) {
+ $a = new App;
+ }
+
+ if(is_null($db)) {
+ @include(".htconfig.php");
+ require_once("include/dba.php");
+ $db = new dba($db_host, $db_user, $db_pass, $db_data);
+ unset($db_host, $db_user, $db_pass, $db_data);
+ };
+
+ require_once('include/session.php');
+ require_once('include/datetime.php');
+ require_once('include/pidfile.php');
+
+ load_config('config');
+ load_config('system');
+
+ $maxsysload = intval(get_config('system','maxloadavg'));
+ if($maxsysload < 1)
+ $maxsysload = 50;
+ if(function_exists('sys_getloadavg')) {
+ $load = sys_getloadavg();
+ if(intval($load[0]) > $maxsysload) {
+ logger('system: load ' . $load[0] . ' too high. discover_poco deferred to next scheduled run.');
+ return;
+ }
+ }
+
+ $lockpath = get_lockpath();
+ if ($lockpath != '') {
+ $pidfile = new pidfile($lockpath, 'discover_poco');
+ if($pidfile->is_already_running()) {
+ logger("discover_poco: Already running");
+ if ($pidfile->running_time() > 19*60) {
+ $pidfile->kill();
+ logger("discover_poco: killed stale process");
+ // Calling a new instance
+ proc_run('php','include/discover_poco.php');
+ }
+ exit;
+ }
+ }
+
+ $a->set_baseurl(get_config('system','url'));
+
+ load_hooks();
+
+ logger('start');
+
+ if (get_config('system','poco_discovery'))
+ poco_discover();
+
+ logger('end');
+
+ return;
+}
+
+if (array_search(__file__,get_included_files())===0){
+ discover_poco_run($_SERVER["argv"],$_SERVER["argc"]);
+ killme();
+}
$contacts = q("SELECT `contact`.* FROM `contact`
WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
- AND NOT `network` IN ( '%s', '%s', '%s' )
+ AND NOT `network` IN ( '%s', '%s' )
AND `contact`.`id` = %d
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `contact`.`archive` = 0 LIMIT 1",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
- dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_FACEBOOK),
dbesc(NETWORK_PUMPIO),
intval($contact_id)
);
- if(! count($contacts)) {
- // Maybe it is a Redmatrix account. Then we can fetch their contacts via poco
- $contacts = q("SELECT `id`, `poco` FROM `contact` WHERE `id` = %d AND `poco` != ''", intval($contact_id));
- if ($contacts)
- poco_load($contacts[0]['id'],$importer_uid,0,$contacts[0]['poco']);
+ if(! count($contacts))
return;
- }
$contact = $contacts[0];
+ // load current friends if possible.
+ if (($contact['poco'] != "") AND ($contact['success_update'] > $contact['failure_update'])) {
+ $r = q("SELECT count(*) as total from glink
+ where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
+ intval($contact['id'])
+ );
+ if (count($r))
+ if (!$r[0]['total'])
+ poco_load($contact['id'],$importer_uid,0,$contact['poco']);
+ }
+
+ // To-Do:
+ // - Check why we don't poll the Diaspora feed at the moment (some guid problem in the items?)
+ // - Check whether this is possible with Redmatrix
+ if ($contact["network"] == NETWORK_DIASPORA) {
+ if (poco_do_update($contact["last-item"], $contact["success_update"], $contact["failure_update"])) {
+ $last_updated = poco_last_updated($contact["url"]);
+ $updated = datetime_convert();
+ if ($last_updated) {
+ q("UPDATE `contact` SET `last-item` = '%s', `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d",
+ dbesc($last_updated),
+ dbesc($updated),
+ dbesc($updated),
+ intval($contact['id'])
+ );
+
+ q("UPDATE `gcontact` SET `updated` = '%s', `last_contact` = '%s' WHERE `nurl` = '%s'",
+ dbesc($last_updated),
+ dbesc($updated),
+ dbesc($contact['nurl'])
+ );
+ } else {
+ q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d",
+ dbesc($updated),
+ dbesc($updated),
+ intval($contact['id'])
+ );
+
+ q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
+ dbesc($updated),
+ dbesc($contact['nurl'])
+ );
+ }
+ }
+ return;
+ }
+
$xml = false;
$t = $contact['last-update'];
mark_for_death($contact);
// set the last-update so we don't keep polling
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d",
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contact['id'])
);
mark_for_death($contact);
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d",
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contact['id'])
);
// set the last-update so we don't keep polling
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d",
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contact['id'])
);
logger('poller: received xml : ' . $xml, LOGGER_DATA);
if(! strstr($xml,'<')) {
logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d",
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contact['id'])
);
return;
}
-
consume_feed($xml,$importer,$contact,$hub,1,1);
}
}
}
- }
- $updated = datetime_convert();
+ $updated = datetime_convert();
- $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d",
- dbesc($updated),
- dbesc($updated),
- intval($contact['id'])
- );
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d",
+ dbesc($updated),
+ dbesc($updated),
+ intval($contact['id'])
+ );
+ q("UPDATE `gcontact` SET `last_contact` = '%s' WHERE `nurl` = '%s'",
+ dbesc($updated),
+ dbesc($contact['nurl'])
+ );
- // load current friends if possible.
+ } elseif (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_FEED))) {
+ $updated = datetime_convert();
- if($contact['poco']) {
- $r = q("SELECT count(*) as total from glink
- where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `failure_update` = '%s' WHERE `id` = %d",
+ dbesc($updated),
+ dbesc($updated),
+ intval($contact['id'])
+ );
+
+ q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
+ dbesc($updated),
+ dbesc($contact['nurl'])
+ );
+ } else {
+ $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d",
+ dbesc($updated),
intval($contact['id'])
);
- }
- if(count($r)) {
- if(! $r[0]['total']) {
- poco_load($contact['id'],$importer_uid,0,$contact['poco']);
- }
}
return;
if (preg_match_all("(\[url=([$URLSearchString]*)\]\s*\[img\]([$URLSearchString]*)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) {
if (count($pictures) == 1) {
// Checking, if the link goes to a picture
- $data = parseurl_getsiteinfo($pictures[0][1], true);
+ $data = parseurl_getsiteinfo_cached($pictures[0][1], true);
if ($data["type"] == "photo") {
$post["type"] = "photo";
if (isset($data["images"][0]))
}
} elseif (isset($post["url"]) AND ($post["type"] == "video")) {
require_once("mod/parse_url.php");
- $data = parseurl_getsiteinfo($post["url"], true);
+ $data = parseurl_getsiteinfo_cached($post["url"], true);
if (isset($data["images"][0]))
$post["image"] = $data["images"][0]["src"];
proc_run('php',"include/dsprphotoq.php");
+ // run the process to discover global contacts in the background
+
+ proc_run('php',"include/discover_poco.php");
+
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
<?php
require_once('include/datetime.php');
+require_once("include/Scrape.php");
+require_once("include/html2bbcode.php");
/*
* poco_load
function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
- require_once("include/html2bbcode.php");
-
$a = get_app();
if($cid) {
if ($profile_url == "")
return $gcid;
+ $orig_updated = $updated;
+
// Don't store the statusnet connector as network
// We can't simply set this to NETWORK_OSTATUS since the connector could have fetched posts from friendica as well
if ($network == NETWORK_STATUSNET)
$x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
dbesc(normalise_link($profile_url))
);
- if(count($x) AND ($network == "") AND ($x[0]["network"] != NETWORK_STATUSNET))
- $network = $x[0]["network"];
- if (($network == "") OR ($name == "") OR ($profile_photo == "")) {
- require_once("include/Scrape.php");
+ if (count($x)) {
+ if (($network == "") AND ($x[0]["network"] != NETWORK_STATUSNET))
+ $network = $x[0]["network"];
+
+ if ($updated == "0000-00-00 00:00:00")
+ $updated = $x[0]["updated"];
+
+ $last_contact = $x[0]["last_contact"];
+ $last_failure = $x[0]["last_failure"];
+ $server_url = $x[0]["server_url"];
+ } else {
+ $last_contact = "0000-00-00 00:00:00";
+ $last_failure = "0000-00-00 00:00:00";
+ $server_url = "";
+ }
+ if (($network == "") OR ($name == "") OR ($profile_photo == "") OR ($server_url == "")) {
$data = probe_url($profile_url);
$network = $data["network"];
$name = $data["name"];
$profile_url = $data["url"];
$profile_photo = $data["photo"];
+ $server_url = $data["baseurl"];
}
if (count($x) AND ($x[0]["network"] == "") AND ($network != "")) {
logger("profile-check generation: ".$generation." Network: ".$network." URL: ".$profile_url." name: ".$name." avatar: ".$profile_photo, LOGGER_DEBUG);
+ // Only fetch last update manually if it wasn't provided and enabled in the system
+ if (get_config('system','poco_completion') AND ($orig_updated == "0000-00-00 00:00:00") AND poco_do_update($updated, $last_contact, $last_failure)) {
+ $last_updated = poco_last_updated($profile_url);
+ if ($last_updated) {
+ $updated = $last_updated;
+ $last_contact = datetime_convert();
+ logger("Last updated for profile ".$profile_url.": ".$updated, LOGGER_DEBUG);
+
+ if (count($x))
+ q("UPDATE `gcontact` SET `last_contact` = '%s' WHERE `nurl` = '%s'", dbesc($last_contact), dbesc(normalise_link($profile_url)));
+ } else {
+ $last_failure = datetime_convert();
+
+ if (count($x))
+ q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'", dbesc($last_failure), dbesc(normalise_link($profile_url)));
+ }
+ }
+
+ poco_check_server($server_url, $network);
+
+ // Test - remove before flight
+ //if ($last_contact > $last_failure)
+ // q("UPDATE `gserver` SET `last_contact` = '%s' WHERE `nurl` = '%s'", dbesc($last_contact), dbesc(normalise_link($server_url)));
+ //else
+ // q("UPDATE `gserver` SET `last_failure` = '%s' WHERE `nurl` = '%s'", dbesc($last_failure), dbesc(normalise_link($server_url)));
+
if(count($x)) {
$gcid = $x[0]['id'];
$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',
+ 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
WHERE (`generation` >= %d OR `generation` = 0) AND `nurl` = '%s'",
dbesc($name),
dbesc($profile_photo),
dbesc($connect_url),
dbesc($profile_url),
+ dbesc($server_url),
dbesc($updated),
dbesc($location),
dbesc($about),
);
}
} else {
- q("INSERT INTO `gcontact` (`name`,`network`, `url`,`nurl`,`photo`,`connect`, `updated`, `location`, `about`, `keywords`, `gender`, `generation`)
- VALUES ('%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s', '%s', '%s', %d)",
+ q("INSERT INTO `gcontact` (`name`,`network`, `url`,`nurl`,`photo`,`connect`, `server_url`, `updated`, `last_contact`, `last_failure`, `location`, `about`, `keywords`, `gender`, `generation`)
+ VALUES ('%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
dbesc($name),
dbesc($network),
dbesc($profile_url),
dbesc(normalise_link($profile_url)),
dbesc($profile_photo),
dbesc($connect_url),
+ dbesc($server_url),
dbesc($updated),
+ dbesc($last_contact),
+ dbesc($last_failure),
dbesc($location),
dbesc($about),
dbesc($keywords),
return $gcid;
}
+function poco_last_updated($profile) {
+ $data = probe_url($profile);
+
+ if (($data["poll"] == "") OR ($data["network"] == NETWORK_FEED))
+ return false;
+
+ // To-Do: Use noscrape
+
+ $feedret = z_fetch_url($data["poll"]);
+
+ if (!$feedret["success"])
+ return false;
+
+ $doc = new DOMDocument();
+ @$doc->loadXML($feedret["body"]);
+
+ $xpath = new DomXPath($doc);
+ $xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom");
+
+ $entries = $xpath->query('/atom:feed/atom:entry');
+
+ $last_updated = "";
+
+ foreach ($entries AS $entry) {
+ $published = $xpath->query('atom:published/text()', $entry)->item(0)->nodeValue;
+ $updated = $xpath->query('atom:updated/text()', $entry)->item(0)->nodeValue;
+
+ if ($last_updated < $published)
+ $last_updated = $published;
+
+ if ($last_updated < $updated)
+ $last_updated = $updated;
+ }
+
+ // Maybe there aren't any entries. Then check if it is a valid feed
+ if ($last_updated == "")
+ if ($xpath->query('/atom:feed')->length > 0)
+ $last_updated = "0000-00-00 00:00:00";
+
+ return($last_updated);
+}
+
+function poco_do_update($updated, $last_contact, $last_failure) {
+ $now = strtotime(datetime_convert());
+
+ if ($updated > $last_contact)
+ $contact_time = strtotime($updated);
+ else
+ $contact_time = strtotime($last_contact);
+
+ $failure_time = strtotime($last_failure);
+
+ // If the last contact was less than 24 hours then don't update
+ if (($now - $contact_time) < (60 * 60 * 24))
+ return false;
+
+ // If the last failure was less than 24 hours then don't update
+ if (($now - $failure_time) < (60 * 60 * 24))
+ return false;
+
+ // If the last contact was less than a week ago and the last failure is older than a week then don't update
+ if ((($now - $contact_time) < (60 * 60 * 24 * 7)) AND ($contact_time > $failure_time))
+ return false;
+
+ // If the last contact time was more than a week ago, then only try once a week
+ if (($now - $contact_time) > (60 * 60 * 24 * 7) AND ($now - $failure_time) < (60 * 60 * 24 * 7))
+ return false;
+
+ // If the last contact time was more than a month ago, then only try once a month
+ if (($now - $contact_time) > (60 * 60 * 24 * 30) AND ($now - $failure_time) < (60 * 60 * 24 * 30))
+ return false;
+
+ return true;
+}
+
+function poco_to_boolean($val) {
+ if (($val == "true") OR ($val == 1))
+ return(true);
+ if (($val == "false") OR ($val == 0))
+ return(false);
+
+ return ($val);
+}
+
+function poco_check_server($server_url, $network = "") {
+
+ if ($server_url == "")
+ return;
+
+ $servers = q("SELECT * FROM `gserver` WHERE `nurl` = '%s'", dbesc(normalise_link($server_url)));
+ if ($servers) {
+ $poco = $servers[0]["poco"];
+ $noscrape = $servers[0]["noscrape"];
+
+ if ($network == "")
+ $network = $servers[0]["network"];
+
+ $last_contact = $servers[0]["last_contact"];
+ $last_failure = $servers[0]["last_failure"];
+ $version = $servers[0]["version"];
+ $platform = $servers[0]["platform"];
+ $site_name = $servers[0]["site_name"];
+ $info = $servers[0]["info"];
+ $register_policy = $servers[0]["register_policy"];
+
+ // Only check the server once a week
+ if (strtotime(datetime_convert()) < (strtotime($last_contact) + (60 * 60 * 24 * 7)))
+ return;
+
+ if (strtotime(datetime_convert()) < (strtotime($last_failure) + (60 * 60 * 24 * 7)))
+ return;
+ } else {
+ $poco = "";
+ $noscrape = "";
+ $version = "";
+ $platform = "";
+ $site_name = "";
+ $info = "";
+ $register_policy = -1;
+
+ $last_contact = "0000-00-00 00:00:00";
+ $last_failure = "0000-00-00 00:00:00";
+ }
+
+ $failure = false;
+ $orig_last_failure = $last_failure;
+
+ // Check if the page is accessible via SSL.
+ $server_url = str_replace("http://", "https://", $server_url);
+ $serverret = z_fetch_url($server_url."/.well-known/host-meta");
+
+ // Maybe the page is unencrypted only?
+ $xmlobj = @simplexml_load_string($serverret["body"],'SimpleXMLElement',0, "http://docs.oasis-open.org/ns/xri/xrd-1.0");
+ if (!$serverret["success"] OR ($serverret["body"] == "") OR (@sizeof($xmlobj) == 0) OR !is_object($xmlobj)) {
+ $server_url = str_replace("https://", "http://", $server_url);
+ $serverret = z_fetch_url($server_url."/.well-known/host-meta");
+
+ $xmlobj = @simplexml_load_string($serverret["body"],'SimpleXMLElement',0, "http://docs.oasis-open.org/ns/xri/xrd-1.0");
+ }
+
+ if (!$serverret["success"] OR ($serverret["body"] == "") OR (sizeof($xmlobj) == 0) OR !is_object($xmlobj)) {
+ $last_failure = datetime_convert();
+ $failure = true;
+ } elseif ($network == NETWORK_DIASPORA)
+ $last_contact = datetime_convert();
+
+ if (!$failure) {
+ // Test for Statusnet
+ // Will also return data for Friendica and GNU Social - but it will be overwritten later
+ // The "not implemented" is a special treatment for really, really old Friendica versions
+ $serverret = z_fetch_url($server_url."/api/statusnet/version.json");
+ if ($serverret["success"] AND ($serverret["body"] != '{"error":"not implemented"}') AND ($serverret["body"] != '') AND (strlen($serverret["body"]) < 250)) {
+ $platform = "StatusNet";
+ $version = trim($serverret["body"], '"');
+ $network = NETWORK_OSTATUS;
+ }
+
+ // Test for GNU Social
+ $serverret = z_fetch_url($server_url."/api/gnusocial/version.json");
+ if ($serverret["success"] AND ($serverret["body"] != '{"error":"not implemented"}') AND ($serverret["body"] != '') AND (strlen($serverret["body"]) < 250)) {
+ $platform = "GNU Social";
+ $version = trim($serverret["body"], '"');
+ $network = NETWORK_OSTATUS;
+ }
+
+ $serverret = z_fetch_url($server_url."/api/statusnet/config.json");
+ if ($serverret["success"]) {
+ $data = json_decode($serverret["body"]);
+
+ if (isset($data->site->server)) {
+ $last_contact = datetime_convert();
+
+ if (isset($data->site->redmatrix)) {
+ if (isset($data->site->redmatrix->PLATFORM_NAME))
+ $platform = $data->site->redmatrix->PLATFORM_NAME;
+ elseif (isset($data->site->redmatrix->RED_PLATFORM))
+ $platform = $data->site->redmatrix->RED_PLATFORM;
+
+ $version = $data->site->redmatrix->RED_VERSION;
+ $network = NETWORK_DIASPORA;
+ }
+ if (isset($data->site->friendica)) {
+ $platform = $data->site->friendica->FRIENDICA_PLATFORM;
+ $version = $data->site->friendica->FRIENDICA_VERSION;
+ $network = NETWORK_DFRN;
+ }
+
+ $site_name = $data->site->name;
+
+ $data->site->closed = poco_to_boolean($data->site->closed);
+ $data->site->private = poco_to_boolean($data->site->private);
+ $data->site->inviteonly = poco_to_boolean($data->site->inviteonly);
+
+ if (!$data->site->closed AND !$data->site->private and $data->site->inviteonly)
+ $register_policy = REGISTER_APPROVE;
+ elseif (!$data->site->closed AND !$data->site->private)
+ $register_policy = REGISTER_OPEN;
+ else
+ $register_policy = REGISTER_CLOSED;
+ }
+ }
+ }
+
+ // Query statistics.json. Optional package for Diaspora, Friendica and Redmatrix
+ if (!$failure) {
+ $serverret = z_fetch_url($server_url."/statistics.json");
+ if ($serverret["success"]) {
+ $data = json_decode($serverret["body"]);
+ if ($version == "")
+ $version = $data->version;
+
+ $site_name = $data->name;
+
+ if (isset($data->network) AND ($platform == ""))
+ $platform = $data->network;
+
+ if ($data->registrations_open)
+ $register_policy = REGISTER_OPEN;
+ else
+ $register_policy = REGISTER_CLOSED;
+
+ if (isset($data->version))
+ $last_contact = datetime_convert();
+ }
+ }
+
+ // Check for noscrape
+ // Friendica servers could be detected as OStatus servers
+ if (!$failure AND in_array($network, array(NETWORK_DFRN, NETWORK_OSTATUS))) {
+ $serverret = z_fetch_url($server_url."/friendica/json");
+
+ if ($serverret["success"]) {
+ $data = json_decode($serverret["body"]);
+
+ if (isset($data->version)) {
+ $last_contact = datetime_convert();
+ $network = NETWORK_DFRN;
+
+ $noscrape = $data->no_scrape_url;
+ $version = $data->version;
+ $site_name = $data->site_name;
+ $info = $data->info;
+ $register_policy_str = $data->register_policy;
+ $platform = $data->platform;
+
+ switch ($register_policy_str) {
+ case "REGISTER_CLOSED":
+ $register_policy = REGISTER_CLOSED;
+ break;
+ case "REGISTER_APPROVE":
+ $register_policy = REGISTER_APPROVE;
+ break;
+ case "REGISTER_OPEN":
+ $register_policy = REGISTER_OPEN;
+ break;
+ }
+ }
+ }
+ }
+
+ // Look for poco
+ if (!$failure) {
+ $serverret = z_fetch_url($server_url."/poco");
+ if ($serverret["success"]) {
+ $data = json_decode($serverret["body"]);
+ if (isset($data->totalResults)) {
+ $poco = $server_url."/poco";
+ $last_contact = datetime_convert();
+ }
+ }
+ }
+
+ if ($servers)
+ q("UPDATE `gserver` SET `url` = '%s', `version` = '%s', `site_name` = '%s', `info` = '%s', `register_policy` = %d, `poco` = '%s', `noscrape` = '%s',
+ `network` = '%s', `platform` = '%s', `last_contact` = '%s', `last_failure` = '%s' WHERE `nurl` = '%s'",
+ dbesc($server_url),
+ dbesc($version),
+ dbesc($site_name),
+ dbesc($info),
+ intval($register_policy),
+ dbesc($poco),
+ dbesc($noscrape),
+ dbesc($network),
+ dbesc($platform),
+ dbesc($last_contact),
+ dbesc($last_failure),
+ dbesc(normalise_link($server_url))
+ );
+ else
+ q("INSERT INTO `gserver` (`url`, `nurl`, `version`, `site_name`, `info`, `register_policy`, `poco`, `noscrape`, `network`, `platform`, `last_contact`)
+ VALUES ('%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s')",
+ dbesc($server_url),
+ dbesc(normalise_link($server_url)),
+ dbesc($version),
+ dbesc($site_name),
+ dbesc($info),
+ intval($register_policy),
+ dbesc($poco),
+ dbesc($noscrape),
+ dbesc($network),
+ dbesc($platform),
+ dbesc(datetime_convert())
+ );
+}
+
function poco_contact_from_body($body, $created, $cid, $uid) {
preg_replace_callback("/\[share(.*?)\].*?\[\/share\]/ism",
function ($match) use ($created, $cid, $uid){
}
function sub_poco_from_share($share, $created, $cid, $uid) {
- $profile = "";
- preg_match("/profile='(.*?)'/ism", $share[1], $matches);
- if ($matches[1] != "")
- $profile = $matches[1];
+ $profile = "";
+ preg_match("/profile='(.*?)'/ism", $share[1], $matches);
+ if ($matches[1] != "")
+ $profile = $matches[1];
- preg_match('/profile="(.*?)"/ism', $share[1], $matches);
- if ($matches[1] != "")
- $profile = $matches[1];
+ preg_match('/profile="(.*?)"/ism', $share[1], $matches);
+ if ($matches[1] != "")
+ $profile = $matches[1];
if ($profile == "")
return;
logger("prepare poco_check for profile ".$profile, LOGGER_DEBUG);
- poco_check($profile, "", "", "", "", "", "", "", "", $created, 3, $cid, $uid);
+ poco_check($profile, "", "", "", "", "", "", "", "", $created, 3, $cid, $uid);
}
function poco_store($item) {
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 ",
intval($uid),
}
}
}
+
+function poco_discover() {
+
+ $last_update = date("c", time() - (60 * 60 * 24));
+
+ $r = q("SELECT `poco`, `nurl` FROM `gserver` WHERE `last_contact` > `last_failure` AND `poco` != '' AND `last_poco_query` < '%s' ORDER BY RAND()", dbesc($last_update));
+ if ($r)
+ foreach ($r AS $server) {
+ $url = $server["poco"]."/@global?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,generation";
+
+ $retdata = z_fetch_url($url);
+ if ($retdata["success"]) {
+ poco_discover_server(json_decode($retdata["body"]));
+ q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"]));
+ break;
+ } else
+ q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"]));
+
+ }
+}
+
+function poco_discover_server($data) {
+
+ foreach ($data->entry AS $entry) {
+ $profile_url = '';
+ $profile_photo = '';
+ $connect_url = '';
+ $name = '';
+ $network = '';
+ $updated = '0000-00-00 00:00:00';
+ $location = '';
+ $about = '';
+ $keywords = '';
+ $gender = '';
+ $generation = 0;
+
+ $name = $entry->displayName;
+
+ if(isset($entry->urls)) {
+ foreach($entry->urls as $url) {
+ if($url->type == 'profile') {
+ $profile_url = $url->value;
+ continue;
+ }
+ if($url->type == 'webfinger') {
+ $connect_url = str_replace('acct:' , '', $url->value);
+ continue;
+ }
+ }
+ }
+ if(isset($entry->photos)) {
+ foreach($entry->photos as $photo) {
+ if($photo->type == 'profile') {
+ $profile_photo = $photo->value;
+ continue;
+ }
+ }
+ }
+
+ if(isset($entry->updated))
+ $updated = date("Y-m-d H:i:s", strtotime($entry->updated));
+
+ if(isset($entry->network))
+ $network = $entry->network;
+
+ if(isset($entry->currentLocation))
+ $location = $entry->currentLocation;
+
+ if(isset($entry->aboutMe))
+ $about = html2bbcode($entry->aboutMe);
+
+ if(isset($entry->gender))
+ $gender = $entry->gender;
+
+ if(isset($entry->generation) AND ($entry->generation > 0))
+ $generation = ++$entry->generation;
+
+ if(isset($entry->tags))
+ foreach($entry->tags as $tag)
+ $keywords = implode(", ", $tag);
+
+ if ($generation > 0)
+ poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation);
+ }
+}
+?>
$poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0);
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$maxloadavg_frontend = ((x($_POST,'maxloadavg_frontend')) ? intval(trim($_POST['maxloadavg_frontend'])) : 50);
+ $poco_completion = ((x($_POST,'poco_completion')) ? intval(trim($_POST['poco_completion'])) : false);
+ $poco_discovery = ((x($_POST,'poco_discovery')) ? intval(trim($_POST['poco_discovery'])) : false);
$dfrn_only = ((x($_POST,'dfrn_only')) ? True : False);
$ostatus_disabled = !((x($_POST,'ostatus_disabled')) ? True : False);
$ostatus_poll_interval = ((x($_POST,'ostatus_poll_interval')) ? intval(trim($_POST['ostatus_poll_interval'])) : 0);
set_config('system','poll_interval',$poll_interval);
set_config('system','maxloadavg',$maxloadavg);
set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
+ set_config('system','poco_completion',$poco_completion);
+ set_config('system','poco_discovery',$poco_discovery);
set_config('config','sitename',$sitename);
set_config('config','hostname',$hostname);
set_config('config','sender_email', $sender_email);
set_config('system','suppress_tags',$suppress_tags);
set_config('system','shortcut_icon',$shortcut_icon);
set_config('system','touch_icon',$touch_icon);
-
+
if ($banner==""){
// don't know why, but del_config doesn't work...
q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
'$upload' => t('File upload'),
'$corporate' => t('Policies'),
'$advanced' => t('Advanced'),
+ '$portable_contacts' => t('Portable Contact Directory'),
'$performance' => t('Performance'),
'$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
'$baseurl' => $a->get_baseurl(true),
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$maxloadavg_frontend' => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
+ '$poco_completion' => array('poco_completion', t("Completion of incoming contacts"), get_config('system','poco_completion'), t("Complete data of incomplete incoming contacts that are provided by the 'portable contacts' functionality. (Useful for poco exchange with Redmatrix and friendica servers before 3.3)")),
+ '$poco_discovery' => array('poco_discovery', t("Discover contacts from other servers"), get_config('system','poco_discovery'), t("Periodically query other friendica servers for their recent contacts.")),
+
'$use_fulltext_engine' => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")),
'$suppress_language' => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
'$suppress_tags' => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
return($complete);
}
+function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = true) {
+
+ $data = Cache::get("parse_url:".$no_guessing.":".$do_oembed.":".$url);
+ if (!is_null($data)) {
+ $data = unserialize($data);
+ return $data;
+ }
+
+ $data = parseurl_getsiteinfo($url, $no_guessing, $do_oembed);
+
+ Cache::set("parse_url:".$no_guessing.":".$do_oembed.":".$url,serialize($data));
+
+ return $data;
+}
+
function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $count = 1) {
require_once("include/network.php");
$update_limit = date("Y-m-d H:i:s",strtotime($_GET['updatedSince']));
if ($global) {
- $r = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `updated` >= '%s' AND `network` IN ('%s')",
+ $r = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `updated` >= '%s' AND `last_contact` >= `last_failure` AND `network` IN ('%s')",
dbesc($update_limit),
dbesc(NETWORK_DFRN)
);
} elseif($system_mode) {
$r = q("SELECT count(*) AS `total` FROM `contact` WHERE `self` = 1 AND `network` IN ('%s', '%s', '%s', '%s', '')
+ AND `success_update` >= `failure_update`
AND `uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) ",
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
);
} else {
$r = q("SELECT count(*) AS `total` FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
- AND `network` IN ('%s', '%s', '%s', '%s', '') $sql_extra",
+ AND `success_update` >= `failure_update` AND `network` IN ('%s', '%s', '%s', '%s', '') $sql_extra",
intval($user['uid']),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
if ($global) {
- $r = q("SELECT * FROM `gcontact` WHERE `updated` > '%s' AND `network` IN ('%s') LIMIT %d, %d",
+ $r = q("SELECT * FROM `gcontact` WHERE `updated` > '%s' AND `network` IN ('%s') AND `last_contact` >= `last_failure` LIMIT %d, %d",
dbesc($update_limit),
dbesc(NETWORK_DFRN),
intval($startIndex),
`profile`.`address` AS `paddress`, `profile`.`region` AS `pregion`, `profile`.`postal-code` AS `ppostalcode`, `profile`.`country-name` AS `pcountry`
FROM `contact` INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
WHERE `self` = 1 AND `network` IN ('%s', '%s', '%s', '%s', '') AND `profile`.`is-default`
+ AND `contact`.`success_update` >= `contact`.`failure_update`
AND `contact`.`uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) LIMIT %d, %d",
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
);
} else {
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
- AND `network` IN ('%s', '%s', '%s', '%s', '') $sql_extra LIMIT %d, %d",
+ AND `success_update` >= `failure_update` AND `network` IN ('%s', '%s', '%s', '%s', '') $sql_extra LIMIT %d, %d",
intval($user['uid']),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
<?php
-define( 'UPDATE_VERSION' , 1185 );
+define( 'UPDATE_VERSION' , 1186 );
/**
*
{{include file="field_checkbox.tpl" field=$old_share}}
{{include file="field_checkbox.tpl" field=$hide_help}}
{{include file="field_select.tpl" field=$singleuser}}
-
-
<div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
<h3>{{$registration}}</h3>
{{include file="field_checkbox.tpl" field=$no_multi_reg}}
{{include file="field_checkbox.tpl" field=$no_openid}}
{{include file="field_checkbox.tpl" field=$no_regfullname}}
-
<div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
<h3>{{$upload}}</h3>
{{include file="field_input.tpl" field=$maximagesize}}
{{include file="field_input.tpl" field=$maximagelength}}
{{include file="field_input.tpl" field=$jpegimagequality}}
+ <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
<h3>{{$corporate}}</h3>
{{include file="field_input.tpl" field=$allowed_sites}}
<div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
<h3>{{$advanced}}</h3>
- {{include file="field_select.tpl" field=$rino}}
+ {{include file="field_select.tpl" field=$rino}}
{{include file="field_checkbox.tpl" field=$no_utf}}
{{include file="field_checkbox.tpl" field=$verifyssl}}
{{include file="field_input.tpl" field=$proxy}}
{{include file="field_input.tpl" field=$basepath}}
{{include file="field_checkbox.tpl" field=$suppress_language}}
{{include file="field_checkbox.tpl" field=$suppress_tags}}
+ <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
+
+ <h3>{{$portable_contacts}}</h3>
+ {{include file="field_checkbox.tpl" field=$poco_completion}}
+ {{include file="field_checkbox.tpl" field=$poco_discovery}}
+ <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
<h3>{{$performance}}</h3>
{{include file="field_checkbox.tpl" field=$use_fulltext_engine}}