Enforcing standards ahead of moving App to src

This commit is contained in:
Hypolite Petovan 2017-05-01 22:50:24 -04:00
commit 68c1939d12
13 changed files with 1292 additions and 1298 deletions

View file

@ -1,114 +1,128 @@
<?php
// Debug stuff.
// ini_set('display_errors', 1);
// ini_set('log_errors','0');
error_reporting(E_ALL^E_NOTICE);
$start_maintain = time();
$verbose = $argv[1] === 'verbose';
//Startup.
require_once('boot.php');
$a = new App;
//Config and DB.
require_once(".htconfig.php");
require_once("dba.php");
// Debug stuff.
// ini_set('display_errors', 1);
// ini_set('log_errors','0');
error_reporting(E_ALL ^ E_NOTICE);
$start_maintain = time();
$verbose = $argv[1] === 'verbose';
//Startup.
require_once 'boot.php';
$a = new App;
//Config and DB.
require_once '.htconfig.php';
require_once 'dba.php';
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Get our set of items. Youngest items first, after the threshold.
//This may be counter-intuitive, but is to prevent items that fail to update from blocking the rest.
$res = q("SELECT `id`, `homepage`, `censored`
FROM `profile`
WHERE `updated` < '%s'
ORDER BY `updated` DESC
LIMIT %u",
dbesc(date('Y-m-d H:i:s', time() - $a->config['maintenance']['min_scrape_delay'])),
intval($a->config['maintenance']['max_scrapes'])
);
//Nothing to do.
if (!$res || !count($res)) {
exit;
}
//Close DB here. Threads need their private connection.
$db->getdb()->close();
//We need the scraper.
require_once 'include/submit.php';
//POSIX threads only.
if (!function_exists('pcntl_fork')) {
logger('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.');
die('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.');
}
//Create the threads we need.
$items = count($res);
$threadc = min($a->config['maintenance']['threads'], $items); //Don't need more threads than items.
$threads = array();
//Debug...
if ($verbose) {
echo "Creating $threadc maintainer threads for $items profiles." . PHP_EOL;
}
logger("Creating $threadc maintainer threads for $items profiles.");
for ($i = 0; $i < $threadc; $i++) {
$pid = pcntl_fork();
if ($pid === -1) {
if ($verbose) {
echo('Error: something went wrong with the fork. ' . pcntl_strerror());
}
logger('Error: something went wrong with the fork. ' . pcntl_strerror());
die('Error: something went wrong with the fork. ' . pcntl_strerror());
}
//You're a child, go do some labor!
if ($pid === 0) {
break;
}
//Store the list of PID's.
if ($pid > 0) {
$threads[] = $pid;
}
}
//The work for child processes.
if ($pid === 0) {
//Lets be nice, we're only doing maintenance here...
pcntl_setpriority(5);
//Get personal DBA's.
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Get our set of items. Youngest items first, after the threshold.
//This may be counter-intuitive, but is to prevent items that fail to update from blocking the rest.
$res = q(
"SELECT `id`, `homepage`, `censored` FROM `profile` WHERE `updated` < '%s' ORDER BY `updated` DESC LIMIT %u",
dbesc(date('Y-m-d H:i:s', time()-$a->config['maintenance']['min_scrape_delay'])),
intval($a->config['maintenance']['max_scrapes'])
);
//Nothing to do.
if(!$res || !count($res)){
exit;
//Get our (round-robin) workload from the DB results.
$myIndex = $i + 1;
$workload = array();
while (isset($res[$i])) {
$entry = $res[$i];
$workload[] = $entry;
$ids[] = $entry['id'];
$i += $threadc;
}
//Close DB here. Threads need their private connection.
$db->getdb()->close();
//We need the scraper.
require_once('include/submit.php');
//POSIX threads only.
if(!function_exists('pcntl_fork')){
logger('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.');
die('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.');
}
//Create the threads we need.
$items = count($res);
$threadc = min($a->config['maintenance']['threads'], $items); //Don't need more threads than items.
$threads = array();
//Debug...
if($verbose) echo("Creating $threadc maintainer threads for $items profiles.".PHP_EOL);
logger("Creating $threadc maintainer threads for $items profiles.");
for($i = 0; $i < $threadc; $i++){
$pid = pcntl_fork();
if($pid === -1){
if($verbose) echo('Error: something went wrong with the fork. '.pcntl_strerror());
logger('Error: something went wrong with the fork. '.pcntl_strerror());
die('Error: something went wrong with the fork. '.pcntl_strerror());
while (count($workload)) {
$entry = array_pop($workload);
set_time_limit(20); //This should work for 1 submit.
if ($verbose) {
echo "Submitting " . $entry['homepage'] . PHP_EOL;
}
//You're a child, go do some labor!
if($pid === 0) break;
//Store the list of PID's.
if($pid > 0) $threads[] = $pid;
run_submit($entry['homepage']);
}
//The work for child processes.
if($pid === 0){
//Lets be nice, we're only doing maintenance here...
pcntl_setpriority(5);
//Get personal DBA's.
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Get our (round-robin) workload from the DB results.
$myIndex = $i+1;
$workload = array();
while(isset($res[$i])){
$entry = $res[$i];
$workload[] = $entry;
$ids[] = $entry['id'];
$i+=$threadc;
}
while(count($workload)){
$entry = array_pop($workload);
set_time_limit(20); //This should work for 1 submit.
if($verbose) echo "Submitting ".$entry['homepage'].PHP_EOL;
run_submit($entry['homepage']);
}
exit;
}
exit;
} else {
//The main process.
else{
foreach($threads as $pid){
pcntl_waitpid($pid, $status);
if($status !== 0){
if($verbose) echo "Bad process return value $pid:$status".PHP_EOL;
logger("Bad process return value $pid:$status");
foreach ($threads as $pid) {
pcntl_waitpid($pid, $status);
if ($status !== 0) {
if ($verbose) {
echo "Bad process return value $pid:$status" . PHP_EOL;
}
logger("Bad process return value $pid:$status");
}
$time = time() - $start_maintain;
if($verbose) echo("Maintenance completed. Took $time seconds.".PHP_EOL);
logger("Maintenance completed. Took $time seconds.");
}
$time = time() - $start_maintain;
if ($verbose) {
echo("Maintenance completed. Took $time seconds." . PHP_EOL);
}
logger("Maintenance completed. Took $time seconds.");
}

View file

@ -1,76 +1,81 @@
<?php
/*
#TODO:
* First do the pulls then the pushes.
If pull prevents the push, the push queue just creates a backlog until it gets a chance to push.
* When doing a first-pull, there's a safety mechanism for the timeout and detecting duplicate attempts.
1. Perform all JSON pulls on the source servers.
2. Combine the results into one giant pool of URLs.
3. Write this pool to a file (TODO-file).
4. Shuffle the pool in RAM.
5. Start threads for crawling.
6. Every finished crawl attempt (successful or not) should write to a 2nd file (DONE-file).
IF the first-pull times out, don't do anything else.
Otherwise, mark the dates we last performed a pull from each server.
* When resuming a first-pull.
1. Check for the TODO-file and the DONE-file.
2. Remove the entries in the DONE-file from the pool in the TODO-file.
3. Replace the TODO-file with the updated pool.
4. Perform steps 4, 5 and 6 (shuffle, create threads and crawl) from before.
This way you can resume without repeating attempts.
* Write documentation about syncing.
* Create "official" directory policy for my directory.
* Decide if a retry mechanism is desirable for pulling (for the failed attempts).
After all, you did imply trust when you indicated to pull from that source...
This could be done easily by doing a /sync/pull/all again from those sources.
* Decide if cron_sync.php should be split into push pull and pull-all commands.
*/
#TODO:
* First do the pulls then the pushes.
If pull prevents the push, the push queue just creates a backlog until it gets a chance to push.
* When doing a first-pull, there's a safety mechanism for the timeout and detecting duplicate attempts.
1. Perform all JSON pulls on the source servers.
2. Combine the results into one giant pool of URLs.
3. Write this pool to a file (TODO-file).
4. Shuffle the pool in RAM.
5. Start threads for crawling.
6. Every finished crawl attempt (successful or not) should write to a 2nd file (DONE-file).
IF the first-pull times out, don't do anything else.
Otherwise, mark the dates we last performed a pull from each server.
* When resuming a first-pull.
1. Check for the TODO-file and the DONE-file.
2. Remove the entries in the DONE-file from the pool in the TODO-file.
3. Replace the TODO-file with the updated pool.
4. Perform steps 4, 5 and 6 (shuffle, create threads and crawl) from before.
This way you can resume without repeating attempts.
* Write documentation about syncing.
* Create "official" directory policy for my directory.
* Decide if a retry mechanism is desirable for pulling (for the failed attempts).
After all, you did imply trust when you indicated to pull from that source...
This could be done easily by doing a /sync/pull/all again from those sources.
* Decide if cron_sync.php should be split into push pull and pull-all commands.
*/
// Debug stuff.
ini_set('display_errors', 1);
ini_set('log_errors','0');
error_reporting(E_ALL^E_NOTICE);
ini_set('log_errors', '0');
error_reporting(E_ALL ^ E_NOTICE);
$start_syncing = time();
//Startup.
require_once('boot.php');
require_once 'boot.php';
$a = new App;
//Create a simple log function for CLI use.
global $verbose;
$verbose = $argv[1] === 'verbose';
function msg($message, $fatal=false){
function msg($message, $fatal = false)
{
global $verbose;
if($verbose || $fatal) echo($message.PHP_EOL);
if ($verbose || $fatal)
echo($message . PHP_EOL);
logger($message);
if($fatal) exit(1);
};
if ($fatal) {
exit(1);
}
}
//Config.
require_once(".htconfig.php");
require_once '.htconfig.php';
//Connect the DB.
require_once("dba.php");
require_once 'dba.php';
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Import syncing functions.
require_once('sync.php');
require_once 'sync.php';
//Get work for pulling.
$pull_batch = get_pulling_job($a);
@ -81,12 +86,14 @@ list($push_targets, $push_batch) = get_pushing_job($a);
//Close the connection for now. Process forking and DB connections are not the best of friends.
$db->getdb()->close();
if(count($pull_batch))
if (count($pull_batch)) {
run_pulling_job($a, $pull_batch, $db_host, $db_user, $db_pass, $db_data, $install);
}
//Do our multi-fork job, if we have a batch and targets.
if(count($push_targets) && count($push_batch))
if (count($push_targets) && count($push_batch)) {
run_pushing_job($push_targets, $push_batch, $db_host, $db_user, $db_pass, $db_data, $install);
}
//Log the time it took.
$time = time() - $start_syncing;

View file

@ -1,27 +1,31 @@
<?php
require_once("boot.php");
require_once 'boot.php';
$a = new App;
$a = new App;
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
@include '.htconfig.php';
require_once 'dba.php';
if($argc != 2)
exit;
$db = new dba($db_host, $db_user, $db_pass, $db_data);
load_config('system');
$a->set_baseurl(get_config('system','url'));
$dir = get_config('system','directory_submit_url');
if(! strlen($dir))
exit;
fetch_url($dir . '?url=' . bin2hex($argv[1]));
unset($db_host, $db_user, $db_pass, $db_data);
if ($argc != 2) {
exit;
}
load_config('system');
$a->set_baseurl(get_config('system', 'url'));
$dir = get_config('system', 'directory_submit_url');
if (!strlen($dir)) {
exit;
}
fetch_url($dir . '?url=' . bin2hex($argv[1]));
exit;

View file

@ -1,311 +1,291 @@
<?php
require_once 'boot.php';
require_once("boot.php");
$a = new App;
$a = new App;
@include '.htconfig.php';
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
require_once 'dba.php';
require_once("session.php");
require_once("datetime.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
if($argc < 3)
exit;
unset($db_host, $db_user, $db_pass, $db_data);
$a->set_baseurl(get_config('system','url'));
require_once 'session.php';
require_once 'datetime.php';
$cmd = $argv[1];
if ($argc < 3) {
exit;
}
switch($cmd) {
case 'mail':
default:
$item_id = intval($argv[2]);
if(! $item_id)
killme();
break;
}
$a->set_baseurl(get_config('system', 'url'));
$cmd = $argv[1];
$recipients = array();
if($cmd == 'mail') {
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
if(! count($message))
switch ($cmd) {
case 'mail':
default:
$item_id = intval($argv[2]);
if (!$item_id) {
killme();
$recipients[] = $message[0]['contact-id'];
$item = $message[0];
}
break;
}
}
else {
// find ancestors
$recipients = array();
$r = q("SELECT `parent`, `edited` FROM `item` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
if(! count($r))
killme();
if ($cmd == 'mail') {
$parent = $r[0]['parent'];
$updated = $r[0]['edited'];
$items = q("SELECT * FROM `item` WHERE `parent` = %d ORDER BY `id` ASC",
intval($parent)
);
if(! count($items))
killme();
}
$r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1");
if(count($r))
$owner = $r[0];
else
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1", intval($item_id));
if (!count($message)) {
killme();
}
$recipients[] = $message[0]['contact-id'];
$item = $message[0];
} else {
// find ancestors
if($cmd != 'mail') {
require_once('include/group.php');
$parent = $items[0];
if($parent['type'] == 'remote') {
// local followup to remote post
$followup = true;
$conversant_str = dbesc($parent['contact-id']);
}
else {
$followup = false;
$allow_people = expand_acl($parent['allow_cid']);
$allow_groups = expand_groups(expand_acl($parent['allow_gid']));
$deny_people = expand_acl($parent['deny_cid']);
$deny_groups = expand_groups(expand_acl($parent['deny_gid']));
$conversants = array();
foreach($items as $item) {
$recipients[] = $item['contact-id'];
$conversants[] = $item['contact-id'];
}
$conversants = array_unique($conversants,SORT_NUMERIC);
$recipients = array_unique(array_merge($recipients,$allow_people,$allow_groups),SORT_NUMERIC);
$deny = array_unique(array_merge($deny_people,$deny_groups),SORT_NUMERIC);
$recipients = array_diff($recipients,$deny);
$conversant_str = dbesc(implode(', ',$conversants));
}
$r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
if( ! count($r))
killme();
$contacts = $r;
$tomb_template = file_get_contents('view/atom_tomb.tpl');
$item_template = file_get_contents('view/atom_item.tpl');
$cmnt_template = file_get_contents('view/atom_cmnt.tpl');
$r = q("SELECT `parent`, `edited` FROM `item` WHERE `id` = %d LIMIT 1", intval($item_id));
if (!count($r)) {
killme();
}
$feed_template = file_get_contents('view/atom_feed.tpl');
$mail_template = file_get_contents('view/atom_mail.tpl');
$parent = $r[0]['parent'];
$updated = $r[0]['edited'];
$atom = '';
$items = q("SELECT * FROM `item` WHERE `parent` = %d ORDER BY `id` ASC", intval($parent));
if (!count($items)) {
killme();
}
}
$atom .= replace_macros($feed_template, array(
'$feed_id' => xmlify($a->get_baseurl()),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC',
$updated . '+00:00' , 'Y-m-d\TH:i:s\Z')) ,
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , 'Y-m-d\TH:i:s\Z')) ,
'$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , 'Y-m-d\TH:i:s\Z')) ,
'$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , 'Y-m-d\TH:i:s\Z'))
$r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1");
if (count($r)) {
$owner = $r[0];
} else {
killme();
}
if ($cmd != 'mail') {
require_once 'include/group.php';
$parent = $items[0];
if ($parent['type'] == 'remote') {
// local followup to remote post
$followup = true;
$conversant_str = dbesc($parent['contact-id']);
} else {
$followup = false;
$allow_people = expand_acl($parent['allow_cid']);
$allow_groups = expand_groups(expand_acl($parent['allow_gid']));
$deny_people = expand_acl($parent['deny_cid']);
$deny_groups = expand_groups(expand_acl($parent['deny_gid']));
$conversants = array();
foreach ($items as $item) {
$recipients[] = $item['contact-id'];
$conversants[] = $item['contact-id'];
}
$conversants = array_unique($conversants, SORT_NUMERIC);
$recipients = array_unique(array_merge($recipients, $allow_people, $allow_groups), SORT_NUMERIC);
$deny = array_unique(array_merge($deny_people, $deny_groups), SORT_NUMERIC);
$recipients = array_diff($recipients, $deny);
$conversant_str = dbesc(implode(', ', $conversants));
}
$r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
if (!count($r)) {
killme();
}
$contacts = $r;
$tomb_template = file_get_contents('view/atom_tomb.tpl');
$item_template = file_get_contents('view/atom_item.tpl');
$cmnt_template = file_get_contents('view/atom_cmnt.tpl');
}
$feed_template = file_get_contents('view/atom_feed.tpl');
$mail_template = file_get_contents('view/atom_mail.tpl');
$atom = '';
$atom .= replace_macros($feed_template, array(
'$feed_id' => xmlify($a->get_baseurl()),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['avatar-date'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$uridate' => xmlify(datetime_convert('UTC', 'UTC', $owner['uri-date'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$namdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['name-date'] . '+00:00', 'Y-m-d\TH:i:s\Z'))
));
if ($cmd == 'mail') {
$atom .= replace_macros($mail_template, array(
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$thumb' => xmlify($owner['thumb']),
'$item_id' => xmlify($item['uri']),
'$subject' => xmlify($item['title']),
'$created' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$content' => xmlify($item['body']),
'$parent_id' => xmlify($item['parent-uri'])
));
if($cmd == 'mail') {
$atom .= replace_macros($mail_template, array(
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$thumb' => xmlify($owner['thumb']),
'$item_id' => xmlify($item['uri']),
'$subject' => xmlify($item['title']),
'$created' => xmlify(datetime_convert('UTC', 'UTC',
$item['created'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$content' =>xmlify($item['body']),
'$parent_id' => xmlify($item['parent-uri'])
));
}
else {
if($followup) {
foreach($items as $item) {
if($item['id'] == $item_id) {
$atom .= replace_macros($cmnt_template, array(
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$thumb' => xmlify($owner['thumb']),
'$item_id' => xmlify($item['uri']),
'$title' => xmlify($item['title']),
'$published' => xmlify(datetime_convert('UTC', 'UTC',
$item['created'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$updated' => xmlify(datetime_convert('UTC', 'UTC',
$item['edited'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$content' =>xmlify($item['body']),
'$parent_id' => xmlify($item['parent-uri']),
'$comment_allow' => 0
));
}
} else {
if ($followup) {
foreach ($items as $item) {
if ($item['id'] == $item_id) {
$atom .= replace_macros($cmnt_template, array(
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$thumb' => xmlify($owner['thumb']),
'$item_id' => xmlify($item['uri']),
'$title' => xmlify($item['title']),
'$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$content' => xmlify($item['body']),
'$parent_id' => xmlify($item['parent-uri']),
'$comment_allow' => 0
));
}
}
else {
foreach($items as $item) {
if($item['deleted']) {
$atom .= replace_macros($tomb_template, array(
'$id' => xmlify($item['uri']),
'$updated' => xmlify(datetime_convert('UTC', 'UTC',
$item['edited'] . '+00:00' , 'Y-m-d\TH:i:s\Z'))
));
}
else {
foreach($contacts as $contact) {
if($item['contact-id'] == $contact['id']) {
if($item['parent'] == $item['id']) {
$atom .= replace_macros($item_template, array(
'$name' => xmlify($contact['name']),
'$profile_page' => xmlify($contact['url']),
'$thumb' => xmlify($contact['thumb']),
'$owner_name' => xmlify($item['owner-name']),
'$owner_profile_page' => xmlify($item['owner-link']),
'$owner_thumb' => xmlify($item['owner-avatar']),
'$item_id' => xmlify($item['uri']),
'$title' => xmlify($item['title']),
'$published' => xmlify(datetime_convert('UTC', 'UTC',
$item['created'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$updated' => xmlify(datetime_convert('UTC', 'UTC',
$item['edited'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$content' =>xmlify($item['body']),
'$comment_allow' => (($item['last-child'] && strlen($contact['dfrn-id'])) ? 1 : 0)
));
}
else {
$atom .= replace_macros($cmnt_template, array(
'$name' => xmlify($contact['name']),
'$profile_page' => xmlify($contact['url']),
'$thumb' => xmlify($contact['thumb']),
'$item_id' => xmlify($item['uri']),
'$title' => xmlify($item['title']),
'$published' => xmlify(datetime_convert('UTC', 'UTC',
$item['created'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$updated' => xmlify(datetime_convert('UTC', 'UTC',
$item['edited'] . '+00:00' , 'Y-m-d\TH:i:s\Z')),
'$content' =>xmlify($item['body']),
'$parent_id' => xmlify($item['parent-uri']),
'$comment_allow' => (($item['last-child']) ? 1 : 0)
));
}
} else {
foreach ($items as $item) {
if ($item['deleted']) {
$atom .= replace_macros($tomb_template, array(
'$id' => xmlify($item['uri']),
'$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\TH:i:s\Z'))
));
} else {
foreach ($contacts as $contact) {
if ($item['contact-id'] == $contact['id']) {
if ($item['parent'] == $item['id']) {
$atom .= replace_macros($item_template, array(
'$name' => xmlify($contact['name']),
'$profile_page' => xmlify($contact['url']),
'$thumb' => xmlify($contact['thumb']),
'$owner_name' => xmlify($item['owner-name']),
'$owner_profile_page' => xmlify($item['owner-link']),
'$owner_thumb' => xmlify($item['owner-avatar']),
'$item_id' => xmlify($item['uri']),
'$title' => xmlify($item['title']),
'$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$content' => xmlify($item['body']),
'$comment_allow' => (($item['last-child'] && strlen($contact['dfrn-id'])) ? 1 : 0)
));
} else {
$atom .= replace_macros($cmnt_template, array(
'$name' => xmlify($contact['name']),
'$profile_page' => xmlify($contact['url']),
'$thumb' => xmlify($contact['thumb']),
'$item_id' => xmlify($item['uri']),
'$title' => xmlify($item['title']),
'$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\TH:i:s\Z')),
'$content' => xmlify($item['body']),
'$parent_id' => xmlify($item['parent-uri']),
'$comment_allow' => (($item['last-child']) ? 1 : 0)
));
}
}
}
}
}
}
$atom .= "</feed>\r\n";
}
$atom .= "</feed>\r\n";
// create a clone of this feed but with comments disabled to send to those who can't respond.
// create a clone of this feed but with comments disabled to send to those who can't respond.
$atom_nowrite = str_replace('<dfrn:comment-allow>1','<dfrn:comment-allow>0',$atom);
$atom_nowrite = str_replace('<dfrn:comment-allow>1', '<dfrn:comment-allow>0', $atom);
if($followup)
$recip_str = $parent['contact-id'];
else
$recip_str = implode(', ', $recipients);
if ($followup) {
$recip_str = $parent['contact-id'];
} else {
$recip_str = implode(', ', $recipients);
}
$r = q("SELECT * FROM `contact` WHERE `id` IN ( %s ) ",
dbesc($recip_str)
);
if(! count($r))
killme();
$r = q("SELECT * FROM `contact` WHERE `id` IN ( %s ) ", dbesc($recip_str));
if (!count($r)) {
killme();
}
// delivery loop
// delivery loop
foreach($r as $rr) {
if($rr['self'])
continue;
if(! strlen($rr['dfrn-id']))
continue;
$url = $rr['notify'] . '?dfrn_id=' . $rr['dfrn-id'];
$xml = fetch_url($url);
if(! $xml)
continue;
$res = simplexml_load_string($xml);
if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
continue;
$postvars = array();
$sent_dfrn_id = hex2bin($res->dfrn_id);
$final_dfrn_id = '';
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$rr['pubkey']);
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if($final_dfrn_id != $rr['dfrn-id']) {
// did not decode properly - cannot trust this site
continue;
}
$postvars['dfrn_id'] = $rr['dfrn-id'];
$challenge = hex2bin($res->challenge);
openssl_public_decrypt($challenge,$postvars['challenge'],$rr['pubkey']);
if($cmd == 'mail') {
$postvars['data'] = $atom;
}
elseif(strlen($rr['dfrn-id']) && (! ($rr['blocked']) || ($rr['readonly']))) {
$postvars['data'] = $atom;
}
else {
$postvars['data'] = $atom_nowrite;
}
$xml = post_url($rr['notify'],$postvars);
$res = simplexml_load_string($xml);
// Currently there is no retry attempt for failed mail delivery.
// We need to handle this in the UI, report the non-deliverables and try again
if(($cmd == 'mail') && (intval($res->status) == 0)) {
$r = q("UPDATE `mail` SET `delivered` = 1 WHERE `id` = %d LIMIT 1",
intval($item_id)
);
}
foreach ($r as $rr) {
if ($rr['self']) {
continue;
}
killme();
if (!strlen($rr['dfrn-id'])) {
continue;
}
$url = $rr['notify'] . '?dfrn_id=' . $rr['dfrn-id'];
$xml = fetch_url($url);
if (!$xml) {
continue;
}
$res = simplexml_load_string($xml);
if ((intval($res->status) != 0) || (!strlen($res->challenge)) || (!strlen($res->dfrn_id))) {
continue;
}
$postvars = array();
$sent_dfrn_id = hex2bin($res->dfrn_id);
$final_dfrn_id = '';
openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $rr['pubkey']);
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if ($final_dfrn_id != $rr['dfrn-id']) {
// did not decode properly - cannot trust this site
continue;
}
$postvars['dfrn_id'] = $rr['dfrn-id'];
$challenge = hex2bin($res->challenge);
openssl_public_decrypt($challenge, $postvars['challenge'], $rr['pubkey']);
if ($cmd == 'mail') {
$postvars['data'] = $atom;
} elseif (strlen($rr['dfrn-id']) && (!($rr['blocked']) || ($rr['readonly']))) {
$postvars['data'] = $atom;
} else {
$postvars['data'] = $atom_nowrite;
}
$xml = post_url($rr['notify'], $postvars);
$res = simplexml_load_string($xml);
// Currently there is no retry attempt for failed mail delivery.
// We need to handle this in the UI, report the non-deliverables and try again
if (($cmd == 'mail') && (intval($res->status) == 0)) {
$r = q("UPDATE `mail` SET `delivered` = 1 WHERE `id` = %d LIMIT 1", intval($item_id));
}
}
killme();

View file

@ -1,270 +1,266 @@
<?php
require_once 'boot.php';
require_once('boot.php');
$a = new App;
$a = new App;
@include('.htconfig.php');
@include('.htconfig.php');
require_once('dba.php');
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
require_once 'dba.php';
require_once('session.php');
require_once('datetime.php');
require_once('simplepie/simplepie.inc');
require_once('include/items.php');
$db = new dba($db_host, $db_user, $db_pass, $db_data);
$a->set_baseurl(get_config('system','url'));
unset($db_host, $db_user, $db_pass, $db_data);
$contacts = q("SELECT * FROM `contact`
WHERE `dfrn-id` != '' AND `self` = 0 AND `blocked` = 0
require_once 'session.php';
require_once 'datetime.php';
require_once 'simplepie/simplepie.inc';
require_once 'include/items.php';
$a->set_baseurl(get_config('system', 'url'));
$contacts = q("SELECT * FROM `contact`
WHERE `dfrn-id` != '' AND `self` = 0 AND `blocked` = 0
AND `readonly` = 0 ORDER BY RAND()");
if(! count($contacts))
killme();
if (!count($contacts)) {
killme();
}
foreach($contacts as $contact) {
foreach ($contacts as $contact) {
if ($contact['priority']) {
$update = false;
$t = $contact['last-update'];
if($contact['priority']) {
$update = false;
$t = $contact['last-update'];
switch ($contact['priority']) {
case 5:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', t . " + 1 month"))
$update = true;
break;
case 4:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', t . " + 1 week"))
$update = true;
break;
case 3:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', t . " + 1 day"))
$update = true;
break;
case 2:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', t . " + 12 hour"))
$update = true;
break;
case 1:
default:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', t . " + 1 hour"))
$update = true;
break;
}
if(! $update)
continue;
switch ($contact['priority']) {
case 5:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', t . " + 1 month"))
$update = true;
break;
case 4:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', t . " + 1 week"))
$update = true;
break;
case 3:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', t . " + 1 day"))
$update = true;
break;
case 2:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', t . " + 12 hour"))
$update = true;
break;
case 1:
default:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', t . " + 1 hour"))
$update = true;
break;
}
$r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1");
if(! count($r))
if (!$update) {
continue;
}
}
$importer = $r[0];
$r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1");
if (!count($r)) {
continue;
}
$last_update = (($contact['last-update'] == '0000-00-00 00:00:00')
? datetime_convert('UTC','UTC','now - 30 days','Y-m-d\TH:i:s\Z')
: datetime_convert('UTC','UTC',$contact['last-update'],'Y-m-d\TH:i:s\Z'));
$importer = $r[0];
$url = $contact['poll'] . '?dfrn_id=' . $contact['dfrn-id'] . '&type=data&last_update=' . $last_update ;
$last_update = (($contact['last-update'] == '0000-00-00 00:00:00') ? datetime_convert('UTC', 'UTC', 'now - 30 days', 'Y-m-d\TH:i:s\Z') : datetime_convert('UTC', 'UTC', $contact['last-update'], 'Y-m-d\TH:i:s\Z'));
$xml = fetch_url($url);
if(! $xml)
continue;
$url = $contact['poll'] . '?dfrn_id=' . $contact['dfrn-id'] . '&type=data&last_update=' . $last_update;
$res = simplexml_load_string($xml);
$xml = fetch_url($url);
if (!$xml) {
continue;
}
if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
continue;
$res = simplexml_load_string($xml);
$postvars = array();
if ((intval($res->status) != 0) || (!strlen($res->challenge)) || (!strlen($res->dfrn_id))) {
continue;
}
$sent_dfrn_id = hex2bin($res->dfrn_id);
$postvars = array();
$final_dfrn_id = '';
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if($final_dfrn_id != $contact['dfrn-id']) {
// did not decode properly - cannot trust this site
continue;
}
$sent_dfrn_id = hex2bin($res->dfrn_id);
$postvars['dfrn_id'] = $contact['dfrn-id'];
$challenge = hex2bin($res->challenge);
$final_dfrn_id = '';
openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if ($final_dfrn_id != $contact['dfrn-id']) {
// did not decode properly - cannot trust this site
continue;
}
openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
$postvars['dfrn_id'] = $contact['dfrn-id'];
$challenge = hex2bin($res->challenge);
$xml = post_url($contact['poll'],$postvars);
openssl_public_decrypt($challenge, $postvars['challenge'], $contact['pubkey']);
if(! strlen($xml)) {
// an empty response may mean there's nothing new - record the fact that we checked
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
continue;
}
$xml = post_url($contact['poll'], $postvars);
$feed = new SimplePie();
$feed->set_raw_data($xml);
$feed->enable_order_by_date(false);
$feed->init();
$photo_rawupdate = $feed->get_feed_tags(NAMESPACE_DFRN,'icon-updated');
if($photo_rawupdate) {
$photo_timestamp = datetime_convert('UTC','UTC',$photo_rawupdate[0]['data']);
$photo_url = $feed->get_image_url();
if(strlen($photo_url) && $photo_timestamp > $contact['avatar-date']) {
require_once("Photo.php");
$photo_failure = false;
$r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d LIMIT 1",
intval($contact['id'])
);
if(count($r)) {
$resource_id = $r[0]['resource-id'];
$img_str = fetch_url($photo_url,true);
$img = new Photo($img_str);
if($img) {
q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND contact-id` = %d ",
dbesc($resource_id),
intval($contact['id'])
);
$img->scaleImageSquare(175);
$hash = $resource_id;
$r = $img->store($contact['id'], $hash, basename($photo_url), t('Contact Photos') , 4);
$img->scaleImage(80);
$r = $img->store($contact['id'], $hash, basename($photo_url), t('Contact Photos') , 5);
if($r)
q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
}
}
}
}
foreach($feed->get_items() as $item) {
$deleted = false;
$rawdelete = $item->get_item_tags("http://purl.org/atompub/tombstones/1.0", 'deleted-entry');
if(isset($rawdelete[0]['attribs']['']['ref'])) {
$uri = $rawthread[0]['attribs']['']['ref'];
$deleted = true;
if(isset($rawdelete[0]['attribs']['']['when'])) {
$when = $rawthread[0]['attribs']['']['when'];
$when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s');
}
else
$when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
}
if($deleted) {
$r = q("SELECT * FROM `item` WHERE `uri` = '%s' LIMIT 1",
dbesc($uri)
);
if(count($r)) {
if($r[0]['uri'] == $r[0]['parent-uri']) {
$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s',
`body` = '', `title` = ''
WHERE `parent-uri` = '%s'",
dbesc($when),
dbesc($r[0]['uri'])
);
}
else {
$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s',
`body` = '', `title` = ''
WHERE `uri` = '%s' LIMIT 1",
dbesc($when),
dbesc($uri)
);
}
}
continue;
}
$is_reply = false;
$item_id = $item->get_id();
$rawthread = $item->get_item_tags("http://purl.org/syndication/thread/1.0",'in-reply-to');
if(isset($rawthread[0]['attribs']['']['ref'])) {
$is_reply = true;
$parent_uri = $rawthread[0]['attribs']['']['ref'];
}
if($is_reply) {
// Have we seen it? If not, import it.
$item_id = $item->get_id();
$r = q("SELECT `last-child`, `edited` FROM `item` WHERE `uri` = '%s' LIMIT 1",
dbesc($item_id)
);
// FIXME update content if 'updated' changes
if(count($r)) {
$allow = $item->get_item_tags( NAMESPACE_DFRN , 'comment-allow');
if($allow && $allow[0]['data'] != $r[0]['last-child']) {
$r = q("UPDATE `item` SET `last-child` = %d WHERE `uri` = '%s' LIMIT 1",
intval($allow[0]['data']),
dbesc($item_id)
);
}
continue;
}
$datarray = get_atom_elements($item);
$datarray['parent-uri'] = $parent_uri;
$datarray['contact-id'] = $contact['id'];
$r = post_remote($a,$datarray);
continue;
}
else {
// Head post of a conversation. Have we seen it? If not, import it.
$item_id = $item->get_id();
$r = q("SELECT `last-child`, `edited` FROM `item` WHERE `uri` = '%s' LIMIT 1",
dbesc($item_id)
);
if(count($r)) {
$allow = $item->get_item_tags( NAMESPACE_DFRN ,'comment-allow');
if($allow && $allow[0]['data'] != $r[0]['last-child']) {
$r = q("UPDATE `item` SET `last-child` = %d WHERE `uri` = '%s' LIMIT 1",
intval($allow[0]['data']),
dbesc($item_id)
);
}
continue;
}
$datarray = get_atom_elements($item);
$datarray['parent-uri'] = $item_id;
$datarray['contact-id'] = $contact['id'];
$r = post_remote($a,$datarray);
continue;
}
}
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
if (!strlen($xml)) {
// an empty response may mean there's nothing new - record the fact that we checked
$r = q(
"UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
continue;
}
killme();
$feed = new SimplePie();
$feed->set_raw_data($xml);
$feed->enable_order_by_date(false);
$feed->init();
$photo_rawupdate = $feed->get_feed_tags(NAMESPACE_DFRN, 'icon-updated');
if ($photo_rawupdate) {
$photo_timestamp = datetime_convert('UTC', 'UTC', $photo_rawupdate[0]['data']);
$photo_url = $feed->get_image_url();
if (strlen($photo_url) && $photo_timestamp > $contact['avatar-date']) {
require_once 'Photo.php';
$photo_failure = false;
$r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d LIMIT 1", intval($contact['id']));
if (count($r)) {
$resource_id = $r[0]['resource-id'];
$img_str = fetch_url($photo_url, true);
$img = new Photo($img_str);
if ($img) {
q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND contact-id` = %d ",
dbesc($resource_id),
intval($contact['id'])
);
$img->scaleImageSquare(175);
$hash = $resource_id;
$r = $img->store($contact['id'], $hash, basename($photo_url), t('Contact Photos'), 4);
$img->scaleImage(80);
$r = $img->store($contact['id'], $hash, basename($photo_url), t('Contact Photos'), 5);
if ($r) {
q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
}
}
}
}
}
foreach ($feed->get_items() as $item) {
$deleted = false;
$rawdelete = $item->get_item_tags("http://purl.org/atompub/tombstones/1.0", 'deleted-entry');
if (isset($rawdelete[0]['attribs']['']['ref'])) {
$uri = $rawthread[0]['attribs']['']['ref'];
$deleted = true;
if (isset($rawdelete[0]['attribs']['']['when'])) {
$when = $rawthread[0]['attribs']['']['when'];
$when = datetime_convert('UTC', 'UTC', $when, 'Y-m-d H:i:s');
} else {
$when = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s');
}
}
if ($deleted) {
$r = q("SELECT * FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri));
if (count($r)) {
if ($r[0]['uri'] == $r[0]['parent-uri']) {
$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s',
`body` = '', `title` = ''
WHERE `parent-uri` = '%s'",
dbesc($when),
dbesc($r[0]['uri'])
);
} else {
$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s',
`body` = '', `title` = ''
WHERE `uri` = '%s' LIMIT 1",
dbesc($when),
dbesc($uri)
);
}
}
continue;
}
$is_reply = false;
$item_id = $item->get_id();
$rawthread = $item->get_item_tags("http://purl.org/syndication/thread/1.0", 'in-reply-to');
if (isset($rawthread[0]['attribs']['']['ref'])) {
$is_reply = true;
$parent_uri = $rawthread[0]['attribs']['']['ref'];
}
if ($is_reply) {
// Have we seen it? If not, import it.
$item_id = $item->get_id();
$r = q("SELECT `last-child`, `edited` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($item_id));
// FIXME update content if 'updated' changes
if (count($r)) {
$allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
$r = q("UPDATE `item` SET `last-child` = %d WHERE `uri` = '%s' LIMIT 1",
intval($allow[0]['data']),
dbesc($item_id)
);
}
continue;
}
$datarray = get_atom_elements($item);
$datarray['parent-uri'] = $parent_uri;
$datarray['contact-id'] = $contact['id'];
$r = post_remote($a, $datarray);
continue;
} else {
// Head post of a conversation. Have we seen it? If not, import it.
$item_id = $item->get_id();
$r = q("SELECT `last-child`, `edited` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($item_id));
if (count($r)) {
$allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
$r = q("UPDATE `item` SET `last-child` = %d WHERE `uri` = '%s' LIMIT 1",
intval($allow[0]['data']),
dbesc($item_id)
);
}
continue;
}
$datarray = get_atom_elements($item);
$datarray['parent-uri'] = $item_id;
$datarray['contact-id'] = $contact['id'];
$r = post_remote($a, $datarray);
continue;
}
}
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
}
killme();

View file

@ -1,165 +1,165 @@
<?php
require_once("boot.php");
require_once 'boot.php';
$a = new App;
$a = new App;
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
unset($db_host, $db_user, $db_pass, $db_data);
@include(".htconfig.php");
require_once 'dba.php';
require_once("session.php");
require_once("datetime.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
$a->set_baseurl(get_config('system','url'));
unset($db_host, $db_user, $db_pass, $db_data);
$u = q("SELECT * FROM `user` WHERE 1 LIMIT 1");
if(! count($u))
killme();
require_once 'session.php';
require_once 'datetime.php';
$uid = $u[0]['uid'];
$nickname = $u[0]['nickname'];
$a->set_baseurl(get_config('system', 'url'));
$intros = q("SELECT `intro`.*, `intro`.`id` AS `intro_id`, `contact`.*
$u = q("SELECT * FROM `user` WHERE 1 LIMIT 1");
if (!count($u)) {
killme();
}
$uid = $u[0]['uid'];
$nickname = $u[0]['nickname'];
$intros = q("SELECT `intro`.*, `intro`.`id` AS `intro_id`, `contact`.*
FROM `intro` LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
WHERE `intro`.`blocked` = 0 AND `intro`.`ignore` = 0");
if(! count($intros))
return;
if (!count($intros)) {
return;
}
foreach ($intros as $intro) {
$intro_id = intval($intro['intro_id']);
foreach($intros as $intro) {
$intro_id = intval($intro['intro_id']);
$dfrn_id = $intro['issued-id'];
$contact_id = $intro['contact-id'];
$relation = $intro['rel'];
$site_pubkey = $intro['site-pubkey'];
$dfrn_confirm = $intro['confirm'];
$aes_allow = $intro['aes_allow'];
$dfrn_id = $intro['issued-id'];
$contact_id = $intro['contact-id'];
$relation = $intro['rel'];
$site_pubkey = $intro['site-pubkey'];
$dfrn_confirm = $intro['confirm'];
$aes_allow = $intro['aes_allow'];
$res = openssl_pkey_new(array(
'digest_alg' => 'whirlpool',
'private_key_bits' => 4096,
'encrypt_key' => false));
$res=openssl_pkey_new(array(
'digest_alg' => 'whirlpool',
'private_key_bits' => 4096,
'encrypt_key' => false ));
$private_key = '';
$private_key = '';
openssl_pkey_export($res, $private_key);
openssl_pkey_export($res, $private_key);
$pubkey = openssl_pkey_get_details($res);
$public_key = $pubkey["key"];
$pubkey = openssl_pkey_get_details($res);
$public_key = $pubkey["key"];
$r = q("UPDATE `contact` SET `issued-pubkey` = '%s', `prvkey` = '%s' WHERE `id` = %d LIMIT 1",
dbesc($public_key),
dbesc($private_key),
intval($contact_id)
);
$r = q("UPDATE `contact` SET `issued-pubkey` = '%s', `prvkey` = '%s' WHERE `id` = %d LIMIT 1",
dbesc($public_key),
dbesc($private_key),
intval($contact_id)
);
$params = array();
$params = array();
$src_aes_key = random_string();
$result = "";
$src_aes_key = random_string();
$result = "";
openssl_private_encrypt($dfrn_id, $result, $u[0]['prvkey']);
openssl_private_encrypt($dfrn_id,$result,$u[0]['prvkey']);
$params['dfrn_id'] = $result;
$params['public_key'] = $public_key;
$params['dfrn_id'] = $result;
$params['public_key'] = $public_key;
$my_url = $a->get_baseurl() . '/profile/' . $nickname;
$my_url = $a->get_baseurl() . '/profile/' . $nickname ;
openssl_public_encrypt($my_url, $params['source_url'], $site_pubkey);
if($aes_allow && function_exists('openssl_encrypt')) {
openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
$params['public_key'] = openssl_encrypt($public_key,'AES-256-CBC',$src_aes_key);
}
$res = post_url($dfrn_confirm,$params);
$xml = simplexml_load_string($res);
$status = (int) $xml->status;
switch($status) {
case 0:
break;
case 1:
// birthday paradox - generate new dfrn-id and fall through.
$new_dfrn_id = random_string();
$r = q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d LIMIT 1",
dbesc($new_dfrn_id),
intval($contact_id)
);
case 2:
break;
case 3:
default:
break;
}
if(($status == 0 || $status == 3) && ($intro_id)) {
// delete the notification
$r = q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1",
intval($intro_id)
);
}
if($status != 0)
killme();
require_once("Photo.php");
$photo_failure = false;
$filename = basename($intro['photo']);
$img_str = fetch_url($intro['photo'],true);
$img = new Photo($img_str);
if($img) {
$img->scaleImageSquare(175);
$hash = hash('md5',uniqid(mt_rand(),true));
$r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 4 );
if($r === false)
$photo_failure = true;
$img->scaleImage(80);
$r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 5 );
if($r === false)
$photo_failure = true;
$photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
$thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';
}
else
$photo_failure = true;
if($photo_failure) {
$photo = $a->get_baseurl() . '/images/default-profile.jpg';
$thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
}
$r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `rel` = %d,
`name-date` = '%s', `uri-date` = '%s', `avatar-date` = '%s',
`readonly` = %d, `profile-id` = %d, `blocked` = 0, `pending` = 0,
`network` = 'dfrn' WHERE `id` = %d LIMIT 1",
dbesc($photo),
dbesc($thumb),
intval(($relation == DIRECTION_OUT) ? DIRECTION_BOTH : DIRECTION_IN),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval((x($a->config,'rockstar-readonly')) ? $a->config['rockstar-readonly'] : 0),
intval((x($a->config,'rockstar-profile')) ? $a->config['rockstar-profile'] : 0),
intval($contact_id)
);
openssl_public_encrypt($my_url, $params['source_url'], $site_pubkey);
if ($aes_allow && function_exists('openssl_encrypt')) {
openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
$params['public_key'] = openssl_encrypt($public_key, 'AES-256-CBC', $src_aes_key);
}
killme();
$res = post_url($dfrn_confirm, $params);
$xml = simplexml_load_string($res);
$status = (int) $xml->status;
switch ($status) {
case 0:
break;
case 1:
// birthday paradox - generate new dfrn-id and fall through.
$new_dfrn_id = random_string();
$r = q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d LIMIT 1",
dbesc($new_dfrn_id),
intval($contact_id)
);
case 2:
break;
case 3:
default:
break;
}
if (($status == 0 || $status == 3) && ($intro_id)) {
// delete the notification
$r = q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1", intval($intro_id));
}
if ($status != 0) {
killme();
}
require_once 'Photo.php';
$photo_failure = false;
$filename = basename($intro['photo']);
$img_str = fetch_url($intro['photo'], true);
$img = new Photo($img_str);
if ($img) {
$img->scaleImageSquare(175);
$hash = hash('md5', uniqid(mt_rand(), true));
$r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 4);
if ($r === false) {
$photo_failure = true;
}
$img->scaleImage(80);
$r = $img->store($contact_id, $hash, $filename, t('Contact Photos'), 5);
if ($r === false) {
$photo_failure = true;
}
$photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
$thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';
} else {
$photo_failure = true;
}
if ($photo_failure) {
$photo = $a->get_baseurl() . '/images/default-profile.jpg';
$thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
}
$r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `rel` = %d,
`name-date` = '%s', `uri-date` = '%s', `avatar-date` = '%s',
`readonly` = %d, `profile-id` = %d, `blocked` = 0, `pending` = 0,
`network` = 'dfrn' WHERE `id` = %d LIMIT 1",
dbesc($photo),
dbesc($thumb),
intval(($relation == DIRECTION_OUT) ? DIRECTION_BOTH : DIRECTION_IN),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval((x($a->config, 'rockstar-readonly')) ? $a->config['rockstar-readonly'] : 0),
intval((x($a->config, 'rockstar-profile')) ? $a->config['rockstar-profile'] : 0),
intval($contact_id)
);
}
killme();

View file

@ -7,14 +7,12 @@
*/
function sync_pull($url)
{
global $a;
//If we support it that is.
if($a->config['syncing']['enable_pulling']){
q("INSERT INTO `sync-pull-queue` (`url`) VALUES ('%s')", dbesc($url));
}
global $a;
//If we support it that is.
if ($a->config['syncing']['enable_pulling']) {
q("INSERT INTO `sync-pull-queue` (`url`) VALUES ('%s')", dbesc($url));
}
}
/**
@ -24,16 +22,14 @@ function sync_pull($url)
*/
function sync_push($url)
{
global $a;
//If we support it that is.
if($a->config['syncing']['enable_pushing']){
q("INSERT INTO `sync-push-queue` (`url`) VALUES ('%s')", dbesc($url));
}
sync_mark($url);
global $a;
//If we support it that is.
if ($a->config['syncing']['enable_pushing']) {
q("INSERT INTO `sync-push-queue` (`url`) VALUES ('%s')", dbesc($url));
}
sync_mark($url);
}
/**
@ -44,21 +40,20 @@ function sync_push($url)
*/
function sync_mark($url)
{
global $a;
//If we support it that is.
if(!$a->config['syncing']['enable_pulling']){
return;
}
$exists = count(q("SELECT * FROM `sync-timestamps` WHERE `url`='%s'", dbesc($url)));
if(!$exists)
q("INSERT INTO `sync-timestamps` (`url`, `modified`) VALUES ('%s', NOW())", dbesc($url));
else
q("UPDATE `sync-timestamps` SET `modified`=NOW() WHERE `url`='%s'", dbesc($url));
global $a;
//If we support it that is.
if (!$a->config['syncing']['enable_pulling']) {
return;
}
$exists = count(q("SELECT * FROM `sync-timestamps` WHERE `url`='%s'", dbesc($url)));
if (!$exists) {
q("INSERT INTO `sync-timestamps` (`url`, `modified`) VALUES ('%s', NOW())", dbesc($url));
} else {
q("UPDATE `sync-timestamps` SET `modified`=NOW() WHERE `url`='%s'", dbesc($url));
}
}
/**
@ -70,27 +65,26 @@ function sync_mark($url)
*/
function push_worker($target, $batch)
{
//Lets be nice, we're only doing a background job here...
pcntl_setpriority(5);
//Find our target's submit URL.
$submit = $target['base_url'].'/submit';
foreach($batch as $item){
set_time_limit(30); //This should work for 1 submit.
msg("Submitting {$item['url']} to $submit");
fetch_url($submit.'?url='.bin2hex($item['url']));
}
//Lets be nice, we're only doing a background job here...
pcntl_setpriority(5);
//Find our target's submit URL.
$submit = $target['base_url'] . '/submit';
foreach ($batch as $item) {
set_time_limit(30); //This should work for 1 submit.
msg("Submitting {$item['url']} to $submit");
fetch_url($submit . '?url=' . bin2hex($item['url']));
}
}
/**
* Gets an array of push targets.
* @return array Push targets.
*/
function get_push_targets(){
return q("SELECT * FROM `sync-targets` WHERE `push`=b'1'");
function get_push_targets()
{
return q("SELECT * FROM `sync-targets` WHERE `push`=b'1'");
}
/**
@ -98,8 +92,9 @@ function get_push_targets(){
* @param object $a The App instance.
* @return array Batch of URL's.
*/
function get_push_batch($a){
return q("SELECT * FROM `sync-push-queue` LIMIT %u", intval($a->config['syncing']['max_push_items']));
function get_push_batch($a)
{
return q("SELECT * FROM `sync-push-queue` LIMIT %u", intval($a->config['syncing']['max_push_items']));
}
/**
@ -109,35 +104,31 @@ function get_push_batch($a){
*/
function get_pushing_job($a)
{
//When pushing is requested...
if(!!$a->config['syncing']['enable_pushing']){
//Find our targets.
$targets = get_push_targets();
//No targets?
if(!count($targets)){
msg('Pushing enabled, but no push targets.');
$batch = array();
}
//If we have targets, get our batch.
else{
$batch = get_push_batch($a);
if(!count($batch)) msg('Empty pushing queue.'); //No batch, means no work.
}
}
//When pushing is requested...
if (!!$a->config['syncing']['enable_pushing']) {
//No pushing if it's disabled.
else{
$targets = array();
$batch = array();
}
return array($targets, $batch);
//Find our targets.
$targets = get_push_targets();
//No targets?
if (!count($targets)) {
msg('Pushing enabled, but no push targets.');
$batch = array();
}
//If we have targets, get our batch.
else {
$batch = get_push_batch($a);
if (!count($batch))
msg('Empty pushing queue.'); //No batch, means no work.
}
} else {
//No pushing if it's disabled.
$targets = array();
$batch = array();
}
return array($targets, $batch);
}
/**
@ -153,74 +144,76 @@ function get_pushing_job($a)
*/
function run_pushing_job($targets, $batch, $db_host, $db_user, $db_pass, $db_data, $install)
{
//Create a thread for each target we want to serve push messages to.
//Not good creating more, because it would stress their server too much.
$threadc = count($targets);
$threads = array();
//Do we only have 1 target? No need for threads.
if($threadc === 1){
msg('No threads needed. Only one pushing target.');
push_worker($targets[0], $batch);
}
//When we need threads.
elseif($threadc > 1){
//POSIX threads only.
if(!function_exists('pcntl_fork')){
msg('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.', true);
}
//Debug...
$items = count($batch);
msg("Creating $threadc push threads for $items items.");
//Loop while we need more threads.
for($i = 0; $i < $threadc; $i++){
$pid = pcntl_fork();
if($pid === -1) msg('Error: something went wrong with the fork. '.pcntl_strerror(), true);
//You're a child, go do some labor!
if($pid === 0){push_worker($targets[$i], $batch); exit;}
//Store the list of PID's.
if($pid > 0) $threads[] = $pid;
}
}
//Wait for all child processes.
$theading_problems = false;
foreach($threads as $pid){
pcntl_waitpid($pid, $status);
if($status !== 0){
$theading_problems = true;
msg("Bad process return value $pid:$status");
}
}
//If we did not have any "threading" problems.
if(!$theading_problems){
//Reconnect
global $db;
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Create a query for deleting this queue.
$where = array();
foreach($batch as $item) $where[] = dbesc($item['url']);
$where = "WHERE `url` IN ('".implode("', '", $where)."')";
//Remove the items from queue.
q("DELETE FROM `sync-push-queue` $where LIMIT %u", count($batch));
msg('Removed items from push queue.');
}
//Create a thread for each target we want to serve push messages to.
//Not good creating more, because it would stress their server too much.
$threadc = count($targets);
$threads = array();
//Do we only have 1 target? No need for threads.
if ($threadc === 1) {
msg('No threads needed. Only one pushing target.');
push_worker($targets[0], $batch);
} elseif ($threadc > 1) {
//When we need threads.
//POSIX threads only.
if (!function_exists('pcntl_fork')) {
msg('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.', true);
}
//Debug...
$items = count($batch);
msg("Creating $threadc push threads for $items items.");
//Loop while we need more threads.
for ($i = 0; $i < $threadc; $i++) {
$pid = pcntl_fork();
if ($pid === -1)
msg('Error: something went wrong with the fork. ' . pcntl_strerror(), true);
//You're a child, go do some labor!
if ($pid === 0) {
push_worker($targets[$i], $batch);
exit;
}
//Store the list of PID's.
if ($pid > 0) {
$threads[] = $pid;
}
}
}
//Wait for all child processes.
$theading_problems = false;
foreach ($threads as $pid) {
pcntl_waitpid($pid, $status);
if ($status !== 0) {
$theading_problems = true;
msg("Bad process return value $pid:$status");
}
}
//If we did not have any "threading" problems.
if (!$theading_problems) {
//Reconnect
global $db;
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Create a query for deleting this queue.
$where = array();
foreach ($batch as $item) {
$where[] = dbesc($item['url']);
}
$where = "WHERE `url` IN ('" . implode("', '", $where) . "')";
//Remove the items from queue.
q("DELETE FROM `sync-push-queue` $where LIMIT %u", count($batch));
msg('Removed items from push queue.');
}
}
/**
@ -228,19 +221,21 @@ function run_pushing_job($targets, $batch, $db_host, $db_user, $db_pass, $db_dat
* @param object $a The App instance.
* @return array Batch of URL's.
*/
function get_queued_pull_batch($a){
//Randomize this, to prevent scraping the same servers too much or dead URL's.
$batch = q("SELECT * FROM `sync-pull-queue` ORDER BY RAND() LIMIT %u", intval($a->config['syncing']['max_pull_items']));
msg(sprintf('Pulling %u items from queue.', count($batch)));
return $batch;
function get_queued_pull_batch($a)
{
//Randomize this, to prevent scraping the same servers too much or dead URL's.
$batch = q("SELECT * FROM `sync-pull-queue` ORDER BY RAND() LIMIT %u", intval($a->config['syncing']['max_pull_items']));
msg(sprintf('Pulling %u items from queue.', count($batch)));
return $batch;
}
/**
* Gets an array of pull targets.
* @return array Pull targets.
*/
function get_pull_targets(){
return q("SELECT * FROM `sync-targets` WHERE `pull`=b'1'");
function get_pull_targets()
{
return q("SELECT * FROM `sync-targets` WHERE `pull`=b'1'");
}
/**
@ -250,57 +245,59 @@ function get_pull_targets(){
*/
function get_remote_pull_batch($a)
{
//Find our targets.
$targets = get_pull_targets();
msg(sprintf('Pulling from %u remote targets.', count($targets)));
//No targets, means no batch.
if(!count($targets))
return array();
//Pull a list of URL's from each target.
$urls = array();
foreach($targets as $i => $target){
//First pull, or an update?
if(!$target['dt_last_pull'])
$url = $target['base_url'].'/sync/pull/all';
else
$url = $target['base_url'].'/sync/pull/since/'.intval($target['dt_last_pull']);
//Go for it :D
$targets[$i]['pull_data'] = json_decode(fetch_url($url), true);
//If we didn't get any JSON.
if(!$targets[$i]['pull_data']){
msg(sprintf('Failed to pull from "%s".', $url));
continue;
}
//Add all entries as keys, to remove duplicates.
foreach($targets[$i]['pull_data']['results'] as $url)
$urls[$url]=true;
}
//Now that we have our URL's. Store them in the queue.
foreach($urls as $url=>$bool){
if($url) sync_pull($url);
}
//Since this all worked out, mark each source with the timestamp of pulling.
foreach($targets as $target){
if($target['pull_data'] && $target['pull_data']['now']){
msg('New pull timestamp '.$target['pull_data']['now'].' for '.$target['base_url']);
q("UPDATE `sync-targets` SET `dt_last_pull`=%u WHERE `base_url`='%s'", $target['pull_data']['now'], dbesc($target['base_url']));
}
}
//Finally, return a batch of this.
return get_queued_pull_batch($a);
//Find our targets.
$targets = get_pull_targets();
msg(sprintf('Pulling from %u remote targets.', count($targets)));
//No targets, means no batch.
if (!count($targets)) {
return array();
}
//Pull a list of URL's from each target.
$urls = array();
foreach ($targets as $i => $target) {
//First pull, or an update?
if (!$target['dt_last_pull']) {
$url = $target['base_url'] . '/sync/pull/all';
} else {
$url = $target['base_url'] . '/sync/pull/since/' . intval($target['dt_last_pull']);
}
//Go for it :D
$targets[$i]['pull_data'] = json_decode(fetch_url($url), true);
//If we didn't get any JSON.
if (!$targets[$i]['pull_data']) {
msg(sprintf('Failed to pull from "%s".', $url));
continue;
}
//Add all entries as keys, to remove duplicates.
foreach ($targets[$i]['pull_data']['results'] as $url) {
$urls[$url] = true;
}
}
//Now that we have our URL's. Store them in the queue.
foreach ($urls as $url => $bool) {
if ($url) {
sync_pull($url);
}
}
//Since this all worked out, mark each source with the timestamp of pulling.
foreach ($targets as $target) {
if ($target['pull_data'] && $target['pull_data']['now']) {
msg('New pull timestamp ' . $target['pull_data']['now'] . ' for ' . $target['base_url']);
q("UPDATE `sync-targets` SET `dt_last_pull`=%u WHERE `base_url`='%s'", $target['pull_data']['now'], dbesc($target['base_url']));
}
}
//Finally, return a batch of this.
return get_queued_pull_batch($a);
}
/**
@ -310,19 +307,22 @@ function get_remote_pull_batch($a)
*/
function get_pulling_job($a)
{
//No pulling today...
if(!$a->config['syncing']['enable_pulling'])
return array();
//Firstly, finish the items from our queue.
$batch = get_queued_pull_batch($a);
if(count($batch)) return $batch;
//If that is empty, fill the queue with remote items and return a batch of that.
$batch = get_remote_pull_batch($a);
if(count($batch)) return $batch;
//No pulling today...
if (!$a->config['syncing']['enable_pulling']) {
return array();
}
//Firstly, finish the items from our queue.
$batch = get_queued_pull_batch($a);
if (count($batch)) {
return $batch;
}
//If that is empty, fill the queue with remote items and return a batch of that.
$batch = get_remote_pull_batch($a);
if (count($batch)) {
return $batch;
}
}
/**
@ -340,30 +340,28 @@ function get_pulling_job($a)
*/
function pull_worker($i, $threadc, $pull_batch, $db_host, $db_user, $db_pass, $db_data, $install)
{
//Lets be nice, we're only doing maintenance here...
pcntl_setpriority(5);
//Get personal DBA's.
global $db;
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Get our (round-robin) workload from the batch.
$workload = array();
while(isset($pull_batch[$i])){
$entry = $pull_batch[$i];
$workload[] = $entry;
$i+=$threadc;
}
//While we've got work to do.
while(count($workload)){
$entry = array_pop($workload);
set_time_limit(20); //This should work for 1 submit.
msg("Submitting ".$entry['url']);
run_submit($entry['url']);
}
//Lets be nice, we're only doing maintenance here...
pcntl_setpriority(5);
//Get personal DBA's.
global $db;
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Get our (round-robin) workload from the batch.
$workload = array();
while (isset($pull_batch[$i])) {
$entry = $pull_batch[$i];
$workload[] = $entry;
$i += $threadc;
}
//While we've got work to do.
while (count($workload)) {
$entry = array_pop($workload);
set_time_limit(20); //This should work for 1 submit.
msg("Submitting " . $entry['url']);
run_submit($entry['url']);
}
}
/**
@ -379,62 +377,66 @@ function pull_worker($i, $threadc, $pull_batch, $db_host, $db_user, $db_pass, $d
*/
function run_pulling_job($a, $pull_batch, $db_host, $db_user, $db_pass, $db_data, $install)
{
//We need the scraper.
require_once('include/submit.php');
//POSIX threads only.
if(!function_exists('pcntl_fork')){
msg('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.', true);
}
//Create the threads we need.
$items = count($pull_batch);
$threadc = min($a->config['syncing']['pulling_threads'], $items); //Don't need more threads than items.
$threads = array();
msg("Creating $threadc pulling threads for $items profiles.");
//Build the threads.
for($i = 0; $i < $threadc; $i++){
$pid = pcntl_fork();
if($pid === -1) msg('Error: something went wrong with the fork. '.pcntl_strerror(), true);
//You're a child, go do some labor!
if($pid === 0){pull_worker($i, $threadc, $pull_batch, $db_host, $db_user, $db_pass, $db_data, $install); exit;}
//Store the list of PID's.
if($pid > 0) $threads[] = $pid;
}
//Wait for all child processes.
$theading_problems = false;
foreach($threads as $pid){
pcntl_waitpid($pid, $status);
if($status !== 0){
$theading_problems = true;
msg("Bad process return value $pid:$status");
}
}
//If we did not have any "threading" problems.
if(!$theading_problems){
//Reconnect
global $db;
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Create a query for deleting this queue.
$where = array();
foreach($pull_batch as $item) $where[] = dbesc($item['url']);
$where = "WHERE `url` IN ('".implode("', '", $where)."')";
//Remove the items from queue.
q("DELETE FROM `sync-pull-queue` $where LIMIT %u", count($pull_batch));
msg('Removed items from pull queue.');
}
//We need the scraper.
require_once 'include/submit.php';
//POSIX threads only.
if (!function_exists('pcntl_fork')) {
msg('Error: no pcntl_fork support. Are you running a different OS? Report an issue please.', true);
}
//Create the threads we need.
$items = count($pull_batch);
$threadc = min($a->config['syncing']['pulling_threads'], $items); //Don't need more threads than items.
$threads = array();
msg("Creating $threadc pulling threads for $items profiles.");
//Build the threads.
for ($i = 0; $i < $threadc; $i++) {
$pid = pcntl_fork();
if ($pid === -1) {
msg('Error: something went wrong with the fork. ' . pcntl_strerror(), true);
}
//You're a child, go do some labor!
if ($pid === 0) {
pull_worker($i, $threadc, $pull_batch, $db_host, $db_user, $db_pass, $db_data, $install);
exit;
}
//Store the list of PID's.
if ($pid > 0) {
$threads[] = $pid;
}
}
//Wait for all child processes.
$theading_problems = false;
foreach ($threads as $pid) {
pcntl_waitpid($pid, $status);
if ($status !== 0) {
$theading_problems = true;
msg("Bad process return value $pid:$status");
}
}
//If we did not have any "threading" problems.
if (!$theading_problems) {
//Reconnect
global $db;
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
//Create a query for deleting this queue.
$where = array();
foreach ($pull_batch as $item) {
$where[] = dbesc($item['url']);
}
$where = "WHERE `url` IN ('" . implode("', '", $where) . "')";
//Remove the items from queue.
q("DELETE FROM `sync-pull-queue` $where LIMIT %u", count($pull_batch));
msg('Removed items from pull queue.');
}
}