diff --git a/100_core/src/gplx/core/envs/Runtime_.java b/100_core/src/gplx/core/envs/Runtime_.java index 34d397c12..98d4667df 100644 --- a/100_core/src/gplx/core/envs/Runtime_.java +++ b/100_core/src/gplx/core/envs/Runtime_.java @@ -22,4 +22,12 @@ public class Runtime_ { public static long Memory_max() {return Runtime.getRuntime().maxMemory();} public static long Memory_total() {return Runtime.getRuntime().totalMemory();} public static long Memory_free() {return Runtime.getRuntime().freeMemory();} + + public static void Exec(String v) { + try { + Runtime.getRuntime().exec(v); + } catch (Exception e) { + Gfo_usr_dlg_.Instance.Log_many("", "", "runtime exec failed; err=~{0}", Err_.Message_gplx_log(e)); + } + } } \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_item.java b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_item.java index af5922c28..cf6fee04e 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_item.java +++ b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_item.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.apps.updates.apps; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*; -class Xoa_manifest_item { +public class Xoa_manifest_item { public Xoa_manifest_item(Io_url src, Io_url trg) { this.src = src; this.trg = trg; diff --git a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_list.java b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_list.java index 9847d5f33..aeef06ff3 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_list.java +++ b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_list.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.apps.updates.apps; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*; -class Xoa_manifest_list { +public class Xoa_manifest_list { private final Ordered_hash hash = Ordered_hash_.New(); public int Len() {return hash.Len();} public Xoa_manifest_item Get_at(int i) {return (Xoa_manifest_item)hash.Get_at(i);} diff --git a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_view.java b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_view.java index eac89ca9c..3ab43fc0c 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_view.java +++ b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_view.java @@ -16,17 +16,99 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.apps.updates.apps; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*; -public class Xoa_manifest_view { +import gplx.core.envs.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.*; +import javax.swing.*; +import javax.swing.border.Border; +public class Xoa_manifest_view extends JFrame implements Gfo_invk { private final Xoa_manifest_wkr wkr; - public Xoa_manifest_view(String manifest_url) { - this.wkr = new Xoa_manifest_wkr(this); + private String run_xowa_cmd; + public Xoa_manifest_view(Io_url manifest_url) { + super("XOWA Application Update"); + // init window + this.setTitle("XOWA Application Update"); + try { + UIManager.setLookAndFeel( + UIManager.getSystemLookAndFeelClassName()); + } + catch (Exception e) {System.out.println(e.getMessage());} + this.setSize(700, 580); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setLocationRelativeTo(null); + this.setBackground(Color.WHITE); + + // init panel + JPanel main_panel = new JPanel(); + main_panel.setSize(700, 580); + this.setContentPane(main_panel); + New_text_area(main_panel); + run_xowa_lbl = New_link_lbl(this, main_panel, Invk__run_xowa, "Run XOWA"); + this.setVisible(true); + this.wkr = new Xoa_manifest_wkr(this); wkr.Init(manifest_url); } - public void Append(String s) { - } + private JTextArea text_area; + private JLabel run_xowa_lbl; + private JScrollPane New_text_area(JPanel owner) { + // init textarea + text_area = new JTextArea(); + text_area.setForeground(Color.BLACK); + text_area.setBackground(Color.WHITE); + text_area.setMargin(new Insets(0, 0, 0,0)); + text_area.setLineWrap(true); + text_area.setWrapStyleWord(true); // else text will wrap in middle of words + text_area.setCaretColor(Color.BLACK); + text_area.getCaret().setBlinkRate(0); + + // init scrollpane + JScrollPane text_scroll_pane = new JScrollPane(text_area); + text_scroll_pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + owner.add(text_scroll_pane, BorderLayout.CENTER); + text_scroll_pane.setPreferredSize(new Dimension(675, 500)); + return text_scroll_pane; + } + private static JLabel New_link_lbl(Gfo_invk invk, JPanel owner, String invk_cmd, String text) { + JLabel rv = new JLabel(); + rv.setText(text); + rv.setPreferredSize(new Dimension(80, 20)); + owner.add(rv, BorderLayout.PAGE_END); + return rv; + } + public void Append(String s) { + text_area.setText(text_area.getText() + "> " + s + "\n"); + } + public void Mark_done(String s) { + this.run_xowa_cmd = s; + run_xowa_lbl.setText("Run XOWA"); + run_xowa_lbl.setCursor(new Cursor(Cursor.HAND_CURSOR)); + run_xowa_lbl.addMouseListener(new Swing_mouse_adapter(Gfo_invk_cmd.New_by_key(this, Invk__run_xowa))); + } + public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + if (ctx.Match(k, Invk__run_xowa)) { + Runtime_.Exec(run_xowa_cmd); + System_.Exit(); + } + else return Gfo_invk_.Rv_unhandled; + return this; + } private static final String Invk__run_xowa = "run_xowa"; - public static void Run(String manifest_url) { - if (!gplx.core.envs.Op_sys.Cur().Tid_is_osx()) + public static void Run() { + Io_url manifest_url = Env_.AppUrl().GenNewExt(".txt"); + if (!Op_sys.Cur().Tid_is_osx()) new Xoa_manifest_view(manifest_url); } } +class Swing_mouse_adapter extends MouseAdapter { + private final Gfo_invk_cmd cmd; + public Swing_mouse_adapter(Gfo_invk_cmd cmd) {this.cmd = cmd;} + @Override public void mouseClicked(MouseEvent ev) { + try {cmd.Exec();} + catch (Exception e) { + System.out.println(Err_.Message_gplx_full(e)); + } + } +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_wkr.java b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_wkr.java index c565ba497..6a427ac99 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_wkr.java +++ b/400_xowa/src/gplx/xowa/addons/apps/updates/apps/Xoa_manifest_wkr.java @@ -16,24 +16,25 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.addons.apps.updates.apps; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.updates.*; +import gplx.core.envs.*; class Xoa_manifest_wkr { private final Xoa_manifest_view view; private final Xoa_manifest_list list = new Xoa_manifest_list(); private Io_url manifest_url; - private byte[] run_xowa_cmd; + private String run_xowa_cmd; public Xoa_manifest_wkr(Xoa_manifest_view view) { this.view = view; } - public void Init(String manifest_url_str) { + public void Init(Io_url manifest_url) { // load manifest - view.Append("loading manifest from: " + manifest_url_str); - this.manifest_url = Io_url_.new_any_(manifest_url_str); + this.manifest_url = manifest_url; + view.Append("loading manifest from: " + manifest_url.Raw()); byte[] src = Io_mgr.Instance.LoadFilBry(manifest_url); // parse manifest int nl_pos = Bry_find_.Find_fwd(src, Byte_ascii.Nl); - if (nl_pos == Bry_find_.Not_found) throw Err_.new_wo_type("could not find nl in manifest", "manifest_url", manifest_url_str); - this.run_xowa_cmd = Bry_.Mid(src, 0, nl_pos); + if (nl_pos == Bry_find_.Not_found) throw Err_.new_wo_type("could not find nl in manifest", "manifest_url", manifest_url.Raw()); + this.run_xowa_cmd = String_.new_u8(src, 0, nl_pos); list.Load(src, nl_pos + 1, src.length); this.Wait(); @@ -53,12 +54,11 @@ class Xoa_manifest_wkr { view.Append("waiting for XOWA to release file: " + topmost); } } + this.On_exit(); } public void On_exit() { Io_mgr.Instance.DeleteFil(manifest_url); - if (run_xowa_cmd != null) - // gplx.core.envs.Process_adp.run_wait_arg_; - gplx.core.envs.System_.Exit(); + view.Mark_done(run_xowa_cmd); } private boolean Copy_files() { // loop list and copy items @@ -69,9 +69,10 @@ class Xoa_manifest_wkr { try { Io_mgr.Instance.DeleteFil_args(item.Trg()).MissingFails_off().Exec(); Io_mgr.Instance.CopyFil(item.Src(), item.Trg(), true); + view.Append(String_.Format("copied file: src={0} trg={1}", item.Src().Raw(), item.Trg().Raw())); } catch (Exception exc) { - view.Append(String_.Format("failed to copy file: src={0} trg ={1} err={2}", item.Src().Raw(), item.Trg().Raw(), Err_.Message_lang(exc))); + view.Append(String_.Format("failed to copy file: src={0} trg={1} err={2}", item.Src().Raw(), item.Trg().Raw(), Err_.Message_lang(exc))); return false; } } diff --git a/400_xowa/src/gplx/xowa/addons/apps/updates/js/Xojs_wkr__replace.java b/400_xowa/src/gplx/xowa/addons/apps/updates/js/Xojs_wkr__replace.java index 39c5dd673..0b811b0d3 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/updates/js/Xojs_wkr__replace.java +++ b/400_xowa/src/gplx/xowa/addons/apps/updates/js/Xojs_wkr__replace.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ 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.xowa.guis.cbks.*; public class Xojs_wkr__replace extends Xojs_wkr__base { private final Io_url src_dir, trg_dir; private final Io_url[] src_fils; @@ -26,20 +26,30 @@ public class Xojs_wkr__replace extends Xojs_wkr__base { this.src_fils = Io_mgr.Instance.QueryDir_args(src_dir).Recur_().ExecAsUrlAry(); this.Prog_data_end_(src_fils.length); } + public Keyval[] Failed() {return failed;} private Keyval[] failed = Keyval_.Ary_empty; @Override protected void Exec_run() { + List_adp failed_list = List_adp_.New(); + int len = src_fils.length; for (int i = 0; i < len; i++) { + if (this.Prog_notify_and_chk_if_suspended(i, len)) return; // stop if canceled + Io_url src_fil = src_fils[i]; Io_url trg_fil = trg_dir.GenSubFil(src_fil.GenRelUrl_orEmpty(src_dir)); - // Io_url trg_fil_del = trg_fil.GenNewNameAndExt(trg_fil.NameAndExt() + ".del"); try { -// Io_mgr.Instance.DeleteFil(trg_fil); -// Io_mgr.Instance.MoveFil_args(src_fil, trg_fil, true).Exec(); - - Io_mgr.Instance.CopyFil(src_fil, trg_fil, true); + Io_mgr.Instance.DeleteFil(trg_fil); // delete first; will fail if file is in use + Io_mgr.Instance.MoveFil_args(src_fil, trg_fil, true).Exec(); // replace with src file } catch (Exception exc) { - Tfds.Write(src_fil, Err_.Message_lang(exc)); + Gfo_usr_dlg_.Instance.Log_many("failed to delete and move file; file=~{0} msg=~{1}", trg_fil.Raw(), Err_.Message_gplx_log(exc)); + failed_list.Add(Keyval_.new_(src_fil.Raw(), trg_fil.Raw())); + try { + Io_mgr.Instance.CopyFil(src_fil, trg_fil, true); // try to copy file anyway + } catch (Exception exc2) { + Gfo_usr_dlg_.Instance.Log_many("failed to fopy file; file=~{0} msg=~{1}", trg_fil.Raw(), Err_.Message_gplx_log(exc2)); + } } } + + this.failed = (Keyval[])failed_list.To_ary_and_clear(Keyval.class); } } diff --git a/400_xowa/src/gplx/xowa/addons/apps/updates/specials/Xoa_update_controller.java b/400_xowa/src/gplx/xowa/addons/apps/updates/specials/Xoa_update_controller.java index 2213d07d0..0cebd6a54 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/updates/specials/Xoa_update_controller.java +++ b/400_xowa/src/gplx/xowa/addons/apps/updates/specials/Xoa_update_controller.java @@ -18,11 +18,14 @@ along with this program. If not, see . 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.core.gfobjs.*; -import gplx.xowa.addons.apps.updates.dbs.*; import gplx.xowa.addons.apps.updates.js.*; +import gplx.xowa.addons.apps.updates.dbs.*; import gplx.xowa.addons.apps.updates.js.*; +import gplx.xowa.addons.apps.updates.apps.*; class Xoa_update_controller implements Gfo_invk { + private Io_url app_root_dir, update_dir; public void Update_app(Xoa_app app, String version_name) { // get app_version from db - Io_url update_dir = app.Fsys_mgr().Root_dir().GenSubDir_nest("user", "app", "update"); + this.app_root_dir = app.Fsys_mgr().Root_dir(); + this.update_dir = app_root_dir.GenSubDir_nest("user", "app", "update"); Io_url update_db_fil = update_dir.GenSubFil_nest("xoa_update.sqlite3"); Xoa_update_db_mgr db_mgr = new Xoa_update_db_mgr(update_db_fil); Xoa_app_version_itm version_itm = db_mgr.Tbl__app_version().Select_by_version_or_null(version_name); @@ -50,13 +53,39 @@ class Xoa_update_controller implements Gfo_invk { Xojs_wkr__unzip unzip_wkr = (Xojs_wkr__unzip)m.ReadObj("v"); Io_url src = unzip_wkr.Trg(); Io_url trg = Io_url_.new_dir_("D:\\xowa_temp\\"); + + // copy update_jar + Io_url src_jar_fil = app_root_dir.GenSubFil_nest("bin", "any", "xowa", "addon", "app", "update", "xoa_update.jar"); + Io_url trg_jar_fil = update_dir.GenSubFil_nest("xoa_update.jar"); + Io_mgr.Instance.MoveFil_args(src_jar_fil, trg_jar_fil, true).MissingFails_off().Exec(); + Xojs_wkr__replace replace_wkr = new Xojs_wkr__replace(unzip_wkr.Cbk_mgr(), unzip_wkr.Cbk_trg(), "xo.app_updater.download__prog", Gfo_invk_cmd.New_by_key(this, Invk__replace_done), src, trg); replace_wkr.Exec_async("app_updater"); } private void On_replace_done(GfoMsg m) { Xojs_wkr__replace replace_wkr = (Xojs_wkr__replace)m.ReadObj("v"); + + // get failed + Xoa_manifest_list list = new Xoa_manifest_list(); + Keyval[] failed_ary = replace_wkr.Failed(); + int len = failed_ary.length; + for (int i = 0; i < len; i++) { + Keyval failed = failed_ary[i]; + list.Add(Io_url_.new_fil_(failed.Key()), Io_url_.new_fil_(failed.Val_to_str_or_empty())); + } + + // write failed + Bry_bfr bfr = Bry_bfr_.New(); + Write_restart(bfr); + list.Save(bfr); + Io_mgr.Instance.SaveFilBfr(update_dir.GenSubFil("xoa_update.txt"), bfr); + replace_wkr.Cbk_mgr().Send_json(replace_wkr.Cbk_trg(), "xo.app_updater.download__prog", Gfobj_nde.New().Add_bool("done", true)); } + private void Write_restart(Bry_bfr bfr) { + String restart = String_.Format("D:\\xowa_temp\\xowa_64.exe\n"); + bfr.Add_str_u8(restart); + } 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); diff --git a/400_xowa/src/gplx/xowa/htmls/hrefs/Xoh_href_parser.java b/400_xowa/src/gplx/xowa/htmls/hrefs/Xoh_href_parser.java index 0d8586587..f74441f60 100644 --- a/400_xowa/src/gplx/xowa/htmls/hrefs/Xoh_href_parser.java +++ b/400_xowa/src/gplx/xowa/htmls/hrefs/Xoh_href_parser.java @@ -70,7 +70,7 @@ public class Xoh_href_parser { } } rv.Page_bry_(tmp_page); - if (tmp_page == null) { // handle xwiki lnke's to history page else null ref; EX:[http://ru.wikipedia.org/w/index.php?title&diff=19103464&oldid=18910980 ???????]; PAGE:ru.w:Project:??????_??_??????_??????/?????/?????????????/2009 DATE:2016-11-24 + if (tmp_page == null) { // handle xwiki lnke's to history page else null ref; EX:[http://ru.wikipedia.org/w/index.php?title&diff=19103464&oldid=18910980 извещен]; PAGE:ru.w:Project:Заявки_на_снятие_флагов/Архив/Патрулирующие/2009 DATE:2016-11-24 rv.Tid_(Xoa_url_.Tid_inet); } break;