function diaspost_queue_hook(&$a, &$b) { $hostname = $a->get_hostname(); $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", dbesc(NETWORK_DIASPORA2)); if (!count($qi)) { return; } require_once 'include/queue_fn.php'; foreach ($qi as $x) { if ($x['network'] !== NETWORK_DIASPORA2) { continue; } logger('diaspost_queue: run'); $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid`\n\t\t\tWHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1", intval($x['cid'])); if (!count($r)) { continue; } $userdata = $r[0]; $diaspost_username = get_pconfig($userdata['uid'], 'diaspost', 'diaspost_username'); $diaspost_password = z_unobscure(get_pconfig($userdata['uid'], 'diaspost', 'diaspost_password')); $diaspost_url = get_pconfig($userdata['uid'], 'diaspost', 'diaspost_url'); $success = false; if ($diaspost_url && $diaspost_username && $diaspost_password) { require_once "addon/diaspost/diasphp.php"; logger('diaspost_queue: able to post for user ' . $diaspost_username); $z = unserialize($x['content']); $post = $z['post']; logger('diaspost_queue: post: ' . $post, LOGGER_DATA); try { logger('diaspost_queue: prepare', LOGGER_DEBUG); $conn = new Diasphp($diaspost_url); logger('diaspost_queue: try to log in ' . $diaspost_username, LOGGER_DEBUG); $conn->login($diaspost_username, $diaspost_password); logger('diaspost_queue: try to send ' . $body, LOGGER_DEBUG); $conn->post($post, $hostname); logger('diaspost_queue: send ' . $userdata['uid'] . ' success', LOGGER_DEBUG); $success = true; remove_queue_item($x['id']); } catch (Exception $e) { logger("diaspost_queue: Send " . $userdata['uid'] . " failed: " . $e->getMessage(), LOGGER_DEBUG); } } else { logger('diaspost_queue: send ' . $userdata['uid'] . ' missing username or password', LOGGER_DEBUG); } if (!$success) { logger('diaspost_queue: delayed'); update_queue_item($x['id']); } } }
public static function run($argc, $argv) { if ($argc < 2) { return; } logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA); for ($x = 1; $x < $argc; $x++) { if (!$argv[$x]) { continue; } $dresult = null; $r = q("select * from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); if ($r) { $notify = json_decode($r[0]['outq_notify'], true); // Messages without an outq_msg will need to go via the web, even if it's a // local delivery. This includes conversation requests and refresh packets. if ($r[0]['outq_posturl'] === z_root() . '/post' && $r[0]['outq_msg']) { logger('deliver: local delivery', LOGGER_DEBUG); // local delivery // we should probably batch these and save a few delivery processes if ($r[0]['outq_msg']) { $m = json_decode($r[0]['outq_msg'], true); if (array_key_exists('message_list', $m)) { foreach ($m['message_list'] as $mm) { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $mm))))); zot_import($msg, z_root()); } } else { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $m))))); $dresult = zot_import($msg, z_root()); } remove_queue_item($r[0]['outq_hash']); if ($dresult && is_array($dresult)) { foreach ($dresult as $xx) { if (is_array($xx) && array_key_exists('message_id', $xx)) { if (delivery_report_is_storable($xx)) { q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", dbesc($xx['message_id']), dbesc($xx['location']), dbesc($xx['recipient']), dbesc($xx['status']), dbesc(datetime_convert($xx['date'])), dbesc($xx['sender'])); } } } } q("delete from dreport where dreport_queue = '%s'", dbesc($argv[$x])); } } // otherwise it's a remote delivery - call queue_deliver() with the $immediate flag queue_deliver($r[0], true); } } }
function gnusoc_queue_deliver(&$a, &$b) { $outq = $b['outq']; if ($outq['outq_driver'] !== 'slap') { return; } $b['handled'] = true; $headers = array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($outq['outq_msg'])); $counter = 0; $result = z_post_url($outq['outq_posturl'], $outq['outq_msg'], $counter, array('headers' => $headers, 'novalidate' => true)); if ($result['success'] && $result['return_code'] < 300) { logger('slap_deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG); if ($b['base']) { q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", dbesc(datetime_convert()), dbesc($b['base'])); } q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1", dbesc('accepted for delivery'), dbesc(datetime_convert()), dbesc($outq['outq_hash'])); remove_queue_item($outq['outq_hash']); } else { logger('slap_deliver: queue post returned ' . $result['return_code'] . ' from ' . $outq['outq_posturl'], LOGGER_DEBUG); update_queue_item($outq['outq_hash']); } return; }
function gpluspost_queue_hook(&$a, &$b) { $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", dbesc(NETWORK_GPLUS)); if (!count($qi)) { return; } require_once 'include/queue_fn.php'; foreach ($qi as $x) { if ($x['network'] !== NETWORK_GPLUS) { continue; } logger('gpluspost_queue: run'); $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid` \n\t\t\tWHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1", intval($x['cid'])); if (!count($r)) { continue; } $userdata = $r[0]; //logger('gpluspost_queue: fetching userdata '.print_r($userdata, true)); $username = get_pconfig($userdata['uid'], 'gpluspost', 'username'); $password = get_pconfig($userdata['uid'], 'gpluspost', 'password'); $page = get_pconfig($userdata['uid'], 'gpluspost', 'page'); $success = false; if ($username && $password) { require_once "addon/gpluspost/postToGooglePlus.php"; logger('gpluspost_queue: able to post for user ' . $username); $z = unserialize($x['content']); $data = $z['post']; // $z['url'] logger('gpluspost_send: data: ' . print_r($data, true), LOGGER_DATA); $loginError = doConnectToGooglePlus2($username, $password); if (!$loginError) { if ($data["url"] != "") { $lnk = doGetGoogleUrlInfo2($data["url"]); } elseif ($data["image"] != "") { $lnk = array('img' => $data["image"]); } else { $lnk = ""; } // Send a special blank to identify the post through the "fromgplus" addon $blank = html_entity_decode(" ", ENT_QUOTES, 'UTF-8'); doPostToGooglePlus2($data["text"] . $blank, $lnk, $page); logger('gpluspost_queue: send ' . $userdata['uid'] . ' success', LOGGER_DEBUG); $success = true; remove_queue_item($x['id']); } else { logger('gpluspost_queue: send ' . $userdata['uid'] . ' failed ' . $loginError, LOGGER_DEBUG); } } else { logger('gpluspost_queue: send ' . $userdata['uid'] . ' missing username or password', LOGGER_DEBUG); } if (!$success) { logger('gpluspost_queue: delayed'); update_queue_time($x['id']); } } }
function pumpio_queue_hook(&$a, &$b) { $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", dbesc(NETWORK_PUMPIO)); if (!count($qi)) { return; } require_once 'include/queue_fn.php'; foreach ($qi as $x) { if ($x['network'] !== NETWORK_PUMPIO) { continue; } logger('pumpio_queue: run'); $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid` \n\t\t\tWHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1", intval($x['cid'])); if (!count($r)) { continue; } $userdata = $r[0]; //logger('pumpio_queue: fetching userdata '.print_r($userdata, true)); $oauth_token = get_pconfig($userdata['uid'], "pumpio", "oauth_token"); $oauth_token_secret = get_pconfig($userdata['uid'], "pumpio", "oauth_token_secret"); $consumer_key = get_pconfig($userdata['uid'], "pumpio", "consumer_key"); $consumer_secret = get_pconfig($userdata['uid'], "pumpio", "consumer_secret"); $host = get_pconfig($userdata['uid'], "pumpio", "host"); $user = get_pconfig($userdata['uid'], "pumpio", "user"); $success = false; if ($oauth_token and $oauth_token_secret and $consumer_key and $consumer_secret) { $username = $user . '@' . $host; logger('pumpio_queue: able to post for user ' . $username); $z = unserialize($x['content']); $client = new oauth_client_class(); $client->oauth_version = '1.0a'; $client->url_parameters = false; $client->authorization_header = true; $client->access_token = $oauth_token; $client->access_token_secret = $oauth_token_secret; $client->client_id = $consumer_key; $client->client_secret = $consumer_secret; if (pumpio_reachable($z['url'])) { $success = $client->CallAPI($z['url'], 'POST', $z['post'], array('FailOnAccessError' => true, 'RequestContentType' => 'application/json'), $user); } else { $success = false; } if ($success) { $post_id = $user->object->id; logger('pumpio_queue: send ' . $username . ': success ' . $post_id); if ($post_id and $iscomment) { logger('pumpio_send ' . $username . ': Update extid ' . $post_id . " for post id " . $z['item']); q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d", dbesc($post_id), intval($z['item'])); } remove_queue_item($x['id']); } else { logger('pumpio_queue: send ' . $username . ': ' . $url . ' general error: ' . print_r($user, true)); } } else { logger("pumpio_queue: Error getting tokens for user " . $userdata['uid']); } if (!$success) { logger('pumpio_queue: delayed'); update_queue_time($x['id']); } } }
function zot_reply_pickup($data) { $ret = array('success' => false); /* * The 'pickup' message arrives with a tracking ID which is associated with a particular outq_hash * First verify that that the returned signatures verify, then check that we have an outbound queue item * with the correct hash. * If everything verifies, find any/all outbound messages in the queue for this hubloc and send them back */ if (!$data['secret'] || !$data['secret_sig']) { $ret['message'] = 'no verification signature'; logger('mod_zot: pickup: ' . $ret['message'], LOGGER_DEBUG); json_return_and_die($ret); } $r = q("select distinct hubloc_sitekey from hubloc where hubloc_url = '%s' and hubloc_callback = '%s' and hubloc_sitekey != '' group by hubloc_sitekey ", dbesc($data['url']), dbesc($data['callback'])); if (!$r) { $ret['message'] = 'site not found'; logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } foreach ($r as $hubsite) { // verify the url_sig // If the server was re-installed at some point, there could be multiple hubs with the same url and callback. // Only one will have a valid key. $forgery = true; $secret_fail = true; $sitekey = $hubsite['hubloc_sitekey']; logger('mod_zot: Checking sitekey: ' . $sitekey, LOGGER_DATA, LOG_DEBUG); if (rsa_verify($data['callback'], base64url_decode($data['callback_sig']), $sitekey)) { $forgery = false; } if (rsa_verify($data['secret'], base64url_decode($data['secret_sig']), $sitekey)) { $secret_fail = false; } if (!$forgery && !$secret_fail) { break; } } if ($forgery) { $ret['message'] = 'possible site forgery'; logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } if ($secret_fail) { $ret['message'] = 'secret validation failed'; logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } /* * If we made it to here, the signatures verify, but we still don't know if the tracking ID is valid. * It wouldn't be an error if the tracking ID isn't found, because we may have sent this particular * queue item with another pickup (after the tracking ID for the other pickup was verified). */ $r = q("select outq_posturl from outq where outq_hash = '%s' and outq_posturl = '%s' limit 1", dbesc($data['secret']), dbesc($data['callback'])); if (!$r) { $ret['message'] = 'nothing to pick up'; logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } /* * Everything is good if we made it here, so find all messages that are going to this location * and send them all. */ $r = q("select * from outq where outq_posturl = '%s'", dbesc($data['callback'])); if ($r) { logger('mod_zot: successful pickup message received from ' . $data['callback'] . ' ' . count($r) . ' message(s) picked up', LOGGER_DEBUG); $ret['success'] = true; $ret['pickup'] = array(); foreach ($r as $rr) { if ($rr['outq_msg']) { $x = json_decode($rr['outq_msg'], true); if (!$x) { continue; } if (is_array($x) && array_key_exists('message_list', $x)) { foreach ($x['message_list'] as $xx) { $ret['pickup'][] = array('notify' => json_decode($rr['outq_notify'], true), 'message' => $xx); } } else { $ret['pickup'][] = array('notify' => json_decode($rr['outq_notify'], true), 'message' => $x); } remove_queue_item($rr['outq_hash']); } } } $encrypted = crypto_encapsulate(json_encode($ret), $sitekey); json_return_and_die($encrypted); /* pickup: end */ }
function twitter_queue_hook(&$a, &$b) { $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", dbesc(NETWORK_TWITTER)); if (!count($qi)) { return; } require_once 'include/queue_fn.php'; foreach ($qi as $x) { if ($x['network'] !== NETWORK_TWITTER) { continue; } logger('twitter_queue: run'); $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid` \n\t\t\tWHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1", intval($x['cid'])); if (!count($r)) { continue; } $user = $r[0]; $ckey = get_config('twitter', 'consumerkey'); $csecret = get_config('twitter', 'consumersecret'); $otoken = get_pconfig($user['uid'], 'twitter', 'oauthtoken'); $osecret = get_pconfig($user['uid'], 'twitter', 'oauthsecret'); $success = false; if ($ckey and $csecret and $otoken and $osecret) { logger('twitter_queue: able to post'); $z = unserialize($x['content']); require_once "addon/twitter/codebird.php"; $cb = \Codebird\Codebird::getInstance(); $cb->setConsumerKey($ckey, $csecret); $cb->setToken($otoken, $osecret); if ($z['url'] == "statuses/update") { $result = $cb->statuses_update($z['post']); } logger('twitter_queue: post result: ' . print_r($result, true), LOGGER_DEBUG); if ($result->errors) { logger('twitter_queue: Send to Twitter failed: "' . print_r($result->errors, true) . '"'); } else { $success = true; remove_queue_item($x['id']); } } else { logger("twitter_queue: Error getting tokens for user " . $user['uid']); } if (!$success) { logger('twitter_queue: delayed'); update_queue_time($x['id']); } } }
function statusnet_queue_deliver(&$a, &$b) { $outq = $b['outq']; if ($outq['outq_driver'] !== 'statusnet') { return; } $ckey = get_pconfig($outq['outq_channel'], 'statusnet', 'consumerkey'); $csecret = get_pconfig($outq['outq_channel'], 'statusnet', 'consumersecret'); $otoken = get_pconfig($outq['outq_channel'], 'statusnet', 'oauthtoken'); $osecret = get_pconfig($outq['outq_channel'], 'statusnet', 'oauthsecret'); if ($ckey && $csecret && $otoken && $osecret) { $dent = new StatusNetOAuth($api, $ckey, $csecret, $otoken, $osecret); if ($outq['outq_msg']) { $result = $dent->post('statuses/update', array('status' => $outq['outq_msg'])); if ($result->error) { logger('Send to GNU social failed: "' . $result->error . '"'); update_queue_item($outq['outq_hash']); } else { logger('statusnet_post send, result: ' . print_r($result, true) . "\nmessage: " . $outq['outq_msg'], LOGGER_DEBUG); remove_queue_item($outq['outq_hash']); } } } $b['handled'] = true; }
function push_queue_deliver(&$a, &$b) { $outq = $b['outq']; if ($outq['outq_driver'] !== 'push') { return; } $b['handled'] = true; $m = json_decode($outq['outq_msg'], true); if ($m) { $headers = array("Content-type: application/atom+xml", sprintf("Link: <%s>;rel=hub,<%s>;rel=self", z_root() . '/pubsubhubbub', $m['topic']), "X-Hub-Signature: sha1=" . $m['sig']); $counter = 0; $result = z_post_url($outq['outq_posturl'], $m['body'], $counter, array('headers' => $headers, 'novalidate' => true)); if ($result['success'] && $result['return_code'] < 300) { logger('push_deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG); if ($b['base']) { q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", dbesc(datetime_convert()), dbesc($b['base'])); } q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1", dbesc('accepted for delivery'), dbesc(datetime_convert()), dbesc($outq['outq_hash'])); q("update push_subscriber set last_update = '%s' where callback_url = '%s' and topic = '%s'", dbesc(datetime_convert()), dbesc($outq['outq_posturl']), dbesc($m['topic'])); remove_queue_item($outq['outq_hash']); } else { logger('push_deliver: queue post returned ' . $result['return_code'] . ' from ' . $outq['outq_posturl'], LOGGER_DEBUG); update_queue_item($outq['outq_hash']); } return; } }
function queue_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/items.php'; require_once 'include/bbcode.php'; require_once 'include/pidfile.php'; require_once 'include/socgraph.php'; load_config('config'); load_config('system'); $lockpath = get_lockpath(); if ($lockpath != '') { $pidfile = new pidfile($lockpath, 'queue'); if ($pidfile->is_already_running()) { logger("queue: Already running"); if ($pidfile->running_time() > 9 * 60) { $pidfile->kill(); logger("queue: killed stale process"); // Calling a new instance proc_run('php', "include/queue.php"); } return; } } $a->set_baseurl(get_config('system', 'url')); load_hooks(); if ($argc > 1) { $queue_id = intval($argv[1]); } else { $queue_id = 0; } $deadguys = array(); logger('queue: start'); // Handling the pubsubhubbub requests proc_run('php', 'include/pubsubpublish.php'); $interval = get_config('system', 'delivery_interval') === false ? 2 : intval(get_config('system', 'delivery_interval')); // If we are using the worker we don't need a delivery interval if (get_config("system", "worker")) { $interval = false; } $r = q("select * from deliverq where 1"); if ($r) { foreach ($r as $rr) { logger('queue: deliverq'); proc_run('php', 'include/delivery.php', $rr['cmd'], $rr['item'], $rr['contact']); if ($interval) { @time_sleep_until(microtime(true) + (double) $interval); } } } $r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue`\n\t\tINNER JOIN `contact` ON `queue`.`cid` = `contact`.`id`\n\t\tWHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); if ($r) { foreach ($r as $rr) { logger('Removing expired queue item for ' . $rr['name'] . ', uid=' . $rr['uid']); logger('Expired queue data :' . $rr['content'], LOGGER_DATA); } q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); } if ($queue_id) { $r = q("SELECT `id` FROM `queue` WHERE `id` = %d LIMIT 1", intval($queue_id)); } else { // For the first 12 hours we'll try to deliver every 15 minutes // After that, we'll only attempt delivery once per hour. $r = q("SELECT `id` FROM `queue` WHERE (( `created` > UTC_TIMESTAMP() - INTERVAL 12 HOUR && `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ) OR ( `last` < UTC_TIMESTAMP() - INTERVAL 1 HOUR ))"); } if (!$r) { return; } if (!$queue_id) { call_hooks('queue_predeliver', $a, $r); } // delivery loop require_once 'include/salmon.php'; require_once 'include/diaspora.php'; foreach ($r as $q_item) { // queue_predeliver hooks may have changed the queue db details, // so check again if this entry still needs processing if ($queue_id) { $qi = q("select * from queue where `id` = %d limit 1", intval($queue_id)); } else { $qi = q("SELECT * FROM `queue` WHERE `id` = %d AND `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ", intval($q_item['id'])); } if (!count($qi)) { continue; } $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($qi[0]['cid'])); if (!count($c)) { remove_queue_item($q_item['id']); continue; } if (in_array($c[0]['notify'], $deadguys)) { logger('queue: skipping known dead url: ' . $c[0]['notify']); update_queue_time($q_item['id']); continue; } if (!poco_reachable($c[0]['url'])) { logger('queue: skipping probably dead url: ' . $c[0]['url']); update_queue_time($q_item['id']); continue; } $u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`\n\t\t\tFROM `user` WHERE `uid` = %d LIMIT 1", intval($c[0]['uid'])); if (!count($u)) { remove_queue_item($q_item['id']); continue; } $data = $qi[0]['content']; $public = $qi[0]['batch']; $contact = $c[0]; $owner = $u[0]; $deliver_status = 0; switch ($contact['network']) { case NETWORK_DFRN: logger('queue: dfrndelivery: item ' . $q_item['id'] . ' for ' . $contact['name']); $deliver_status = dfrn_deliver($owner, $contact, $data); if ($deliver_status == -1) { update_queue_time($q_item['id']); $deadguys[] = $contact['notify']; } else { remove_queue_item($q_item['id']); } break; case NETWORK_OSTATUS: if ($contact['notify']) { logger('queue: slapdelivery: item ' . $q_item['id'] . ' for ' . $contact['name']); $deliver_status = slapper($owner, $contact['notify'], $data); if ($deliver_status == -1) { update_queue_time($q_item['id']); } else { remove_queue_item($q_item['id']); } } break; case NETWORK_DIASPORA: if ($contact['notify']) { logger('queue: diaspora_delivery: item ' . $q_item['id'] . ' for ' . $contact['name']); $deliver_status = diaspora_transmit($owner, $contact, $data, $public, true); if ($deliver_status == -1) { update_queue_time($q_item['id']); } else { remove_queue_item($q_item['id']); } } break; default: $params = array('owner' => $owner, 'contact' => $contact, 'queue' => $q_item, 'result' => false); call_hooks('queue_deliver', $a, $params); if ($params['result']) { remove_queue_item($q_item['id']); } else { update_queue_time($q_item['id']); } break; } } return; }
function queue_deliver($outq, $immediate = false) { $base = null; $h = parse_url($outq['outq_posturl']); if ($h) { $base = $h['scheme'] . '://' . $h['host'] . ($h['port'] ? ':' . $h['port'] : ''); } if ($base && $base !== z_root() && $immediate) { $y = q("select site_update, site_dead from site where site_url = '%s' ", dbesc($base)); if ($y) { if (intval($y[0]['site_dead'])) { remove_queue_by_posturl($outq['outq_posturl']); logger('dead site ignored ' . $base); return; } if ($y[0]['site_update'] < datetime_convert('UTC', 'UTC', 'now - 1 month')) { update_queue_item($outq['outq_hash'], 10); logger('immediate delivery deferred for site ' . $base); return; } } else { // zot sites should all have a site record, unless they've been dead for as long as // your site has existed. Since we don't know for sure what these sites are, // call them unknown q("insert into site (site_url, site_update, site_dead, site_type) values ('%s','%s',0,%d) ", dbesc($base), dbesc(datetime_convert()), intval($outq['outq_driver'] === 'post' ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN)); } } $arr = array('outq' => $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate); call_hooks('queue_deliver', $arr); if ($arr['handled']) { return; } // "post" queue driver - used for diaspora and friendica-over-diaspora communications. if ($outq['outq_driver'] === 'post') { $result = z_post_url($outq['outq_posturl'], $outq['outq_msg']); if ($result['success'] && $result['return_code'] < 300) { logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG); if ($base) { q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", dbesc(datetime_convert()), dbesc($base)); } q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1", dbesc('accepted for delivery'), dbesc(datetime_convert()), dbesc($outq['outq_hash'])); remove_queue_item($outq['outq_hash']); // server is responding - see if anything else is going to this destination and is piled up // and try to send some more. We're relying on the fact that delivery_loop() results in an // immediate delivery otherwise we could get into a queue loop. if (!$immediate) { $x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0", dbesc($outq['outq_posturl'])); $piled_up = array(); if ($x) { foreach ($x as $xx) { $piled_up[] = $xx['outq_hash']; } } if ($piled_up) { delivery_loop($piled_up); } } } else { logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $outq['outq_posturl'], LOGGER_DEBUG); update_queue_item($outq['outq_posturl']); } return; } // normal zot delivery logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG); $result = zot_zot($outq['outq_posturl'], $outq['outq_notify']); if ($result['success']) { logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']); zot_process_response($outq['outq_posturl'], $result, $outq); } else { logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']); logger('deliver: remote zot delivery fail data: ' . print_r($result, true), LOGGER_DATA); update_queue_item($outq['outq_hash'], 10); } return; }
/** * @param App $a * @param object $b */ function fbpost_queue_hook(&$a, &$b) { $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", dbesc(NETWORK_FACEBOOK)); if (!count($qi)) { return; } require_once 'include/queue_fn.php'; foreach ($qi as $x) { if ($x['network'] !== NETWORK_FACEBOOK) { continue; } logger('fbpost_queue_hook: run'); $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid` \n\t\t\tWHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1", intval($x['cid'])); if (!count($r)) { logger('fbpost_queue_hook: no user found for entry ' . print_r($x, true)); update_queue_time($x['id']); continue; } $user = $r[0]; $appid = get_config('facebook', 'appid'); $secret = get_config('facebook', 'appsecret'); if ($appid && $secret) { $fb_post = intval(get_pconfig($user['uid'], 'facebook', 'post')); $fb_token = get_pconfig($user['uid'], 'facebook', 'access_token'); if ($fb_post && $fb_token) { logger('fbpost_queue_hook: able to post'); require_once 'library/facebook.php'; $z = unserialize($x['content']); $item = $z['item']; $j = post_url($z['url'], $z['post']); $retj = json_decode($j); if ($retj->id) { // Only set the extid when it isn't the toplevel post q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d AND `parent` != %d", dbesc('fb::' . $retj->id), intval($item), intval($item)); logger('fbpost_queue_hook: success: ' . $j); remove_queue_item($x['id']); } else { logger('fbpost_queue_hook: failed: ' . $j); // If it is a special kind of failure the post was receiced // Although facebook said it wasn't received ... $ret = json_decode($j); if ($ret->error->type != "OAuthException" or $ret->error->code != 2 and $j != "") { update_queue_time($x['id']); } else { logger('fbpost_queue_hook: Not requeued, since it seems to be received'); } } } else { logger('fbpost_queue_hook: No fb_post or fb_token.'); update_queue_time($x['id']); } } else { logger('fbpost_queue_hook: No appid or secret.'); update_queue_time($x['id']); } } }
function queue_run($argv, $argc) { global $a, $db; if (is_null($a)) { $a = new App(); } if (is_null($db)) { @(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 "session.php"; require_once "datetime.php"; require_once 'include/items.php'; require_once 'include/bbcode.php'; load_config('config'); load_config('system'); $a->set_baseurl(get_config('system', 'url')); load_hooks(); if ($argc > 1) { $queue_id = intval($argv[1]); } else { $queue_id = 0; } $deadguys = array(); logger('queue: start'); $interval = get_config('system', 'delivery_interval') === false ? 2 : intval(get_config('system', 'delivery_interval')); $r = q("select * from deliverq where 1"); if (count($r)) { foreach ($r as $rr) { logger('queue: deliverq'); proc_run('php', 'include/delivery.php', $rr['cmd'], $rr['item'], $rr['contact']); if ($interval) { @time_sleep_until(microtime(true) + (double) $interval); } } } $r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue` \n\t\tLEFT JOIN `contact` ON `queue`.`cid` = `contact`.`id` \n\t\tWHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); if (count($r)) { foreach ($r as $rr) { logger('Removing expired queue item for ' . $rr['name'] . ', uid=' . $rr['uid']); logger('Expired queue data :' . $rr['content'], LOGGER_DATA); } q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); } if ($queue_id) { $r = q("SELECT `id` FROM `queue` WHERE `id` = %d LIMIT 1", intval($queue_id)); } else { $r = q("SELECT `id` FROM `queue` WHERE `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE "); } if (!count($r)) { return; } if (!$queue_id) { call_hooks('queue_predeliver', $a, $r); } // delivery loop require_once 'include/salmon.php'; require_once 'include/diaspora.php'; foreach ($r as $q_item) { // queue_predeliver hooks may have changed the queue db details, // so check again if this entry still needs processing if ($queue_id) { $qi = q("select * from queue where `id` = %d limit 1", intval($queue_id)); } else { $qi = q("SELECT * FROM `queue` WHERE `id` = %d AND `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ", intval($q_item['id'])); } if (!count($qi)) { continue; } $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($qi[0]['cid'])); if (!count($c)) { remove_queue_item($q_item['id']); continue; } if (in_array($c[0]['notify'], $deadguys)) { logger('queue: skipping known dead url: ' . $c[0]['notify']); update_queue_time($q_item['id']); continue; } $u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey` \n\t\t\tFROM `user` WHERE `uid` = %d LIMIT 1", intval($c[0]['uid'])); if (!count($u)) { remove_queue_item($q_item['id']); continue; } $data = $qi[0]['content']; $public = $qi[0]['batch']; $contact = $c[0]; $owner = $u[0]; $deliver_status = 0; switch ($contact['network']) { case NETWORK_DFRN: logger('queue: dfrndelivery: item ' . $q_item['id'] . ' for ' . $contact['name']); $deliver_status = dfrn_deliver($owner, $contact, $data); if ($deliver_status == -1) { update_queue_time($q_item['id']); $deadguys[] = $contact['notify']; } else { remove_queue_item($q_item['id']); } break; case NETWORK_OSTATUS: if ($contact['notify']) { logger('queue: slapdelivery: item ' . $q_item['id'] . ' for ' . $contact['name']); $deliver_status = slapper($owner, $contact['notify'], $data); if ($deliver_status == -1) { update_queue_time($q_item['id']); } else { remove_queue_item($q_item['id']); } } break; case NETWORK_DIASPORA: if ($contact['notify']) { logger('queue: diaspora_delivery: item ' . $q_item['id'] . ' for ' . $contact['name']); $deliver_status = diaspora_transmit($owner, $contact, $data, $public); if ($deliver_status == -1) { update_queue_time($q_item['id']); } else { remove_queue_item($q_item['id']); } } break; default: $params = array('owner' => $owner, 'contact' => $contact, 'queue' => $q_item, 'result' => false); call_hooks('queue_deliver', $a, $params); if ($params['result']) { remove_queue_item($q_item['id']); } else { update_queue_time($q_item['id']); } break; } } return; }
/** * @param App $a * @param object $b */ function fb_queue_hook(&$a, &$b) { $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", dbesc(NETWORK_FACEBOOK)); if (!count($qi)) { return; } require_once 'include/queue_fn.php'; foreach ($qi as $x) { if ($x['network'] !== NETWORK_FACEBOOK) { continue; } logger('facebook_queue: run'); $r = q("SELECT `user`.* FROM `user` LEFT JOIN `contact` on `contact`.`uid` = `user`.`uid` \n\t\t\tWHERE `contact`.`self` = 1 AND `contact`.`id` = %d LIMIT 1", intval($x['cid'])); if (!count($r)) { continue; } $user = $r[0]; $appid = get_config('facebook', 'appid'); $secret = get_config('facebook', 'appsecret'); if ($appid && $secret) { $fb_post = intval(get_pconfig($user['uid'], 'facebook', 'post')); $fb_token = get_pconfig($user['uid'], 'facebook', 'access_token'); if ($fb_post && $fb_token) { logger('facebook_queue: able to post'); require_once 'library/facebook.php'; $z = unserialize($x['content']); $item = $z['item']; $j = post_url($z['url'], $z['post']); $retj = json_decode($j); if ($retj->id) { q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d LIMIT 1", dbesc('fb::' . $retj->id), intval($item)); logger('facebook_queue: success: ' . $j); remove_queue_item($x['id']); } else { logger('facebook_queue: failed: ' . $j); update_queue_time($x['id']); } } } } }