Przeglądaj źródła

Updater: Initial commit of standalone update app

gnosygnu 8 lat temu
rodzic
commit
c9d1193e7f

+ 7 - 0
401_xowa_updater/.classpath

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/100_core"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 26 - 0
401_xowa_updater/src/gplx/xowa/Xoa_manifest_item.java

@@ -0,0 +1,26 @@
+/*
+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; import gplx.*;
+public class Xoa_manifest_item {
+	public Xoa_manifest_item(Io_url src, Io_url trg) {
+		this.src = src;
+		this.trg = trg;
+	}
+	public Io_url Src() {return src;} private final    Io_url src;
+	public Io_url Trg() {return trg;} private final    Io_url trg;
+}

+ 61 - 0
401_xowa_updater/src/gplx/xowa/Xoa_manifest_list.java

@@ -0,0 +1,61 @@
+/*
+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; import gplx.*;
+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);}
+	public void Del_at(int i) {
+		Xoa_manifest_item item = (Xoa_manifest_item)hash.Get_at(i);
+		hash.Del(item.Src().Raw());
+	}
+	public void Add(Io_url src, Io_url trg) {
+		Xoa_manifest_item item = new Xoa_manifest_item(src, trg);
+		hash.Add(src.Raw(), item);
+	}
+	public void Save(Bry_bfr bfr) {
+		// save as "src\ttrg\n"
+		int len = hash.Len();
+		for (int i = 0; i < len; i++) {
+			Xoa_manifest_item item = (Xoa_manifest_item)hash.Get_at(i);
+			bfr.Add_str_u8(item.Src().Raw());
+			bfr.Add_byte(Byte_ascii.Tab);
+			bfr.Add_str_u8(item.Trg().Raw());
+			bfr.Add_byte(Byte_ascii.Nl);
+		}
+	}
+	public void Load(byte[] src, int src_bgn, int src_end) {
+		int pos = src_bgn;
+		// load by "src\ttrg\n"
+		while (pos < src_end) {
+			// get pos
+			int tab_pos = Bry_find_.Find_fwd(src, Byte_ascii.Tab, pos, src_end);
+			if (tab_pos == Bry_find_.Not_found) throw Err_.new_wo_type("failed to find tab", "excerpt", Bry_.Mid(src, pos, src_end));
+			int nl_pos  = Bry_find_.Find_fwd(src, Byte_ascii.Nl, tab_pos + 1, src_end);
+			if (nl_pos == Bry_find_.Not_found) throw Err_.new_wo_type("failed to find nl", "excerpt", Bry_.Mid(src, pos, src_end));
+
+			// create
+			Io_url src_url = Io_url_.new_fil_(String_.new_u8(src, pos, tab_pos));
+			Io_url trg_url = Io_url_.new_fil_(String_.new_u8(src, tab_pos + 1, nl_pos));
+			Xoa_manifest_item item = new Xoa_manifest_item(src_url, trg_url);
+			hash.Add(src_url.Raw(), item);
+
+			pos = nl_pos + 1;
+		}
+	}
+}

+ 113 - 0
401_xowa_updater/src/gplx/xowa/Xoa_manifest_view.java

@@ -0,0 +1,113 @@
+/*
+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; import gplx.*; import gplx.xowa.*;
+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;
+	private String run_xowa_cmd;
+	public Xoa_manifest_view(Io_url manifest_url, Io_url update_root) {
+				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, "<html><a href=\"\" style='color:#b9b9b9;'>Run XOWA</a></html>");
+		this.setVisible(true);
+				this.wkr = new Xoa_manifest_wkr(this);
+		wkr.Init(manifest_url, update_root);
+	}
+		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("<html><a href=\"\"'>Run XOWA</a></html>");
+		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 void Run_xowa() {
+		Runtime_.Exec(run_xowa_cmd);
+		System_.Exit();
+	}
+	public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
+		if		(ctx.Match(k, Invk__run_xowa)) Run_xowa();
+		else	return Gfo_invk_.Rv_unhandled;
+		return this;
+	}	private static final    String Invk__run_xowa = "run_xowa";
+
+	public static void Run(Io_url manifest_url, Io_url update_root) {
+		new Xoa_manifest_view(manifest_url, update_root);
+	}
+}
+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));
+		}
+	}
+}

+ 92 - 0
401_xowa_updater/src/gplx/xowa/Xoa_manifest_wkr.java

@@ -0,0 +1,92 @@
+/*
+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; import gplx.*;
+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, update_root;
+	private String run_xowa_cmd;
+	public Xoa_manifest_wkr(Xoa_manifest_view view) {
+		this.view = view;
+	}
+	public void Init(Io_url manifest_url, Io_url update_root) {
+		// load manifest
+		this.manifest_url = manifest_url;
+		this.update_root = update_root;
+		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.Raw());
+		this.run_xowa_cmd = String_.new_u8(src, 0, nl_pos);
+		list.Load(src, nl_pos + 1, src.length);
+		
+		this.Wait();
+	}
+	private void Wait() {
+		int tries = 0;
+		while (tries++ < 100) {
+			gplx.core.threads.Thread_adp_.Sleep(1000);
+			if (Copy_files())
+				break;
+			else {
+				String topmost = "#error";
+				if (list.Len() > 0) {
+					Xoa_manifest_item item = (Xoa_manifest_item)list.Get_at(0);
+					topmost = item.Src().Raw();
+				}
+				view.Append("waiting for XOWA to release file: " + topmost);
+			}
+		}
+		this.On_exit();
+	}
+	public void On_exit() {
+		// delte update root and manifest_url
+		view.Append("deleting update dir: " + update_root.Raw());
+		Io_mgr.Instance.DeleteDirDeep(update_root);
+		Io_mgr.Instance.DeleteFil(manifest_url);
+		
+		view.Mark_done(run_xowa_cmd);
+		view.Run_xowa();
+	}
+	private boolean Copy_files() {
+		// loop list and copy items
+		int len = list.Len();
+		int idx = 0;
+		for (idx = 0; idx < len; idx++) {
+			Xoa_manifest_item item = (Xoa_manifest_item)list.Get_at(idx);
+			try {
+				Io_mgr.Instance.DeleteFil_args(item.Trg()).MissingFails_off().Exec();
+				Io_mgr.Instance.MoveFil_args(item.Src(), item.Trg(), true).Exec();;
+				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)));
+				return false;
+			}
+		}
+
+		// remove completed items
+		for (int i = 0; i < idx; i++) {
+			list.Del_at(0);
+		}
+		return true;
+	}
+}

+ 30 - 0
401_xowa_updater/src/gplx/xowa/Xowa_app_updater.java

@@ -0,0 +1,30 @@
+/*
+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;
+import gplx.Io_url_;
+import gplx.core.envs.*;
+public class Xowa_app_updater {
+	public static void main(String[] args) {
+		Env_.Init_swt(args, Xowa_app_updater.class);
+		if (args.length == 0) {
+			System.out.println("could not run app_updater; must pass 2 arguments: manifest url and update_root");
+			return;
+		}
+		Xoa_manifest_view.Run(Io_url_.new_fil_(args[0]), Io_url_.new_dir_(args[1]));
+	}
+}