diff options
Diffstat (limited to 'include/notifier.php')
-rw-r--r-- | include/notifier.php | 235 |
1 files changed, 107 insertions, 128 deletions
diff --git a/include/notifier.php b/include/notifier.php index ecd2ac86f..34a527e15 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -96,14 +96,25 @@ function notifier_run($argv, $argc){ require_once('include/identity.php'); $sys = get_sys_channel(); - if($cmd == 'permission_update') { + $deliveries = array(); + + $dead_hubs = array(); + + $dh = q("select site_url from site where site_dead = 1"); + if(dh) { + foreach($dh as $dead) { + $dead_hubs[] = $dead['site_url']; + } + } + + + if($cmd == 'permission_update' || $cmd == 'permission_create') { // Get the recipient $r = q("select abook.*, hubloc.* from abook left join hubloc on hubloc_hash = abook_xchan - where abook_id = %d and not ( abook_flags & %d ) > 0 + where abook_id = %d and abook_self = 0 and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0 limit 1", intval($item_id), - intval(ABOOK_FLAG_SELF), intval(HUBLOC_FLAGS_DELETED), intval(HUBLOC_OFFLINE) ); @@ -114,11 +125,17 @@ function notifier_run($argv, $argc){ intval($r[0]['abook_channel']) ); if($s) { - if($r[0]['hubloc_network'] === 'diaspora' || $r[0]['hubloc_network'] === 'friendica-over-diaspora') { - require_once('include/diaspora.php'); - diaspora_share($s[0],$r[0]); - } - else { + $perm_update = array('sender' => $s[0], 'recipient' => $r[0], 'success' => false, 'deliveries' => ''); + + if($cmd == 'permission_create') + call_hooks('permissions_create',$perm_update); + else + call_hooks('permissions_update',$perm_update); + + if($perm_update['success'] && $perm_update['deliveries']) + $deliveries[] = $perm_update['deliveries']; + + if(! $perm_update['success']) { // send a refresh message to each hub they have registered here $h = q("select * from hubloc where hubloc_hash = '%s' and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0", @@ -128,36 +145,40 @@ function notifier_run($argv, $argc){ ); if($h) { foreach($h as $hh) { + if(in_array($hh['hubloc_url'],$dead_hubs)) { + logger('skipping dead hub: ' . $hh['hubloc_url'], LOGGER_DEBUG); + continue; + } + $data = zot_build_packet($s[0],'refresh',array(array( 'guid' => $hh['hubloc_guid'], 'guid_sig' => $hh['hubloc_guid_sig'], 'url' => $hh['hubloc_url']) )); if($data) { - $result = zot_zot($hh['hubloc_callback'],$data); - - // if immediate delivery failed, stick it in the queue to try again later. - - if(! $result['success']) { - $hash = random_string(); - q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) - values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", - dbesc($hash), - intval($s[0]['channel_account_id']), - intval($s[0]['channel_id']), - dbesc('zot'), - dbesc($hh['hubloc_callback']), - intval(1), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc($data), - dbesc('') - ); - } + $hash = random_string(); + q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) + values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", + dbesc($hash), + intval($s[0]['channel_account_id']), + intval($s[0]['channel_id']), + dbesc('zot'), + dbesc($hh['hubloc_callback']), + intval(1), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($data), + dbesc('') + ); + $deliveries[] = $hash; } - } + } + } } + + if($deliveries) + do_delivery($deliveries); } } return; @@ -228,11 +249,9 @@ function notifier_run($argv, $argc){ $normal_mode = false; $expire = true; - $items = q("SELECT * FROM item WHERE uid = %d AND ( item_flags & %d )>0 - AND ( item_restrict & %d )>0 AND `changed` > %s - INTERVAL %s", + $items = q("SELECT * FROM item WHERE uid = %d AND item_wall = 1 + AND item_deleted = 1 AND `changed` > %s - INTERVAL %s", intval($item_id), - intval(ITEM_WALL), - intval(ITEM_DELETED), db_utcnow(), db_quoteinterval('10 MINUTE') ); $uid = $item_id; @@ -338,19 +357,22 @@ function notifier_run($argv, $argc){ $target_item = $r[0]; $deleted_item = false; - if($target_item['item_restrict'] & ITEM_DELETED) { + if(intval($target_item['item_deleted'])) { logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG); $deleted_item = true; } - if(strpos($target_item['postopts'],'nodeliver') !== false) { - logger('notifier: target item is undeliverable', LOGGER_DEBUG); + if(intval($target_item['item_type']) != ITEM_TYPE_POST) { + logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG); + return; + } + if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed'])) { + logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG); return; } - $unforwardable = ITEM_UNPUBLISHED|ITEM_DELAYED_PUBLISH|ITEM_WEBPAGE|ITEM_BUILDBLOCK|ITEM_PDL; - if($target_item['item_restrict'] & $unforwardable) { - logger('notifier: target item not forwardable: flags ' . $target_item['item_restrict'], LOGGER_DEBUG); + if(strpos($target_item['postopts'],'nodeliver') !== false) { + logger('notifier: target item is undeliverable', LOGGER_DEBUG); return; } @@ -407,10 +429,7 @@ function notifier_run($argv, $argc){ // flag on comments for an extended period. So we'll also call comment_local_origin() which looks at // the hostname in the message_id and provides a second (fallback) opinion. - $relay_to_owner = (((! $top_level_post) && ($target_item['item_flags'] & ITEM_ORIGIN) && comment_local_origin($target_item)) - ? true - : false - ); + $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false); @@ -421,11 +440,10 @@ function notifier_run($argv, $argc){ logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA); logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA); - logger('notifier: target_item_flags: ' . $target_item['item_flags'] . ' ' . (($target_item['item_flags'] & ITEM_ORIGIN ) ? 'true' : 'false'), LOGGER_DATA); // tag_deliver'd post which needs to be sent back to the original author - if(($cmd === 'uplink') && ($parent_item['item_flags'] & ITEM_UPLINK) && (! $top_level_post)) { + if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) { logger('notifier: uplink'); $uplink = true; } @@ -446,7 +464,7 @@ function notifier_run($argv, $argc){ // if our parent is a tag_delivery recipient, uplink to the original author causing // a delivery fork. - if(($parent_item['item_flags'] & ITEM_UPLINK) && (! $top_level_post) && ($cmd !== 'uplink')) { + if(intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) { logger('notifier: uplinking this item'); proc_run('php','include/notifier.php','uplink',$item_id); } @@ -459,7 +477,7 @@ function notifier_run($argv, $argc){ // don't send deletions onward for other people's stuff // TODO verify this is needed - copied logic from same place in old code - if(($target_item['item_restrict'] & ITEM_DELETED) && (!($target_item['item_flags'] & ITEM_WALL))) { + if(intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) { logger('notifier: ignoring delete notification for non-wall item'); return; } @@ -492,20 +510,6 @@ function notifier_run($argv, $argc){ if($details) { foreach($details as $d) { - // If the recipient is federated from a traditional network they won't be able to - // handle nomadic identity. If we're publishing from a site that they aren't - // directly connected with, ignore them. - - // FIXME: make sure we run through a notifier loop on the hub they're connected - // with if this post comes in from a different hub - so that we will deliver to them. - - // On the down side, these channels will stop working if the hub they connected with - // goes down permanently, as they are (doh) not nomadic. - - if(($d['xchan_instance_url']) && ($d['xchan_instance_url'] != z_root())) - continue; - - $recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')'; if($private) $env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']); @@ -532,34 +536,10 @@ function notifier_run($argv, $argc){ // Now we have collected recipients (except for external mentions, FIXME) // Let's reduce this to a set of hubs. - logger('notifier: hub choice: ' . intval($relay_to_owner) . ' ' . intval($private) . ' ' . $cmd, LOGGER_DEBUG); - - // FIXME: I think we need to remove the private bit or this clause will never execute. Needs more coffee to think it through. - // We may in fact have to send it to clones in case the one we pick recently died. - - if($relay_to_owner && (! $private) && ($cmd !== 'relay')) { - - // If sending a followup to the post owner, only send it to one channel clone - to avoid race conditions. - // In this case we'll pick the most recently contacted hub, as their primary might be down and the most - // recently contacted has the best chance of being alive. - - // For private posts or uplinks we have to do things differently as only the sending clone will have the recipient list. - // We have to send to all clone channels of the owner to find out who has the definitive list. Posts with - // item_private set (but no ACL list) will return empty recipients (except for the sender and owner) in - // collect_recipients() above. The end result is we should get only one delivery per delivery chain if we - // aren't the owner or author. - - - $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") order by hubloc_connected desc limit 1"); - } - else { - $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0", - intval(HUBLOC_FLAGS_DELETED), - intval(HUBLOC_OFFLINE) - ); - } + $r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ") + and hubloc_error = 0 and hubloc_deleted = 0" + ); + if(! $r) { logger('notifier: no hubs'); @@ -569,6 +549,7 @@ function notifier_run($argv, $argc){ $hubs = $r; + /** * Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been * a re-install which has not yet been detected and pruned. @@ -583,6 +564,11 @@ function notifier_run($argv, $argc){ foreach($hubs as $hub) { + if(in_array($hub['hubloc_url'],$dead_hubs)) { + logger('skipping dead hub: ' . $hub['hubloc_url'], LOGGER_DEBUG); + continue; + } + if($hub['hubloc_network'] == 'zot') { if(! in_array($hub['hubloc_sitekey'],$keys)) { $hublist[] = $hub['hubloc_host']; @@ -601,30 +587,12 @@ function notifier_run($argv, $argc){ logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG); - $interval = ((get_config('system','delivery_interval') !== false) - ? intval(get_config('system','delivery_interval')) : 2 ); - - $deliveries_per_process = intval(get_config('system','delivery_batch_count')); - - if($deliveries_per_process <= 0) - $deliveries_per_process = 1; - - $deliver = array(); foreach($dhubs as $hub) { - if($hub['hubloc_network'] === 'diaspora' || $hub['hubloc_network'] === 'friendica-over-diaspora') { - if(! get_config('system','diaspora_enabled')) - continue; - - // allow this to be set per message + if($hub['hubloc_network'] !== 'zot') { - if(strpos($target_item['postopts'],'nodspr') !== false) - continue; - - require_once('include/diaspora.php'); - - diaspora_process_outbound(array( + $narr = array( 'channel' => $channel, 'env_recips' => $env_recips, 'recipients' => $recipients, @@ -644,14 +612,20 @@ function notifier_run($argv, $argc){ 'request' => $request, 'normal_mode' => $normal_mode, 'packet_type' => $packet_type, - 'walltowall' => $walltowall - )); + 'walltowall' => $walltowall, + 'queued' => array() + ); + + call_hooks('notifier_hub',$narr); + if($narr['queued']) { + foreach($narr['queued'] as $pq) + $deliveries[] = $pq; + } continue; } - // default: zot protocol @@ -700,28 +674,33 @@ function notifier_run($argv, $argc){ dbesc($n), dbesc(json_encode($encoded_item)) ); + // only create delivery reports for normal undeleted items + if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted'])) { + q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ", + dbesc($target_item['mid']), + dbesc($hub['hubloc_host']), + dbesc($hub['hubloc_host']), + dbesc('queued'), + dbesc(datetime_convert()), + dbesc($channel['channel_hash']), + dbesc($hash) + ); + } } - $deliver[] = $hash; - if(count($deliver) >= $deliveries_per_process) { - proc_run('php','include/deliver.php',$deliver); - $deliver = array(); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } + $deliveries[] = $hash; } - - // catch any stragglers - - if(count($deliver)) { - proc_run('php','include/deliver.php',$deliver); + + if($normal_mode) { + $x = q("select * from hook where hook = 'notifier_normal'"); + if($x) + proc_run('php','include/deliver_hooks.php', $target_item['id']); } - logger('notifier: basic loop complete.', LOGGER_DEBUG); - - if($normal_mode) - call_hooks('notifier_normal',$target_item); + if($deliveries) + do_delivery($deliveries); + logger('notifier: basic loop complete.', LOGGER_DEBUG); call_hooks('notifier_end',$target_item); |