aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Daemon/Master.php129
-rw-r--r--Zotlabs/Lib/Apps.php4
-rw-r--r--Zotlabs/Lib/PConfig.php17
-rw-r--r--Zotlabs/Module/Pconfig.php2
-rwxr-xr-xboot.php3
-rw-r--r--doc/hook/daemon_master_release.bb5
-rw-r--r--doc/hooklist.bb3
-rw-r--r--include/bbcode.php17
-rw-r--r--include/photo/photo_driver.php13
-rw-r--r--include/zid.php6
-rw-r--r--view/js/main.js13
-rwxr-xr-xview/tpl/conv_item.tpl6
-rwxr-xr-xview/tpl/conv_list.tpl6
13 files changed, 67 insertions, 157 deletions
diff --git a/Zotlabs/Daemon/Master.php b/Zotlabs/Daemon/Master.php
index 0656ca05b..857d47243 100644
--- a/Zotlabs/Daemon/Master.php
+++ b/Zotlabs/Daemon/Master.php
@@ -16,8 +16,6 @@ if(array_search( __file__ , get_included_files()) === 0) {
class Master {
- static public $queueworker = null;
-
static public function Summon($arr) {
proc_run('php','Zotlabs/Daemon/Master.php',$arr);
}
@@ -25,126 +23,21 @@ class Master {
static public function Release($argc,$argv) {
cli_startup();
- $maxworkers = get_config('system','max_queue_workers');
-
- if (!$maxworkers || $maxworkers == 0) {
- logger('Master: release: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
- $cls = '\\Zotlabs\\Daemon\\' . $argv[0];
- $cls::run($argc,$argv);
- self::ClearQueue();
- } else {
- logger('Master: enqueue: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
- $workinfo = ['argc'=>$argc,'argv'=>$argv];
- q("insert into config (cat,k,v) values ('queuework','%s','%s')",
- dbesc(uniqid('workitem:',true)),
- dbesc(serialize($workinfo)));
- self::Process();
- }
- }
-
- static public function GetWorkerID() {
- $maxworkers = get_config('system','max_queue_workers');
- $maxworkers = ($maxworkers) ? $maxworkers : 3;
-
- $workermaxage = get_config('system','max_queue_worker_age');
- $workermaxage = ($workermaxage) ? $workermaxage : 300;
-
- $workers = q("select * from config where cat='queueworkers' and k like '%s'", 'workerstarted_%');
-
- if (count($workers) > $maxworkers) {
- foreach ($workers as $idx => $worker) {
- $curtime = time();
- $age = (intval($curtime) - intval($worker['v']));
- if ( $age > $workermaxage) {
- logger("Prune worker: ".$worker['k'], LOGGER_ALL, LOGGER_DEBUG);
- $k = explode('_',$worker['k']);
- q("delete from config where cat='queueworkers' and k='%s'",
- 'workerstarted_'.$k[1]);
- q("update config set k='%s' where cat='queuework' and k='%s'",
- dbesc(uniqid('workitem:',true)),
- 'workitem_'.$k[1]);
- unset($workers[$idx]);
- }
- }
- if (count($workers) > $maxworkers) {
- return false;
- }
- }
- return uniqid('',true);
-
- }
-
- static public function Process() {
-
- self::$queueworker = self::GetWorkerID();
-
- if (!self::$queueworker) {
- logger('Master: unable to obtain worker ID.');
- killme();
- }
-
- set_config('queueworkers','workerstarted_'.self::$queueworker,time());
-
- $workersleep = get_config('system','queue_worker_sleep');
- $workersleep = ($workersleep) ? $workersleep : 5;
- cli_startup();
-
- $work = q("update config set k='%s' where cat='queuework' and k like '%s' limit 1",
- 'workitem_'.self::$queueworker,
- dbesc('workitem:%'));
- $jobs = 0;
- while ($work) {
- $workitem = q("select * from config where cat='queuework' and k='%s'",
- 'workitem_'.self::$queueworker);
-
- if (isset($workitem[0])) {
- $jobs++;
- $workinfo = unserialize($workitem[0]['v']);
- $argc = $workinfo['argc'];
- $argv = $workinfo['argv'];
- logger('Master: process: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
-
- //Delete unclaimed duplicate workitems.
- q("delete from config where cat='queuework' and k='workitem' and v='%s'",
- serialize($argv));
-
- $cls = '\\Zotlabs\\Daemon\\' . $argv[0];
- $cls::run($argc,$argv);
+ $hookinfo = [
+ 'argv'=>$argv
+ ];
- //Right now we assume that if we get a return, everything is OK.
- //At some point we may want to test whether the run returns true/false
- // and requeue the work to be tried again. But we probably want
- // to implement some sort of "retry interval" first.
+ call_hooks ('daemon_master_release',$hookinfo);
- q("delete from config where cat='queuework' and k='%s'",
- 'workitem_'.self::$queueworker);
- } else {
- break;
- }
- sleep ($workersleep);
- $work = q("update config set k='%s' where cat='queuework' and k like '%s' limit 1",
- 'workitem_'.self::$queueworker,
- dbesc('workitem:%'));
+ $argv = $hookinfo['argv'];
+ $argc = count($argv);
+ if ((!is_array($argv) || (count($argv) < 1))) {
+ return;
}
- logger('Master: Worker Thread: queue items processed:' . $jobs);
- q("delete from config where cat='queueworkers' and k='%s'",
- 'workerstarted_'.self::$queueworker);
- }
- static public function ClearQueue() {
- $work = q("select * from config where cat='queuework' and k like '%s'",
- dbesc('workitem%'));
- foreach ($work as $workitem) {
- $workinfo = unserialize($workitem['v']);
- $argc = $workinfo['argc'];
- $argv = $workinfo['argv'];
- logger('Master: process: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
- $cls = '\\Zotlabs\\Daemon\\' . $argv[0];
- $cls::run($argc,$argv);
- }
- $work = q("delete from config where cat='queuework' and k like '%s'",
- dbesc('workitem%'));
+ logger('Master: release: ' . json_encode($argv), LOGGER_ALL,LOG_DEBUG);
+ $cls = '\\Zotlabs\\Daemon\\' . $argv[0];
+ $cls::run($argc,$argv);
}
-
}
diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php
index 8cf62c01a..de7439ed7 100644
--- a/Zotlabs/Lib/Apps.php
+++ b/Zotlabs/Lib/Apps.php
@@ -57,7 +57,7 @@ class Apps {
}
static public function get_base_apps() {
- return get_config('system','base_apps',[
+ $x = get_config('system','base_apps',[
'Connections',
'Network',
'Settings',
@@ -72,6 +72,8 @@ class Apps {
'Mail',
'Profile Photo'
]);
+ call_hooks('get_base_apps',$x);
+ return $x;
}
static public function import_system_apps() {
diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php
index 5e5954c95..69f4de2db 100644
--- a/Zotlabs/Lib/PConfig.php
+++ b/Zotlabs/Lib/PConfig.php
@@ -131,14 +131,19 @@ class PConfig {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+ $now = datetime_convert();
if (! $updated) {
- $updated = datetime_convert();
+ //Sometimes things happen fast... very fast.
+ //To make sure legitimate updates aren't rejected
+ //because not enough time has passed. We say our updates
+ //happened just a short time in the past rather than right now.
+ $updated = datetime_convert('UTC','UTC','-2 seconds');
}
$hash = hash('sha256',$family.':'.$key);
if (self::Get($uid, 'hz_delpconfig', $hash) !== false) {
- if (self::Get($uid, 'hz_delpconfig', $hash) > $updated) {
+ if (self::Get($uid, 'hz_delpconfig', $hash) > $now) {
logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR);
return self::Get($uid,$family,$key);
} else {
@@ -173,7 +178,7 @@ class PConfig {
}
else {
- $new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $updated);
+ $new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
if ($new) {
@@ -241,9 +246,9 @@ class PConfig {
if(is_null($uid) || $uid === false)
return false;
- $updated = ($updated) ? $updated : datetime_convert();
-
- $newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $updated);
+ $updated = ($updated) ? $updated : datetime_convert('UTC','UTC','-2 seconds');
+ $now = datetime_convert();
+ $newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
if (! $newer) {
logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR);
diff --git a/Zotlabs/Module/Pconfig.php b/Zotlabs/Module/Pconfig.php
index f31d5fdf6..06b94b34f 100644
--- a/Zotlabs/Module/Pconfig.php
+++ b/Zotlabs/Module/Pconfig.php
@@ -24,7 +24,7 @@ class Pconfig extends \Zotlabs\Web\Controller {
$aj = intval($_POST['aj']);
// Do not store "serialized" data received in the $_POST
- if (preg_match('|^a:[0-9]+:{.*}$|s',$v) || preg_match('O:8:"stdClass":[0-9]+:{.*}$|s',$v)) {
+ if (preg_match('|^a:[0-9]+:{.*}$|s',$v) || preg_match('|O:8:"stdClass":[0-9]+:{.*}$|s',$v)) {
return;
}
diff --git a/boot.php b/boot.php
index 410aa91b1..321f1a93b 100755
--- a/boot.php
+++ b/boot.php
@@ -84,7 +84,8 @@ define ( 'DIRECTORY_FALLBACK_MASTER', 'https://zotadel.net');
$DIRECTORY_FALLBACK_SERVERS = array(
'https://hubzilla.zottel.net',
- 'https://zotadel.net'
+ 'https://zotadel.net',
+ 'https://zotsite.net'
);
diff --git a/doc/hook/daemon_master_release.bb b/doc/hook/daemon_master_release.bb
new file mode 100644
index 000000000..a17216d48
--- /dev/null
+++ b/doc/hook/daemon_master_release.bb
@@ -0,0 +1,5 @@
+[h2]daemon_master_release[/h2]
+
+Permit filtering or alternate methods of processing of background processes when [code] \Zotlabs\Daemon\Master::Release() [/code] is called.
+
+Default behavior is for a new PHP process to fire immediately upon a call to Master::Summon(). This hook permits pre-emption and the ability to provide queuing or other alternatives to this procedure.
diff --git a/doc/hooklist.bb b/doc/hooklist.bb
index 08fc587e2..afb2cebee 100644
--- a/doc/hooklist.bb
+++ b/doc/hooklist.bb
@@ -190,6 +190,9 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/daemon_addon]daemon_addon[/zrl]
Called when invoking the extensible background daemon
+[zrl=[baseurl]/help/hook/daemon_master_release]daemon_master_release[/zrl]
+ Called at the start of processing \Zotlabs\Daemon\Master::Release()
+
[zrl=[baseurl]/help/hook/directory_item]directory_item[/zrl]
Called when generating a directory listing for display
diff --git a/include/bbcode.php b/include/bbcode.php
index 817986da0..7531bd774 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -326,22 +326,11 @@ function bb_ShareAttributes($match) {
$auth = is_matrix_url($profile);
}
- // message_id is never used, do we still need it?
- $message_id = "";
- preg_match("/message_id='(.*?)'/ism", $attributes, $matches);
- if ($matches[1] != "")
- $message_id = $matches[1];
-
- if(! $message_id) {
- preg_match("/guid='(.*?)'/ism", $attributes, $matches);
- if ($matches[1] != "")
- $message_id = $matches[1];
- }
-
+ $rnd = mt_rand();
$reldate = '<span class="autotime" title="' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'c') . '" >' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'r') . '</span>';
- $headline = '<div class="shared_container"> <div class="shared_header">';
+ $headline = '<div id="shared_container_' . $rnd . '" class="shared_container"> <div id="shared_header_' . $rnd . '" class="shared_header">';
if ($avatar != "")
$headline .= '<a href="' . (($auth) ? zid($profile) : $profile) . '" ><img src="' . $avatar . '" alt="' . $author . '" height="32" width="32" /></a>';
@@ -363,7 +352,7 @@ function bb_ShareAttributes($match) {
$headline .= '<span>' . $fmt . '</span></div>';
- $text = $headline . '<div class="reshared-content">' . trim($match[2]) . '</div></div>';
+ $text = $headline . '<div id="reshared-content-' . $rnd . '" class="reshared-content">' . trim($match[2]) . '</div></div>';
return $text;
}
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index 9aeb2ef17..5c8ed9bdc 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -482,7 +482,6 @@ function guess_image_type($filename, $headers = '') {
// logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG);
$type = null;
if ($headers) {
-
$hdrs=array();
$h = explode("\n",$headers);
foreach ($h as $l) {
@@ -490,11 +489,16 @@ function guess_image_type($filename, $headers = '') {
$hdrs[strtolower($k)] = $v;
}
logger('Curl headers: '.var_export($hdrs, true), LOGGER_DEBUG);
- if (array_key_exists('content-type', $hdrs))
- $type = $hdrs['content-type'];
+ if (array_key_exists('content-type', $hdrs)) {
+ $ph = photo_factory('');
+ $types = $ph->supportedTypes();
+
+ if(array_key_exists($hdrs['content-type'], $types))
+ $type = $hdrs['content-type'];
+ }
}
- if (is_null($type)){
+ if (is_null($type)){
$ignore_imagick = get_config('system', 'ignore_imagick');
// Guessing from extension? Isn't that... dangerous?
if(class_exists('Imagick') && file_exists($filename) && is_readable($filename) && !$ignore_imagick) {
@@ -638,7 +642,6 @@ function import_xchan_photo($photo,$xchan,$thing = false,$force = false) {
$img_str = $result['body'];
$type = guess_image_type($photo, $result['header']);
$modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $o) ? strtotime($o[1] . 'Z') : time()));
-
if(is_null($type))
$photo_failure = true;
}
diff --git a/include/zid.php b/include/zid.php
index fe06948ba..a37ebe1f6 100644
--- a/include/zid.php
+++ b/include/zid.php
@@ -70,9 +70,9 @@ function zid($s, $address = '') {
$zurl .= '#' . $fragment;
$arr = [
- 'url' => $s,
- 'zid' => urlencode($myaddr),
- 'result' => $zurl
+ 'url' => $s,
+ 'zid' => urlencode($myaddr),
+ 'result' => $zurl
];
/**
* @hooks zid
diff --git a/view/js/main.js b/view/js/main.js
index a69bcfa64..ca9ad8ca4 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -239,7 +239,11 @@ function handle_comment_form(e) {
},10000);
});
- function commentSaveChanges(convId,isFinal = false) {
+ function commentSaveChanges(convId, isFinal) {
+
+ if(typeof isFinal === 'undefined')
+ isFinal = false;
+
if(auto_save_draft) {
tmp = $('#' + emptyCommentElm).val();
if(tmp) {
@@ -888,7 +892,12 @@ function liveUpdate(notify_id) {
if((src === null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
- if(($('.comment-edit-text.expanded').length) || (in_progress) || (mediaPlaying)) {
+ // if auto updates are enabled and a comment box is open,
+ // prevent live updates until the comment is submitted
+
+ var lockUpdates = (($('.comment-edit-text.expanded').length && (! bParam_static)) ? true : false);
+
+ if(lockUpdates || in_progress || mediaPlaying) {
if(livetime) {
clearTimeout(livetime);
}
diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl
index 7dddf9c01..69e09b272 100755
--- a/view/tpl/conv_item.tpl
+++ b/view/tpl/conv_item.tpl
@@ -9,12 +9,12 @@
<div class="wall-item-outside-wrapper{{if $item.is_comment}} comment{{/if}}{{if $item.previewing}} preview{{/if}}" id="wall-item-outside-wrapper-{{$item.id}}" >
<div class="clearfix wall-item-content-wrapper{{if $item.is_comment}} comment{{/if}}" id="wall-item-content-wrapper-{{$item.id}}">
{{if $item.photo}}
- <div class="wall-photo-item" id="wall-photo-item-{{$item.id}}">
+ <div class="wall-photo-item{{if $item.is_new && !$item.title}} wall-item-head-new rounded-top{{/if}}" id="wall-photo-item-{{$item.id}}">
{{$item.photo}}
</div>
{{/if}}
{{if $item.event}}
- <div class="wall-event-item" id="wall-event-item-{{$item.id}}">
+ <div class="wall-event-item{{if $item.is_new && !$item.title}} wall-item-head-new rounded-top{{/if}}" id="wall-event-item-{{$item.id}}">
{{$item.event}}
</div>
{{/if}}
@@ -26,7 +26,7 @@
<hr class="m-0">
{{/if}}
{{/if}}
- <div class="p-2 clearfix wall-item-head{{if $item.is_new && !$item.title && !$item.event && !$item.is_comment}} wall-item-head-new rounded-top{{/if}}">
+ <div class="p-2 clearfix wall-item-head{{if $item.is_new && !$item.title && !$item.event && !$item.is_comment && !$item.photo}} wall-item-head-new rounded-top{{/if}}">
<div class="wall-item-info " id="wall-item-info-{{$item.id}}" >
<div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}} h-card p-author" id="wall-item-photo-wrapper-{{$item.id}}">
<img src="{{$item.thumb}}" class="fakelink wall-item-photo{{$item.sparkle}} u-photo p-name" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" data-toggle="dropdown" />
diff --git a/view/tpl/conv_list.tpl b/view/tpl/conv_list.tpl
index c6da3d8a4..28e120d17 100755
--- a/view/tpl/conv_list.tpl
+++ b/view/tpl/conv_list.tpl
@@ -9,12 +9,12 @@
<div class="wall-item-outside-wrapper{{if $item.is_comment}} comment{{/if}}{{if $item.previewing}} preview{{/if}}" id="wall-item-outside-wrapper-{{$item.id}}" >
<div class="clearfix wall-item-content-wrapper{{if $item.is_comment}} comment{{/if}}" id="wall-item-content-wrapper-{{$item.id}}">
{{if $item.photo}}
- <div class="wall-photo-item" id="wall-photo-item-{{$item.id}}">
+ <div class="wall-photo-item{{if $item.is_new && !$item.title}} wall-item-head-new rounded-top{{/if}}" id="wall-photo-item-{{$item.id}}">
{{$item.photo}}
</div>
{{/if}}
{{if $item.event}}
- <div class="wall-event-item" id="wall-event-item-{{$item.id}}">
+ <div class="wall-event-item{{if $item.is_new && !$item.title}} wall-item-head-new rounded-top{{/if}}" id="wall-event-item-{{$item.id}}">
{{$item.event}}
</div>
{{/if}}
@@ -26,7 +26,7 @@
<hr class="m-0">
{{/if}}
{{/if}}
- <div class="p-2 clearfix wall-item-head{{if $item.is_new && !$item.title && !$item.event && !$item.is_comment}} wall-item-head-new rounded-top{{/if}}">
+ <div class="p-2 clearfix wall-item-head{{if $item.is_new && !$item.title && !$item.event && !$item.is_comment && !$item.photo}} wall-item-head-new rounded-top{{/if}}">
<div class="wall-item-info" id="wall-item-info-{{$item.id}}" >
<div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}} h-card p-author" id="wall-item-photo-wrapper-{{$item.id}}">
<img src="{{$item.thumb}}" class="fakelink wall-item-photo{{$item.sparkle}} u-photo p-name" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" data-toggle="dropdown" /></a>