App_update: Add download and unzip workers

v3.3.4
gnosygnu 8 years ago
parent 1c37d4e599
commit 103d005e62

@ -54,7 +54,7 @@ class Io_zip_decompress_cmd__jre extends Io_zip_decompress_cmd__base {
// create file
Io_url trg_fil_url = Io_url_.new_any_(trg_dir.GenSubFil(entry_name).Raw());
Io_url trg_tmp_url = trg_fil_url.GenNewNameAndExt(trg_fil_url.NameAndExt() + ".tmp");
if (trg_tmp_url.Type_fil()) {
if (trg_fil_url.Type_fil()) {
// handle resume
long item_in_raw = 0;
if (resume_item > 0) {
@ -79,9 +79,12 @@ class Io_zip_decompress_cmd__jre extends Io_zip_decompress_cmd__base {
}
trg_fil_stream.close();
if (!loop) return Gfo_prog_ui_.Status__suspended; // manually canceled
Io_mgr.Instance.MoveFil_args(trg_tmp_url, trg_fil_url, true).Exec();
trg_fils.Add(trg_fil_url);
}
else {
Io_mgr.Instance.CreateDir(trg_fil_url);
}
Io_mgr.Instance.MoveFil_args(trg_tmp_url, trg_fil_url, true).Exec();
trg_fils.Add(trg_fil_url);
}
Gfo_evt_mgr_.Pub_val(Io_mgr.Instance, Io_mgr.Evt__fil_created, trg_fils.To_ary(Io_url.class));
}

@ -121,7 +121,7 @@ public class Swt_html implements Gxw_html, Swt_control, FocusListener, Gfo_evt_m
bfr.Add_byte(Byte_ascii.Paren_end).Add_byte(Byte_ascii.Semic);
return Eval_script(bfr.To_str_and_clear());
}
private static String Escape_quote(String v) {
public static String Escape_quote(String v) {
String rv = v;
rv = String_.Replace(rv, "'", "\\'");
rv = String_.Replace(rv, "\"", "\\\"");
@ -182,9 +182,11 @@ class Swt_html_lnr_title implements TitleListener {
}
}
class Swt_html_func extends BrowserFunction {
private Gfo_invk invk;
private final Gfo_invk invk;
private final Browser browser;
public Swt_html_func(Browser browser, String name, Gfo_invk invk) {
super (browser, name);
this.browser = browser;
this.invk = invk;
}
public Object function (Object[] args) {
@ -192,7 +194,9 @@ class Swt_html_func extends BrowserFunction {
return gplx.gfui.controls.standards.Gfui_html.Js_args_exec(invk, args);
}
catch (Exception e) {
return Err_.Message_gplx_full(e);
String rv = Err_.Message_gplx_full(e);
browser.execute("alert('" + Swt_html.Escape_quote(rv) + "')");
return rv;
}
}
}

@ -0,0 +1,90 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.apps.updates.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*;
import gplx.core.gfobjs.*; import gplx.core.progs.*; import gplx.core.progs.rates.*;
import gplx.xowa.guis.cbks.*;
public class Xojs_wkr__base implements Gfo_prog_ui, Gfo_invk {
private long time_prv;
private double rate_cur;
private final Gfo_rate_list rate_list = new Gfo_rate_list(32);
private final long notify_delay = 1000;
private final double delta_threshold = .25d; // allow variance of up to 25% before updating rate
private final String js_cbk;
private final Gfo_invk_cmd done_cbk;
public Xojs_wkr__base(Xog_cbk_mgr cbk_mgr, Xog_cbk_trg cbk_trg, String js_cbk, Gfo_invk_cmd done_cbk) {
this.cbk_mgr = cbk_mgr;
this.cbk_trg = cbk_trg;
this.js_cbk = js_cbk;
this.done_cbk = done_cbk;
rate_list.Add(1024 * 1024, 1); // add default rate of 1 MB per second;
}
public void Exec() {
this.time_prv = gplx.core.envs.System_.Ticks();
this.Exec_run();
done_cbk.Exec_by_ctx(GfsCtx.Instance, GfoMsg_.new_cast_("m").Add("v", this));
}
@gplx.Virtual protected void Exec_run() {}
public void Exec_async(String thread_name) {
gplx.core.threads.Thread_adp_.Start_by_key(thread_name + ".download", this, Invk__exec);
}
public Xog_cbk_mgr Cbk_mgr() {return cbk_mgr;} private final Xog_cbk_mgr cbk_mgr;
public Xog_cbk_trg Cbk_trg() {return cbk_trg;} private final Xog_cbk_trg cbk_trg;
public boolean Canceled() {return canceled;} private boolean canceled;
public void Cancel() {this.canceled = true;}
public byte Prog_status() {return status;}
public void Prog_status_(byte v) {status = v;} private byte status;
public long Prog_data_cur() {return data_cur;} private long data_cur;
public long Prog_data_end() {return data_end;} private long data_end;
protected void Prog_data_end_(long v) {this.data_end = v;}
public void Prog_notify_by_msg(String msg) {}
public boolean Prog_notify_and_chk_if_suspended(long new_data_cur, long new_data_end) {
if (status == Gfo_prog_ui_.Status__suspended) return true; // task paused by ui; exit now;
long time_cur = gplx.core.envs.System_.Ticks();
if (time_cur < time_prv + notify_delay) return false; // message came too soon. ignore it
// update rate
double rate_now = (rate_list.Add(new_data_cur - data_cur, (time_cur - time_prv))) * 1000;
double delta = Math_.Abs_double((rate_now - rate_cur) / rate_cur);
if ( rate_cur == 0 // rate not set
|| delta > delta_threshold) { // rate_now is at least 25% different than rate_prv
if (delta > delta_threshold * 2) // rate_now is > 50% different
rate_cur = rate_now; // update it now
else {
double rate_new = ((rate_now - rate_cur) * .05) + rate_cur; // calc new rate as 5% of difference
// Tfds.Dbg(delta, rate_now, rate_cur, rate_new);
rate_cur = rate_new;
}
}
// update prog vals
this.time_prv = time_cur;
this.data_cur = new_data_cur;
this.data_end = new_data_end;
cbk_mgr.Send_json(cbk_trg, js_cbk, Gfobj_nde.New().Add_long("prog_data_cur", data_cur).Add_long("prog_data_end", data_end).Add_int("prog_rate", (int)rate_cur));
return false;
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk__exec)) this.Exec();
else return Gfo_invk_.Rv_unhandled;
return this;
} private static final String Invk__exec = "exec";
}

@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.apps.updates.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*;
import gplx.xowa.guis.cbks.*;
import gplx.core.net.downloads.*;
public class Xojs_wkr__download extends Xojs_wkr__base {
public Xojs_wkr__download(Xog_cbk_mgr cbk_mgr, Xog_cbk_trg cbk_trg, String js_cbk, Gfo_invk_cmd done_cbk, String src, Io_url trg, long src_len) {super(cbk_mgr, cbk_trg, js_cbk, done_cbk);
this.src = src;
this.src_len = src_len;
this.trg = trg;
this.Prog_data_end_(src_len);
}
public String Src() {return src;} private final String src;
public Io_url Trg() {return trg;} private final Io_url trg;
public long Src_len() {return src_len;} private final long src_len;
@Override protected void Exec_run() {
Http_download_wkr wkr = Http_download_wkr_.Proto.Make_new();
wkr.Exec(this, src, trg, src_len);
}
}

@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.apps.updates.js; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*;
import gplx.xowa.guis.cbks.*;
import gplx.core.ios.zips.*;
public class Xojs_wkr__unzip extends Xojs_wkr__base {
private final Io_url src, trg;
public Xojs_wkr__unzip(Xog_cbk_mgr cbk_mgr, Xog_cbk_trg cbk_trg, String js_cbk, Gfo_invk_cmd done_cbk, Io_url src, Io_url trg, long prog_data_end) {super(cbk_mgr, cbk_trg, js_cbk, done_cbk);
this.src = src; this.trg = trg;
this.Prog_data_end_(prog_data_end);
}
@Override protected void Exec_run() {
Io_zip_decompress_cmd decompress = Io_zip_decompress_cmd_.Proto.Make_new();
List_adp unzip_urls = List_adp_.New();
decompress.Exec(this, src, trg, unzip_urls);
}
}

@ -16,24 +16,28 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.apps.updates.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*;
import gplx.langs.jsons.*;
import gplx.xowa.htmls.bridges.*;
import gplx.langs.jsons.*; import gplx.xowa.htmls.bridges.*;
public class Xoa_update_bridge implements Bridge_cmd_itm {
private Xoa_app app;
public void Init_by_app(Xoa_app app) {
this.app = app;
}
public String Exec(Json_nde data) {
byte proc_id = proc_hash.Get_as_byte_or(data.Get_as_bry_or(Bridge_cmd_mgr.Msg__proc, null), Byte_ascii.Max_7_bit);
// Json_nde args = data.Get_kv(Bridge_cmd_mgr.Msg__args).Val_as_nde();
Json_nde args = data.Get_kv(Bridge_cmd_mgr.Msg__args).Val_as_nde();
switch (proc_id) {
case Proc__download_and_update: break;
case Proc__download:
Xoa_update_controller controller = new Xoa_update_controller();
controller.Update_app(app, args.Get_as_str("src"), args.Get_as_str("trg"), args.Get_as_long("src_len"));
break;
default: throw Err_.new_unhandled_default(proc_id);
}
return "";
}
private static final byte Proc__download_and_update = 0;
private static final byte Proc__download = 0;
private static final Hash_adp_bry proc_hash = Hash_adp_bry.cs()
.Add_str_byte("download_and_update" , Proc__download_and_update)
.Add_str_byte("download" , Proc__download)
;
public byte[] Key() {return BRIDGE_KEY;} public static final byte[] BRIDGE_KEY = Bry_.new_a7("app.updater");

@ -0,0 +1,43 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.apps.updates.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*;
import gplx.xowa.guis.cbks.*;
import gplx.xowa.addons.apps.updates.js.*;
class Xoa_update_controller implements Gfo_invk {
public void Update_app(Xoa_app app, String src, String trg_str, long src_len) {
Io_url trg = Io_url_.new_any_(trg_str);
Xog_cbk_mgr cbk_mgr = app.Gui__cbk_mgr();
Xog_cbk_trg cbk_trg = Xog_cbk_trg.New(Xoa_update_special.Prototype.Special__meta().Ttl_bry());
Xojs_wkr__download download_wkr = new Xojs_wkr__download(cbk_mgr, cbk_trg, "xo.app_updater.download__prog", Gfo_invk_cmd.New_by_key(this, Invk__download_done), src, trg, src_len);
download_wkr.Exec_async("app_updater");
}
private void On_download_done(GfoMsg m) {
Xojs_wkr__download download_wkr = (Xojs_wkr__download)m.ReadObj("v");
Io_url trg = download_wkr.Trg();
Xojs_wkr__unzip unzip_wkr = new Xojs_wkr__unzip(download_wkr.Cbk_mgr(), download_wkr.Cbk_trg(), "xo.app_updater.download__prog", Gfo_invk_cmd.New_by_key(this, Invk__unzip_done), trg, trg.OwnerDir().GenSubDir(trg.NameOnly()), download_wkr.Prog_data_end());
unzip_wkr.Exec_async("app_updater");
}
private void On_unzip_done(GfoMsg m) {
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk__download_done)) On_download_done(m);
else if (ctx.Match(k, Invk__unzip_done)) On_unzip_done(m);
else return Gfo_invk_.Rv_unhandled;
return this;
} private static final String Invk__download_done = "download_done", Invk__unzip_done = "unzip_done";
}

@ -24,9 +24,9 @@ class Xoa_update_html extends Xow_special_wtr__base {
@Override protected Mustache_doc_itm Bld_mustache_root(Xoa_app app) {
Io_url update_db_url = Get_addon_dir(app).GenSubFil("xoa_update.sqlite3");
Xoa_update_db_mgr db_mgr = new Xoa_update_db_mgr(update_db_url);
return Load(db_mgr);
return Load(app, db_mgr);
}
private static Mustache_doc_itm Load(Xoa_update_db_mgr db_mgr) {
private static Mustache_doc_itm Load(Xoa_app app, Xoa_update_db_mgr db_mgr) {
// get from internet
if (gplx.core.ios.IoEngine_system.Web_access_enabled) {
Io_url trg_url = db_mgr.Url();
@ -35,17 +35,25 @@ class Xoa_update_html extends Xow_special_wtr__base {
}
// load from db
String check_date = "2016-11-01 02:03:04";
String check_date = app.User().User_db_mgr().Cfg().Get_app_str_or("app.updater.last_check", null);
if (check_date == null) check_date = Datetime_now.Get().XtoStr_fmt_yyyy_MM_dd_HH_mm_ss();
Xoa_app_version_itm[] db_itms = db_mgr.Tbl__app_version().Select_by_date(Xoa_app_.Build_date);
String build_date = String_.Mid(Xoa_app_.Build_date, 0, String_.FindFwd(Xoa_app_.Build_date, " "));
if (db_itms.length == 0) return new Xoa_update_itm__root(Xoa_app_.Version, build_date, check_date, "", "", Xoa_app_version_itm.Priority__trivial, "", "");
if (db_itms.length == 0) return new Xoa_update_itm__root(Xoa_app_.Version, build_date, check_date, "", "", "", Xoa_app_version_itm.Priority__trivial, "", "");
// convert to gui itm
Xoa_app_version_itm db_itm = db_itms[0];
Xoa_update_itm__root root = new Xoa_update_itm__root(Xoa_app_.Version, build_date, check_date, db_itm.Name(), db_itm.Date(), db_itm.Priority(), db_itm.Summary(), db_itm.Details());
String download_url = Gen_download_url(db_itm.Url(), db_itm.Name());
Xoa_update_itm__root root = new Xoa_update_itm__root(Xoa_app_.Version, build_date, download_url, check_date, db_itm.Name(), db_itm.Date(), db_itm.Priority(), db_itm.Summary(), db_itm.Details());
root.Itms_(To_gui_itm(db_itms));
return root;
}
private static String Gen_download_url(String version_url, String version_name) {
String folder = version_url;
if (String_.Len_eq_0(folder))
folder = "https://github.com/gnosygnu/xowa/releases/download/v"; // + 3.11.2.1/xowa_app_windows_64_v3.11.2.1.zip";
return String_.Format("{0}{1}/xowa_app_{2}_v{2}.zip", folder, version_name, Xoa_app_.Op_sys_str);
}
private static Xoa_update_itm__leaf[] To_gui_itm(Xoa_app_version_itm[] db_itms) {
int len = db_itms.length;
Xoa_update_itm__leaf[] rv = new Xoa_update_itm__leaf[len];
@ -65,8 +73,10 @@ class Xoa_update_html extends Xow_special_wtr__base {
Xopg_tag_wtr_.Add__xolog (head_tags, app.Fsys_mgr().Http_root());
Xopg_tag_wtr_.Add__xoajax (head_tags, app.Fsys_mgr().Http_root(), app);
Xopg_alertify_.Add_tags (head_tags, app.Fsys_mgr().Http_root());
Xopg_tag_wtr_.Add__xoajax (head_tags, app.Fsys_mgr().Http_root(), app);
head_tags.Add(Xopg_tag_itm.New_css_file(addon_dir.GenSubFil_nest("bin", "xoa_update.css")));
head_tags.Add(Xopg_tag_itm.New_js_file(addon_dir.GenSubFil_nest("bin", "xoa_update.js")));
head_tags.Add(Xopg_tag_itm.New_js_file(addon_dir.GenSubFil_nest("bin", "xobc.util.js")));
}
}

@ -17,14 +17,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.apps.updates.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*;
import gplx.langs.mustaches.*;
class Xoa_update_itm__root extends Xoa_update_itm__leaf { private final String current_version, current_date, check_date;
class Xoa_update_itm__root extends Xoa_update_itm__leaf { private final String current_version, current_date, download_url, check_date;
private Xoa_update_itm__leaf[] itms = Xoa_update_itm__leaf.Ary__empty;
public Xoa_update_itm__root
( String current_version, String current_date, String check_date
( String current_version, String current_date, String download_url, String check_date
, String version, String date, int priority, String summary, String details
) {super(version, date, priority, summary, details);
this.current_version = current_version;
this.current_date = current_date;
this.download_url = download_url;
this.check_date = check_date;
}
public void Itms_(Xoa_update_itm__leaf[] v) {
@ -33,6 +34,7 @@ class Xoa_update_itm__root extends Xoa_update_itm__leaf { private final Stri
@Override public boolean Mustache__write(String k, Mustache_bfr bfr) {
if (String_.Eq(k, "current_version")) bfr.Add_str_u8(current_version);
else if (String_.Eq(k, "current_date")) bfr.Add_str_u8(current_date);
else if (String_.Eq(k, "download_url")) bfr.Add_str_u8(download_url);
else if (String_.Eq(k, "check_date")) bfr.Add_str_u8(check_date);
return super.Mustache__write (k, bfr);
}

Loading…
Cancel
Save