summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2021-02-27 13:05:02 +0300
committerAndrew Dolgov <[email protected]>2021-02-27 13:05:02 +0300
commitdfff2cef7b29e2275bd1cf9ac59d3e50f09b7bc5 (patch)
tree967719142c2e105e765039fc79661f4fc1efe898
parent5edcbf2e9bfa79ea87a6e420a4c17e8b02997716 (diff)
add basic updater for stuff in plugins.local
-rw-r--r--backend.php5
-rw-r--r--classes/pref/prefs.php72
-rw-r--r--js/PrefHelpers.js64
3 files changed, 132 insertions, 9 deletions
diff --git a/backend.php b/backend.php
index 206d866b7..e310322f2 100644
--- a/backend.php
+++ b/backend.php
@@ -135,6 +135,9 @@
} else {
if (method_exists($handler, "catchall")) {
$handler->catchall($method);
+ } else {
+ header("Content-Type: text/json");
+ print Errors::to_json(Errors::E_UNKNOWN_METHOD, ["info" => get_class($handler) . "->$method"]);
}
}
$handler->after();
@@ -154,6 +157,6 @@
}
header("Content-Type: text/json");
- print Errors::to_json(Errors::E_UNKNOWN_METHOD);
+ print Errors::to_json(Errors::E_UNKNOWN_METHOD, ["info" => get_class($handler) . "->$method"]);
?>
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index 14ca9b49c..7ab9966ba 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -842,6 +842,8 @@ class Pref_Prefs extends Handler_Protected {
$is_checked = "checked='1'";
}
+ $can_update = is_dir(dirname(dirname(__DIR__)) . "/plugins.local/$name/.git");
+
?>
<fieldset class='prefs plugin'>
@@ -853,12 +855,19 @@ class Pref_Prefs extends Handler_Protected {
</input>
</label>
+ <?php if ($_SESSION["access_level"] >= 10 && $can_update) { ?>
+ <button dojoType='dijit.form.Button' onclick='Helpers.Plugins.updateLocal("<?= htmlspecialchars($name) ?>")'>
+ <?= \Controls\icon("update") ?>
+ <?= __("Update") ?>
+ </button>
+ <?php } ?>
+
<?php if (count($tmppluginhost->get_all($plugin)) > 0) {
if (in_array($name, $system_enabled) || in_array($name, $user_enabled)) { ?>
<button dojoType='dijit.form.Button'
- onclick='Helpers.Prefs.clearPluginData("<?= htmlspecialchars($name) ?>")'>
+ onclick='Helpers.Plugins.clearPluginData("<?= htmlspecialchars($name) ?>")'>
<i class='material-icons'>clear</i> <?= __("Clear data") ?></button>
- <?php }
+ <?php }
} ?>
<?php if ($about[4] ?? false) { ?>
@@ -937,6 +946,12 @@ class Pref_Prefs extends Handler_Protected {
<button dojoType='dijit.form.Button' class='alt-primary' type='submit'>
<?= __("Enable selected plugins") ?>
</button>
+ <?php if ($_SESSION["access_level"] >= 10) { ?>
+ <button dojoType='dijit.form.Button' onclick="Helpers.Plugins.updateLocal()">
+ <?= \Controls\icon("update") ?>
+ <?= __("Update local plugins") ?>
+ </button>
+ <?php } ?>
</div>
</div>
</form>
@@ -1073,6 +1088,59 @@ class Pref_Prefs extends Handler_Protected {
set_pref(Prefs::_ENABLED_PLUGINS, $plugins);
}
+ private function _update_plugin($root_dir, $plugin_name) {
+ $plugin_dir = "$root_dir/plugins.local/" . basename($plugin_name);
+ $rv = [];
+
+ if (is_dir($plugin_dir) && is_dir("$plugin_dir/.git")) {
+ $pipes = [];
+
+ $descriptorspec = [
+ 0 => ["pipe", "r"], // STDIN
+ 1 => ["pipe", "w"], // STDOUT
+ 2 => ["pipe", "w"], // STDERR
+ ];
+
+ $proc = proc_open("git pull --ff-only -q origin master", $descriptorspec, $pipes, $plugin_dir);
+
+ if (is_resource($proc)) {
+ $rv["o"] = stream_get_contents($pipes[1]);
+ $rv["e"] = stream_get_contents($pipes[2]);
+ $status = proc_close($proc);
+ $rv["s"] = $status;
+ }
+ }
+
+ return $rv;
+ }
+
+ function updateLocalPlugins() {
+ if ($_SESSION["access_level"] >= 10) {
+ $plugin_name = $_REQUEST["name"] ?? "";
+
+ # we're in classes/pref/
+ $root_dir = dirname(dirname(__DIR__));
+
+ $rv = [];
+
+ if (!empty($plugin_name)) {
+ array_push($rv, ["plugin" => $plugin_name, "rv" => $this->_update_plugin($root_dir, $plugin_name)]);
+ } else {
+ $plugin_dirs = array_filter(glob("$root_dir/plugins.local/*"), "is_dir");
+
+ foreach ($plugin_dirs as $dir) {
+ if (is_dir("$dir/.git")) {
+ $plugin_name = basename($dir);
+
+ array_push($rv, ["plugin" => $plugin_name, "rv" => $this->_update_plugin($root_dir, $plugin_name)]);
+ }
+ }
+ }
+
+ print json_encode($rv);
+ }
+ }
+
function clearplugindata() {
$name = clean($_REQUEST["name"]);
diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js
index 62f6d91b1..125cc20d0 100644
--- a/js/PrefHelpers.js
+++ b/js/PrefHelpers.js
@@ -278,20 +278,72 @@ const Helpers = {
});
}
},
+ refresh: function() {
+ xhr.post("backend.php", { op: "pref-prefs" }, (reply) => {
+ dijit.byId('prefsTab').attr('content', reply);
+ Notify.close();
+ });
+ },
+ },
+ Plugins: {
clearPluginData: function(name) {
if (confirm(__("Clear stored data for this plugin?"))) {
Notify.progress("Loading, please wait...");
- xhr.post("backend.php", {op: "pref-prefs", method: "clearplugindata", name: name}, () => {
+ xhr.post("backend.php", {op: "pref-prefs", method: "clearPluginData", name: name}, () => {
Helpers.Prefs.refresh();
});
}
},
- refresh: function() {
- xhr.post("backend.php", { op: "pref-prefs" }, (reply) => {
- dijit.byId('prefsTab').attr('content', reply);
- Notify.close();
- });
+ updateLocal: function(name = null) {
+ const msg = name ? __("Update %p using git?").replace("%p", name) :
+ __("Update all local plugins using git?");
+
+ if (confirm(msg)) {
+
+ const dialog = new fox.SingleUseDialog({
+ title: __("Plugin Updater"),
+ content: `
+ <ul class="panel panel-scrollable update-results">
+ <li>${__("Loading, please wait...")}</li>
+ </ul>
+
+ <footer class="text-center">
+ ${App.FormFields.submit_tag(__("Close this window"))}
+ </footer>
+ `,
+ });
+
+ const tmph = dojo.connect(dialog, 'onShow', function () {
+ dojo.disconnect(tmph);
+
+ xhr.json("backend.php", {op: "pref-prefs", method: "updateLocalPlugins", name: name}, (reply) => {
+ const container = dialog.domNode.querySelector(".update-results");
+
+ if (!reply) {
+ container.innerHTML = __("Operation failed: check event log.");
+ } else {
+ container.innerHTML = "";
+
+ reply.forEach((p) => {
+ container.innerHTML +=
+ `
+ <li><h3 style="margin-top: 0">${p.plugin}</h3>
+ ${p.rv.e ? `<pre class="small text-error">${p.rv.e}</pre>` : ''}
+ ${p.rv.o ? `<pre class="small text-success">${p.rv.o}</pre>` : ''}
+ <p class="small">
+ ${p.rv.s ? __("Exited with RC: %d").replace("%d", p.rv.s) : __("OK")}
+ </p>
+ </li>
+ `
+ });
+ }
+ });
+
+ });
+
+ dialog.show();
+ }
},
},
OPML: {