buuuump
[guerillascript.git] / main / modules / pkg / pkgman.js
blobadd0cdd4bf1e70a4ffebec092a01f14fd7d3f989
1 /* coded by Ketmar // Invisible Vector (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://www.wtfpl.net/txt/copying/ for more details.
9 */
10 ////////////////////////////////////////////////////////////////////////////////
11 Components.utils.import("chrome://guerilla-script-jscode/content/modules/signals.jsm");
12 let asvc = Components.classes["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
15 addSignalListener("package-downloader", function (signame, state) {
16 conlog("package-downloader: phase=", state.phase, "; url=", state.url);
18 if (state.phase.substr(0, 6) === "error-") {
19 // show notification
20 asvc.showAlertNotification(
21 "chrome://guerilla-script-misc/content/icon.png",
22 "GuerillaScript package manager",
23 "DOWNLOAD FAILED! ("+state.phase+")\n"+state.url,
24 false
26 //error-main-file
27 //error-main-content-type
28 //error-main-metadata
29 //error-resource-file
30 } else if (state.phase === "complete") {
31 // show notification
32 asvc.showAlertNotification(
33 "chrome://guerilla-script-misc/content/icon.png",
34 "GuerillaScript package manager",
35 "DOWNLOAD COMPLETE!\n"+state.url,
36 false
39 });
42 ////////////////////////////////////////////////////////////////////////////////
43 let dldr = null;
44 let lastUpdateCount = 0;
45 let pkgList = {lmod:-1};
48 ////////////////////////////////////////////////////////////////////////////////
49 exports.getPackageList = function () {
50 if (lastUpdateCount != pkgList.lmod) {
51 pkgList.lmod = lastUpdateCount;
52 pkgList.list = pkgDB.getActivePackages();
53 //for (let pi of pkgList.list) conlog("id=", pi.id, "; name=", pi.name);
55 return pkgList;
59 exports.getLastUpdateTimeForId = function (pkgid) pkgDB.getPackageUpdateTimeById(pkgid);
62 ////////////////////////////////////////////////////////////////////////////////
63 // queue object:
64 // string name
65 // string url
66 let queue = new Array();
69 ////////////////////////////////////////////////////////////////////////////////
70 exports.__defineGetter__("inProgress", function () (dldr && dldr.running));
73 ////////////////////////////////////////////////////////////////////////////////
74 exports.cancel = function () {
75 if (dldr) {
76 if (dldr.running) dldr.cancel();
77 dldr = null;
79 queue = new Array();
83 ////////////////////////////////////////////////////////////////////////////////
84 function pingQueue () {
85 if (dldr) return; // in progress
86 let qo; // queue object
87 for (;;) {
88 if (queue.length == 0) return; // nothing to do
89 // get queue object
90 qo = queue[0];
91 queue.splice(0, 1); // remove first element
92 if (!qo.url) {
93 //conlog("NO URL for '", qo.name, "'");
94 // no url: update request; find package
95 let pi = pkgDB.getActivePackageByName(qo.name);
96 if (pi) {
98 conlog(
99 "pi.id=", pi.id, "\n",
100 "pi.name=", pi.name, "\n",
101 "pi.dirname=", pi.dirname, "\n",
102 "pi.version=", pi.version, "\n",
103 "pi.url=", pi.url, "\n"
106 qo.url = pi.url;
107 break;
109 logError("can't update unknown package '"+qo.name+"'");
110 } else {
111 break;
114 //conlog("GS: qo.name=", qo.name, "; qo.url=", qo.url);
115 // new downloader
116 dldr = new PkgDownloader(qo.url);
117 let skipCancel = false;
118 dldr.clearTempDir();
119 dldr.onError = function () {
120 /*++lastUpdateCount;*/
121 emitSignal("package-manager", {name:qo.name, phase:"error"});
122 logError("package '", qo.name, "': download failed!");
123 dldr = null;
124 pingQueue();
126 dldr.onCancel = function () {
127 /*++lastUpdateCount;*/
128 if (!skipCancel) {
129 emitSignal("package-manager", {name:qo.name, phase:"cancelled"});
130 logError("package '", qo.name, "': download cancelled!");
132 dldr = null;
133 pingQueue();
135 dldr.onComplete = function () {
136 dldr = null;
137 let upd = pkgDB.checkAndUpdate(qo.name, this.pkg);
138 conlog((upd ? "" : "NOT "), "UPDATED: '", qo.name, "'");
139 if (upd) {
140 ++lastUpdateCount;
141 scacheAPI.reset();
143 emitSignal("package-manager", {name:qo.name, phase:"complete"});
144 pingQueue();
146 dldr.onMainReceived = function () {
147 conlog("package '", qo.name, "': received main file");
148 let res = pkgDB.checkAndUpdate(qo.name, this.pkg, {checkOnly:true});
149 if (!res) {
150 conlog("package '", qo.name, "' is up-to-date");
151 skipCancel = true;
152 emitSignal("package-manager", {name:qo.name, phase:"complete"});
154 return res;
156 emitSignal("package-manager", {name:qo.name, phase:"started"});
157 dldr.start();
161 ////////////////////////////////////////////////////////////////////////////////
162 exports.install = function (name, url) {
163 if (typeof(name) !== "string" || !name) throw new Error("invalid package name");
164 if (typeof(url) !== "string" || !(/https?:/.test(url))) throw new Error("invalid package url");
165 // queue
166 let found = false;
167 for (let qo of queue) {
168 if (qo.name == name) {
169 if (qo.url != url) throw new Error("conflicting URLs for package '"+name+"'");
170 found = true;
171 break;
174 if (!found) queue.push({name:name, url:url});
175 pingQueue();
179 ////////////////////////////////////////////////////////////////////////////////
180 exports.update = function (name) {
181 if (typeof(name) !== "string" || !name) throw new Error("invalid package name");
182 // queue
183 let found = false;
184 for (let qo of queue) {
185 if (qo.name == name) {
186 found = true;
187 break;
190 if (!found) queue.push({name:name, url:null});
191 pingQueue();
195 ////////////////////////////////////////////////////////////////////////////////
196 exports.remove = function (name) {
197 if (typeof(name) !== "string" || !name) throw new Error("invalid package name");
198 if (dldr && dldr.running) throw new Error("package manager is busy");
199 try {
200 pkgDB.removePackage(name);
201 conlog("package '", name, "' removed");
202 } catch (e) { logException("WTF", e); }
203 ++lastUpdateCount;
204 scacheAPI.reset();