1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2025-06-13 12:54:14 +00:00

Edit: Save compiled HTML when editing pages [#699]

This commit is contained in:
gnosygnu 2020-08-06 07:09:34 -04:00
parent dc374fa7fc
commit 0aced904a5
11 changed files with 1471 additions and 1310 deletions

View File

@ -1,309 +1,310 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis. for your project on a case-by-case basis.
The terms of each license can be found in the source code repository: The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.guis.views; package gplx.xowa.guis.views;
import gplx.Bry_; import gplx.Bry_;
import gplx.Bry_find_; import gplx.Bry_find_;
import gplx.Err_; import gplx.Err_;
import gplx.GfoMsg; import gplx.GfoMsg;
import gplx.Gfo_evt_mgr_; import gplx.Gfo_evt_mgr_;
import gplx.Gfo_invk; import gplx.Gfo_invk;
import gplx.Gfo_invk_; import gplx.Gfo_invk_;
import gplx.Gfo_usr_dlg; import gplx.Gfo_usr_dlg;
import gplx.GfsCtx; import gplx.GfsCtx;
import gplx.Int_; import gplx.Int_;
import gplx.List_adp; import gplx.List_adp;
import gplx.String_; import gplx.String_;
import gplx.core.envs.Env_; import gplx.core.envs.Env_;
import gplx.core.threads.Gfo_thread_wkr; import gplx.core.threads.Gfo_thread_wkr;
import gplx.gfui.controls.elems.GfuiElem; import gplx.gfui.controls.elems.GfuiElem;
import gplx.gfui.controls.elems.GfuiElemKeys; import gplx.gfui.controls.elems.GfuiElemKeys;
import gplx.gfui.controls.standards.Gfui_html; import gplx.gfui.controls.standards.Gfui_html;
import gplx.gfui.controls.standards.Gfui_tab_itm; import gplx.gfui.controls.standards.Gfui_tab_itm;
import gplx.gfui.controls.standards.Gfui_tab_itm_data; import gplx.gfui.controls.standards.Gfui_tab_itm_data;
import gplx.gfui.ipts.IptBnd_; import gplx.gfui.ipts.IptBnd_;
import gplx.gfui.ipts.IptCfg_; import gplx.gfui.ipts.IptCfg_;
import gplx.gfui.ipts.IptEventType_; import gplx.gfui.ipts.IptEventType_;
import gplx.gfui.ipts.IptKey_; import gplx.gfui.ipts.IptKey_;
import gplx.gfui.ipts.IptMouseBtn_; import gplx.gfui.ipts.IptMouseBtn_;
import gplx.gfui.kits.core.Gfui_kit; import gplx.gfui.kits.core.Gfui_kit;
import gplx.xowa.Xoa_app; import gplx.xowa.Xoa_app;
import gplx.xowa.Xoa_page; import gplx.xowa.Xoa_page;
import gplx.xowa.Xoa_ttl; import gplx.xowa.Xoa_ttl;
import gplx.xowa.Xoa_url; import gplx.xowa.Xoa_url;
import gplx.xowa.Xoa_url_; import gplx.xowa.Xoa_url_;
import gplx.xowa.Xoae_app; import gplx.xowa.Xoae_app;
import gplx.xowa.Xoae_page; import gplx.xowa.Xoae_page;
import gplx.xowa.Xow_wiki; import gplx.xowa.Xow_wiki;
import gplx.xowa.Xowe_wiki; import gplx.xowa.Xowe_wiki;
import gplx.xowa.files.Xof_file_wkr; import gplx.xowa.files.Xof_file_wkr;
import gplx.xowa.files.Xog_redlink_thread; import gplx.xowa.files.Xog_redlink_thread;
import gplx.xowa.guis.Xoa_gui_mgr; import gplx.xowa.guis.Xoa_gui_mgr;
import gplx.xowa.guis.bnds.Xog_bnd_box_; import gplx.xowa.guis.bnds.Xog_bnd_box_;
import gplx.xowa.guis.history.Xog_history_mgr; import gplx.xowa.guis.history.Xog_history_mgr;
import gplx.xowa.wikis.pages.Xopg_view_mode_; import gplx.xowa.wikis.pages.Xopg_view_mode_;
import gplx.xowa.wikis.pages.dbs.Xopg_db_page;
public class Xog_tab_itm implements Gfo_invk {
private Xog_win_itm win; public class Xog_tab_itm implements Gfo_invk {
public Xog_tab_itm(Xog_tab_mgr tab_mgr, Gfui_tab_itm_data tab_data, Xowe_wiki wiki, Xoae_page page) { private Xog_win_itm win;
this.tab_mgr = tab_mgr; this.tab_data = tab_data; this.wiki = wiki; this.page = page; public Xog_tab_itm(Xog_tab_mgr tab_mgr, Gfui_tab_itm_data tab_data, Xowe_wiki wiki, Xoae_page page) {
this.win = tab_mgr.Win(); this.tab_mgr = tab_mgr; this.tab_data = tab_data; this.wiki = wiki; this.page = page;
this.html_itm = new Xog_html_itm(this); this.win = tab_mgr.Win();
cmd_sync = win.Kit().New_cmd_sync(this); this.html_itm = new Xog_html_itm(this);
} cmd_sync = win.Kit().New_cmd_sync(this);
public Xowe_wiki Wiki() {return wiki;} public void Wiki_(Xowe_wiki v) {this.wiki = v;} private Xowe_wiki wiki; }
public Gfo_invk Cmd_sync() {return cmd_sync;} private Gfo_invk cmd_sync; public Xowe_wiki Wiki() {return wiki;} public void Wiki_(Xowe_wiki v) {this.wiki = v;} private Xowe_wiki wiki;
public void Make_html_box(int uid, Gfui_tab_itm tab_box, Xog_win_itm win, GfuiElem owner) { public Gfo_invk Cmd_sync() {return cmd_sync;} private Gfo_invk cmd_sync;
this.tab_box = tab_box; public void Make_html_box(int uid, Gfui_tab_itm tab_box, Xog_win_itm win, GfuiElem owner) {
Xoae_app app = win.App(); Xoa_gui_mgr gui_mgr = win.Gui_mgr(); Gfui_kit kit = win.Kit(); this.tab_box = tab_box;
Gfui_html html_box = kit.New_html("html_box" + Int_.To_str(uid), owner); Xoae_app app = win.App(); Xoa_gui_mgr gui_mgr = win.Gui_mgr(); Gfui_kit kit = win.Kit();
html_box.Html_js_enabled_(tab_mgr.Javascript_enabled()); Gfui_html html_box = kit.New_html("html_box" + Int_.To_str(uid), owner);
html_box.Html_invk_src_(win); html_box.Html_js_enabled_(tab_mgr.Javascript_enabled());
html_itm.Html_box_(html_box); html_box.Html_invk_src_(win);
if (app.Mode().Tid_is_gui()) { // NOTE: only run for gui; will cause firefox_addon to fail; DATE:2014-05-03 html_itm.Html_box_(html_box);
// NOTE: must set source, else control will be empty, and key events will not be raised; DATE:2014-04-30 if (app.Mode().Tid_is_gui()) { // NOTE: only run for gui; will cause firefox_addon to fail; DATE:2014-05-03
// NOTE: use load_by_url for nightmode else load_by_mem causes "white flashing" DATE:2017-03-04 // NOTE: must set source, else control will be empty, and key events will not be raised; DATE:2014-04-30
if (app.Gui_mgr().Nightmode_mgr().Enabled()) { // NOTE: use load_by_url for nightmode else load_by_mem causes "white flashing" DATE:2017-03-04
html_box.Html_doc_html_load_by_url if (app.Gui_mgr().Nightmode_mgr().Enabled()) {
( app.Usere().Fsys_mgr().App_temp_html_dir().GenSubFil("tab_new.html") html_box.Html_doc_html_load_by_url
, String_.new_u8(gplx.xowa.specials.xowa.default_tab.Default_tab_page.DEFAULT_HTML_NIGHT) ( app.Usere().Fsys_mgr().App_temp_html_dir().GenSubFil("tab_new.html")
); , String_.new_u8(gplx.xowa.specials.xowa.default_tab.Default_tab_page.DEFAULT_HTML_NIGHT)
} );
else { }
html_box.Html_doc_html_load_by_mem(""); else {
} html_box.Html_doc_html_load_by_mem("");
IptBnd_.ipt_to_(IptCfg_.Null, html_box, this, "popup", IptEventType_.MouseDown, IptMouseBtn_.Right); }
IptBnd_.cmd_to_(IptCfg_.Null, html_box, win, Xog_win_itm.Invk_exit, IptKey_.add_(IptKey_.Alt, IptKey_.F4)); // WORKAROUND:SWT: xulrunner_v24 no longer sends Alt+F4 to SwtShell; must manually subscribe it to quit; DATE:2015-07-31 IptBnd_.ipt_to_(IptCfg_.Null, html_box, this, "popup", IptEventType_.MouseDown, IptMouseBtn_.Right);
Gfo_evt_mgr_.Sub_same(html_box, GfuiElemKeys.Evt_menu_detected, html_itm); IptBnd_.cmd_to_(IptCfg_.Null, html_box, win, Xog_win_itm.Invk_exit, IptKey_.add_(IptKey_.Alt, IptKey_.F4)); // WORKAROUND:SWT: xulrunner_v24 no longer sends Alt+F4 to SwtShell; must manually subscribe it to quit; DATE:2015-07-31
gui_mgr.Bnd_mgr().Bind(Xog_bnd_box_.Tid_browser_html, html_box); Gfo_evt_mgr_.Sub_same(html_box, GfuiElemKeys.Evt_menu_detected, html_itm);
if (!Env_.Mode_testing()) gui_mgr.Bnd_mgr().Bind(Xog_bnd_box_.Tid_browser_html, html_box);
kit.Set_mnu_popup(html_box, gui_mgr.Menu_mgr().Popup().Html_page().Under_mnu()); if (!Env_.Mode_testing())
} kit.Set_mnu_popup(html_box, gui_mgr.Menu_mgr().Popup().Html_page().Under_mnu());
} }
public void Switch_mem(Xog_tab_itm comp) { }
// switch html_itm.owner_tab reference only public void Switch_mem(Xog_tab_itm comp) {
html_itm.Switch_mem(comp.html_itm); // switch html_itm.owner_tab reference only
html_itm.Switch_mem(comp.html_itm);
// switch .html_itm, since the underlying CTabFolder has reparented the control
Xog_html_itm temp_html_itm = html_itm; // switch .html_itm, since the underlying CTabFolder has reparented the control
this.html_itm = comp.html_itm; Xog_html_itm temp_html_itm = html_itm;
comp.html_itm = temp_html_itm; this.html_itm = comp.html_itm;
comp.html_itm = temp_html_itm;
// switch .page, since its underlying html_box has changed and .page must reflect html_box
Xoae_page temp_page = page; // switch .page, since its underlying html_box has changed and .page must reflect html_box
this.page = comp.page; Xoae_page temp_page = page;
comp.page = temp_page; this.page = comp.page;
page.Tab_data().Tab_(this); comp.Page().Tab_data().Tab_(comp); comp.page = temp_page;
page.Tab_data().Tab_(this); comp.Page().Tab_data().Tab_(comp);
// switch .wiki also; ISSUE#:761; DATE:2020-07-17
Xowe_wiki temp_wiki = wiki; // switch .wiki also; ISSUE#:761; DATE:2020-07-17
this.wiki = comp.wiki; Xowe_wiki temp_wiki = wiki;
comp.wiki = temp_wiki; this.wiki = comp.wiki;
comp.wiki = temp_wiki;
// switch .view_mode to match .page
byte temp_view_mode = view_mode; // switch .view_mode to match .page
this.view_mode = comp.view_mode; byte temp_view_mode = view_mode;
comp.view_mode = temp_view_mode; this.view_mode = comp.view_mode;
comp.view_mode = temp_view_mode;
// switch .history_mgr along with .page
Xog_history_mgr temp_history_mgr = history_mgr; // switch .history_mgr along with .page
this.history_mgr = comp.history_mgr; Xog_history_mgr temp_history_mgr = history_mgr;
comp.history_mgr = temp_history_mgr; this.history_mgr = comp.history_mgr;
} comp.history_mgr = temp_history_mgr;
public Gfui_tab_itm_data Tab_data() {return tab_data;} private Gfui_tab_itm_data tab_data; }
public String Tab_key() {return tab_data.Key();} public Gfui_tab_itm_data Tab_data() {return tab_data;} private Gfui_tab_itm_data tab_data;
public int Tab_idx() {return tab_data.Idx();} public void Tab_idx_(int v) {tab_data.Idx_(v);} public String Tab_key() {return tab_data.Key();}
public Xog_tab_mgr Tab_mgr() {return tab_mgr;} private Xog_tab_mgr tab_mgr; public int Tab_idx() {return tab_data.Idx();} public void Tab_idx_(int v) {tab_data.Idx_(v);}
public Gfui_tab_itm Tab_box() {return tab_box;} private Gfui_tab_itm tab_box; public Xog_tab_mgr Tab_mgr() {return tab_mgr;} private Xog_tab_mgr tab_mgr;
public boolean Tab_is_loading() {return tab_is_loading;} private boolean tab_is_loading; public Gfui_tab_itm Tab_box() {return tab_box;} private Gfui_tab_itm tab_box;
public Xog_html_itm Html_itm() {return html_itm;} private Xog_html_itm html_itm; public boolean Tab_is_loading() {return tab_is_loading;} private boolean tab_is_loading;
public Gfui_html Html_box() {return html_itm.Html_box();} public Xog_html_itm Html_itm() {return html_itm;} private Xog_html_itm html_itm;
public Xoae_page Page() {return page;} public Gfui_html Html_box() {return html_itm.Html_box();}
public void Page_ref_(Xoae_page v) { public Xoae_page Page() {return page;}
this.page = v; public void Page_ref_(Xoae_page v) {
this.wiki = page.Wikie(); // NOTE: must update wiki else back doesn't work; DATE:2015-03-05 this.page = v;
} this.wiki = page.Wikie(); // NOTE: must update wiki else back doesn't work; DATE:2015-03-05
public void Page_(Xoae_page page) { }
Page_ref_(page); public void Page_(Xoae_page page) {
this.Page_update_ui(); // force tab button to update when page changes Page_ref_(page);
} private Xoae_page page; this.Page_update_ui(); // force tab button to update when page changes
public void Page_update_ui() { } private Xoae_page page;
this.Tab_name_(); public void Page_update_ui() {
tab_box.Tab_tip_text_(page.Url().To_str()); this.Tab_name_();
} tab_box.Tab_tip_text_(page.Url().To_str());
public void Tab_name_() { }
byte[] tab_name = page.Html_data().Custom_tab_name(); // Custom_tab_name set by Special:Default_tab or variants; DATE:2015-10-05 public void Tab_name_() {
if (tab_name == null) tab_name = page.Ttl().Full_txt(); // no custom_tab_name; use ttl's text byte[] tab_name = page.Html_data().Custom_tab_name(); // Custom_tab_name set by Special:Default_tab or variants; DATE:2015-10-05
Tab_name_(String_.new_u8(tab_name)); if (tab_name == null) tab_name = page.Ttl().Full_txt(); // no custom_tab_name; use ttl's text
} Tab_name_(String_.new_u8(tab_name));
public void Tab_name_(String tab_name) { }
tab_name = Xog_tab_itm_.Tab_name_min(tab_name, tab_mgr.Btns__min_chars()); public void Tab_name_(String tab_name) {
tab_name = Xog_tab_itm_.Tab_name_max(tab_name, tab_mgr.Btns__max_chars()); tab_name = Xog_tab_itm_.Tab_name_min(tab_name, tab_mgr.Btns__min_chars());
tab_box.Tab_name_(tab_name); tab_name = Xog_tab_itm_.Tab_name_max(tab_name, tab_mgr.Btns__max_chars());
} tab_box.Tab_name_(tab_name);
public Xog_history_mgr History_mgr() {return history_mgr;} private Xog_history_mgr history_mgr = new Xog_history_mgr(); }
public byte View_mode() {return view_mode;} private byte view_mode = Xopg_view_mode_.Tid__read; public Xog_history_mgr History_mgr() {return history_mgr;} private Xog_history_mgr history_mgr = new Xog_history_mgr();
public void View_mode_(byte v) { public byte View_mode() {return view_mode;} private byte view_mode = Xopg_view_mode_.Tid__read;
view_mode = v; public void View_mode_(byte v) {
if (view_mode != Xopg_view_mode_.Tid__read) // if read, don't bother adding "action=read" view_mode = v;
page.Url().Qargs_mgr().Set_val_by_bry(Xoa_url_.Qarg__action, Xopg_view_mode_.To_bry(v)); if (view_mode != Xopg_view_mode_.Tid__read) // if read, don't bother adding "action=read"
} page.Url().Qargs_mgr().Set_val_by_bry(Xoa_url_.Qarg__action, Xopg_view_mode_.To_bry(v));
public void Pin_toggle() {} }
public void Show_url_bgn(Xoa_url url) { public void Pin_toggle() {}
this.tab_is_loading = true; public void Show_url_bgn(Xoa_url url) {
Xoae_app app = win.App(); Gfo_usr_dlg usr_dlg = app.Usr_dlg(); this.tab_is_loading = true;
Xoae_app app = win.App(); Gfo_usr_dlg usr_dlg = app.Usr_dlg();
// get new_tab_name
this.wiki = (Xowe_wiki)app.Wiki_mgr().Get_by_or_make_init_y(url.Wiki_bry()); // NOTE: must go before wiki.Props().Main_page(); DATE:2016-08-02; NOTE: must load wiki; DATE:2015-07-22 // get new_tab_name
if (url.Page_is_main()) url.Page_bry_(wiki.Props().Main_page()); // NOTE: must go before ttl.Make; DATE:2016-07-31 this.wiki = (Xowe_wiki)app.Wiki_mgr().Get_by_or_make_init_y(url.Wiki_bry()); // NOTE: must go before wiki.Props().Main_page(); DATE:2016-08-02; NOTE: must load wiki; DATE:2015-07-22
Xoa_ttl ttl = wiki.Ttl_parse(url.Page_bry()); if (url.Page_is_main()) url.Page_bry_(wiki.Props().Main_page()); // NOTE: must go before ttl.Make; DATE:2016-07-31
if (ttl == null) {usr_dlg.Prog_one("", "", "title is invalid: ~{0}", String_.new_u8(url.Raw())); return;} Xoa_ttl ttl = wiki.Ttl_parse(url.Page_bry());
String new_tab_name = String_.new_u8(ttl.Full_txt()); if (ttl == null) {usr_dlg.Prog_one("", "", "title is invalid: ~{0}", String_.new_u8(url.Raw())); return;}
String new_tab_name = String_.new_u8(ttl.Full_txt());
// if clicking on anchor, just scroll; do not load page
if ( url.Anch_str() != null // url has anchor // if clicking on anchor, just scroll; do not load page
&& url.Eq_page(page.Url()) // url has same page_name as existing page if ( url.Anch_str() != null // url has anchor
&& url.Qargs_ary().length == 0 // url has no args; needed for Category:A?from=b#mw-pages && url.Eq_page(page.Url()) // url has same page_name as existing page
&& String_.Eq(new_tab_name, tab_data.Name()) // NOTE: name will be null / empty when starting app and last session had page with #anchor; EX:Main_Page#Links; DATE:2016-07-21 && url.Qargs_ary().length == 0 // url has no args; needed for Category:A?from=b#mw-pages
) { && String_.Eq(new_tab_name, tab_data.Name()) // NOTE: name will be null / empty when starting app and last session had page with #anchor; EX:Main_Page#Links; DATE:2016-07-21
html_itm.Scroll_page_by_id_gui(url.Anch_str()); ) {
return; html_itm.Scroll_page_by_id_gui(url.Anch_str());
} return;
if (win.Page__async__working(url)) return; }
if (page != null) page.Tab_data().Close_mgr().When_close(this, url); // cancel any current search cmds if (win.Page__async__working(url)) return;
app.Log_wtr().Queue_enabled_(true); if (page != null) page.Tab_data().Close_mgr().When_close(this, url); // cancel any current search cmds
usr_dlg.Gui_wkr().Clear(); app.Log_wtr().Queue_enabled_(true);
if (url.Vnt_bry() != null) { usr_dlg.Gui_wkr().Clear();
byte[] vnt = url.Vnt_bry(); if (url.Vnt_bry() != null) {
if (!Bry_.Eq(vnt, wiki.Lang().Vnt_mgr().Cur_itm().Key())) byte[] vnt = url.Vnt_bry();
wiki.Appe().Cfg().Set_bry_wiki(wiki, Xowe_wiki.Cfg__variant__current, vnt); if (!Bry_.Eq(vnt, wiki.Lang().Vnt_mgr().Cur_itm().Key()))
} wiki.Appe().Cfg().Set_bry_wiki(wiki, Xowe_wiki.Cfg__variant__current, vnt);
Tab_name_(new_tab_name); }
usr_dlg.Prog_one("", "", "loading: ~{0}", String_.new_u8(ttl.Raw())); Tab_name_(new_tab_name);
usr_dlg.Prog_one("", "", "loading: ~{0}", String_.new_u8(ttl.Raw()));
// DELETE: no longer seems needed; popups always disappear when navigating to new page; DATE:2018-11-11
// if (wiki.Html_mgr().Head_mgr().Popup_mgr().Enabled()) // DELETE: no longer seems needed; popups always disappear when navigating to new page; DATE:2018-11-11
// this.Html_box().Html_js_eval_script("if (window.xowa_popups_hide_all != null) window.xowa_popups_hide_all();"); // should be more configurable; DATE:2014-07-09 // if (wiki.Html_mgr().Head_mgr().Popup_mgr().Enabled())
// this.Html_box().Html_js_eval_script("if (window.xowa_popups_hide_all != null) window.xowa_popups_hide_all();"); // should be more configurable; DATE:2014-07-09
app.Thread_mgr_old().Page_load_mgr().Add_at_end(new Load_page_wkr(this, wiki, url, ttl)).Run();
} app.Thread_mgr_old().Page_load_mgr().Add_at_end(new Load_page_wkr(this, wiki, url, ttl)).Run();
private void Show_url_loaded(Load_page_wkr wkr) { }
Xowe_wiki wiki = wkr.Wiki(); Xoae_page page = wkr.Page(); private void Show_url_loaded(Load_page_wkr wkr) {
Xoa_url url = page.Url(); Xoa_ttl ttl = page.Ttl(); Xowe_wiki wiki = wkr.Wiki(); Xoae_page page = wkr.Page();
Xoae_app app = wiki.Appe(); Gfo_usr_dlg usr_dlg = app.Usr_dlg(); Xoa_url url = page.Url(); Xoa_ttl ttl = page.Ttl();
try { Xoae_app app = wiki.Appe(); Gfo_usr_dlg usr_dlg = app.Usr_dlg();
if (page.Tab_data().Cancel_show()) return; // Special:Search canceled show; NOTE: must be inside try b/c finally handles thread try {
wiki.Parser_mgr().Ctx().Page_(page); if (page.Tab_data().Cancel_show()) return; // Special:Search canceled show; NOTE: must be inside try b/c finally handles thread
if ( page.Db().Page().Exists_n() wiki.Parser_mgr().Ctx().Page_(page);
&& !page.Commons_mgr().Xowa_mockup()) { // do not enter "missing" section if File_mockup; EX:en.wikipedia.org/wiki/File:Protoplanetary-disk.jpg DATE:2016-11-13 if ( page.Db().Page().Exists_n()
if (wiki.Db_mgr().Save_mgr().Create_enabled() && !page.Commons_mgr().Xowa_mockup()) { // do not enter "missing" section if File_mockup; EX:en.wikipedia.org/wiki/File:Protoplanetary-disk.jpg DATE:2016-11-13
|| wiki.Page_mgr().Sync_mgr().Auto_enabled()) { if (wiki.Db_mgr().Save_mgr().Create_enabled()
page = Xoae_page.New_edit(wiki, ttl); || wiki.Page_mgr().Sync_mgr().Auto_enabled()) {
page.Url_(url); // NOTE: need to set url else query args like action=edit will be lost; DATE:2019-03-20 page = Xoae_page.New_edit(wiki, ttl);
view_mode = Xopg_view_mode_.Tid__edit; page.Url_(url); // NOTE: need to set url else query args like action=edit will be lost; DATE:2019-03-20
history_mgr.Add(page); // NOTE: must put new_page on stack so that pressing back will pop new_page, not previous page view_mode = Xopg_view_mode_.Tid__edit;
Xog_tab_itm_read_mgr.Show_page(this, page, false); history_mgr.Add(page); // NOTE: must put new_page on stack so that pressing back will pop new_page, not previous page
} Xog_tab_itm_read_mgr.Show_page(this, page, false);
else { }
wkr.Page().Tab_data().Tab().Page_(page); // NOTE: must set tab's page to current page, so that switching to it will update url bar; EX:pt.b:A"MANUAL_DE_PROCEDURI_.Sectiunea:""CONTABILITATE_SI_MANAGEMENT_FINANCIAR""" DATE:2015-09-17 else {
if (page.Redirect_trail().Itms__len() > 0) wkr.Page().Tab_data().Tab().Page_(page); // NOTE: must set tab's page to current page, so that switching to it will update url bar; EX:pt.b:A"MANUAL_DE_PROCEDURI_.Sectiunea:""CONTABILITATE_SI_MANAGEMENT_FINANCIAR""" DATE:2015-09-17
usr_dlg.Prog_many("", "", "could not find page in wiki: ~{0} (redirected from ~{1})", String_.new_u8(page.Url().Page_bry()), page.Redirect_trail().Itms__get_at_0th_or_null()); if (page.Redirect_trail().Itms__len() > 0)
else { usr_dlg.Prog_many("", "", "could not find page in wiki: ~{0} (redirected from ~{1})", String_.new_u8(page.Url().Page_bry()), page.Redirect_trail().Itms__get_at_0th_or_null());
if (ttl.Ns().Id_is_file()) else {
usr_dlg.Prog_one("", "", "commons.wikimedia.org must be installed in order to view the file. See [[App/Wiki_types/Commons]]: ~{0}", String_.new_u8(url.Raw()));// HOME if (ttl.Ns().Id_is_file())
else usr_dlg.Prog_one("", "", "commons.wikimedia.org must be installed in order to view the file. See [[App/Wiki_types/Commons]]: ~{0}", String_.new_u8(url.Raw()));// HOME
usr_dlg.Prog_one("", "", "could not find page in wiki: ~{0}", String_.new_u8(url.Raw())); else
} usr_dlg.Prog_one("", "", "could not find page in wiki: ~{0}", String_.new_u8(url.Raw()));
} }
app.Log_wtr().Queue_enabled_(false); }
return; app.Log_wtr().Queue_enabled_(false);
} return;
// if (!page.Redirected()) page.Url_(url); // NOTE: handle redirect from commons; COMMENTED: part of redirect rewrite; DATE:2016-07-05 }
if (page.Ttl().Anch_bgn() != Bry_find_.Not_found) page.Url().Anch_bry_(page.Ttl().Anch_txt()); // NOTE: occurs when page is a redirect to an anchor; EX: w:Duck race -> Rubber duck#Races // if (!page.Redirected()) page.Url_(url); // NOTE: handle redirect from commons; COMMENTED: part of redirect rewrite; DATE:2016-07-05
history_mgr.Add(page); if (page.Ttl().Anch_bgn() != Bry_find_.Not_found) page.Url().Anch_bry_(page.Ttl().Anch_txt()); // NOTE: occurs when page is a redirect to an anchor; EX: w:Duck race -> Rubber duck#Races
Xog_tab_itm_read_mgr.Show_page(this, page, true); history_mgr.Add(page);
if (app.Usere().History_mgr().Enabled()) { Xog_tab_itm_read_mgr.Show_page(this, page, true);
app.Usere().History_mgr().Add(page); if (app.Usere().History_mgr().Enabled()) {
app.User().User_db_mgr().History_mgr().Update_async(app.Async_mgr(), ttl, url); app.Usere().History_mgr().Add(page);
} app.User().User_db_mgr().History_mgr().Update_async(app.Async_mgr(), ttl, url);
usr_dlg.Prog_none("", "", "rendering html"); }
// html_itm.Html_box().Size_(tab_mgr.Tab_mgr().Size()); // COMMENTED: causes clicks on macosx to be off by 4 px; NOTE: must resize tab here, else scrolling to anchor in background tab doesn't work (html_box has size of 0, 0) DATE:2015-05-03 usr_dlg.Prog_none("", "", "rendering html");
// win.Page__async__bgn(this); // html_itm.Html_box().Size_(tab_mgr.Tab_mgr().Size()); // COMMENTED: causes clicks on macosx to be off by 4 px; NOTE: must resize tab here, else scrolling to anchor in background tab doesn't work (html_box has size of 0, 0) DATE:2015-05-03
Gfo_thread_wkr async_wkr = null; // win.Page__async__bgn(this);
if (page.Html_data().Hdump_exists()) { Gfo_thread_wkr async_wkr = null;
// wiki.File_mgr().Init_file_mgr_by_load(wiki); if (page.Html_data().Hdump_exists()) {
// Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr(); // wiki.File_mgr().Init_file_mgr_by_load(wiki);
// async_wkr = new Xof_file_wkr(wiki.File__orig_mgr(), fsdb_mgr.Bin_mgr(), fsdb_mgr.Mnt_mgr(), app.Usere().User_db_mgr().Cache_mgr(), wiki.File__repo_mgr(), html_itm, page, page.Hdump_mgr().Imgs()); // Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr();
async_wkr = new Load_files_wkr(this); // async_wkr = new Xof_file_wkr(wiki.File__orig_mgr(), fsdb_mgr.Bin_mgr(), fsdb_mgr.Mnt_mgr(), app.Usere().User_db_mgr().Cache_mgr(), wiki.File__repo_mgr(), html_itm, page, page.Hdump_mgr().Imgs());
if (wiki.Html__hdump_enabled() && page.Db().Page().Html_db_id() == -1) { async_wkr = new Load_files_wkr(this);
wiki.Html__hdump_mgr().Save_mgr().Save(page); if (wiki.Html__hdump_enabled() && page.Db().Page().Html_db_id() == Xopg_db_page.HTML_DB_ID_NULL) {
} wiki.Html__hdump_mgr().Save_mgr().Save(page);
} }
else }
async_wkr = new Load_files_wkr(this); else
async_wkr = new Load_files_wkr(this);
page.Html_data().Mode_wtxt_shown_y_();
app.Thread_mgr_old().File_load_mgr().Add_at_end(async_wkr).Run(); page.Html_data().Mode_wtxt_shown_y_();
// app.Thread_mgr().Get_by_or_new("on_page_load").Add(new Xopg_img_thread(), new Xopg_rl_thread()); app.Thread_mgr_old().File_load_mgr().Add_at_end(async_wkr).Run();
} // app.Thread_mgr().Get_by_or_new("on_page_load").Add(new Xopg_img_thread(), new Xopg_rl_thread());
finally { }
app.Thread_mgr_old().Page_load_mgr().Resume(); finally {
this.tab_is_loading = false; app.Thread_mgr_old().Page_load_mgr().Resume();
} this.tab_is_loading = false;
} }
public void Exec_async_hdump(Xoa_app app, Xow_wiki wiki, gplx.xowa.guis.cbks.js.Xog_js_wkr js_wkr, gplx.core.threads.Gfo_thread_pool thread_pool, Xoa_page page, List_adp imgs, int[] redlink_ary) { }
if (imgs.Count() > 0) { public void Exec_async_hdump(Xoa_app app, Xow_wiki wiki, gplx.xowa.guis.cbks.js.Xog_js_wkr js_wkr, gplx.core.threads.Gfo_thread_pool thread_pool, Xoa_page page, List_adp imgs, int[] redlink_ary) {
Xof_file_wkr file_thread = new Xof_file_wkr if (imgs.Count() > 0) {
( wiki.File__orig_mgr(), wiki.File__bin_mgr(), wiki.File__mnt_mgr() Xof_file_wkr file_thread = new Xof_file_wkr
, app.User().User_db_mgr().Cache_mgr(), wiki.File__repo_mgr(), html_itm, page, imgs ( wiki.File__orig_mgr(), wiki.File__bin_mgr(), wiki.File__mnt_mgr()
); , app.User().User_db_mgr().Cache_mgr(), wiki.File__repo_mgr(), html_itm, page, imgs
thread_pool.Add_at_end(file_thread); thread_pool.Run(); );
} thread_pool.Add_at_end(file_thread); thread_pool.Run();
if (redlink_ary.length > 0) { }
Xog_redlink_thread redlink_thread = new Xog_redlink_thread(redlink_ary, js_wkr); if (redlink_ary.length > 0) {
thread_pool.Add_at_end(redlink_thread); thread_pool.Run(); Xog_redlink_thread redlink_thread = new Xog_redlink_thread(redlink_ary, js_wkr);
} thread_pool.Add_at_end(redlink_thread); thread_pool.Run();
} }
public void Exec_notify(boolean pass, String msg) { }
this.Html_box().Html_js_eval_proc_as_str("xowa.cmds.exec_by_str", "xowa.notify", "{\"text\":\"" + msg + "\",\"status\":\"" + (pass ? "success" : "error") + "\"}"); public void Exec_notify(boolean pass, String msg) {
} this.Html_box().Html_js_eval_proc_as_str("xowa.cmds.exec_by_str", "xowa.notify", "{\"text\":\"" + msg + "\",\"status\":\"" + (pass ? "success" : "error") + "\"}");
@gplx.Internal protected void Show_url_failed(Load_page_wkr wkr) { }
try { @gplx.Internal protected void Show_url_failed(Load_page_wkr wkr) {
Xog_tab_itm_read_mgr.Show_page_err(win, this, wkr.Wiki(), wkr.Url(), wkr.Ttl(), wkr.Exec_err()); try {
} finally { Xog_tab_itm_read_mgr.Show_page_err(win, this, wkr.Wiki(), wkr.Url(), wkr.Ttl(), wkr.Exec_err());
wkr.Wiki().Appe().Thread_mgr_old().Page_load_mgr().Resume(); } finally {
} wkr.Wiki().Appe().Thread_mgr_old().Page_load_mgr().Resume();
} }
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { }
if (ctx.Match(k, Invk_show_url_loaded_swt)) this.Show_url_loaded((Load_page_wkr)m.ReadObj("v")); public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
else if (ctx.Match(k, Invk_show_url_failed_swt)) this.Show_url_failed((Load_page_wkr)m.ReadObj("v")); if (ctx.Match(k, Invk_show_url_loaded_swt)) this.Show_url_loaded((Load_page_wkr)m.ReadObj("v"));
else return Gfo_invk_.Rv_unhandled; else if (ctx.Match(k, Invk_show_url_failed_swt)) this.Show_url_failed((Load_page_wkr)m.ReadObj("v"));
return this; else return Gfo_invk_.Rv_unhandled;
} return this;
public static final String Invk_show_url_loaded_swt = "show_url_loaded_swt", Invk_show_url_failed_swt = "show_url_failed_swt"; }
} public static final String Invk_show_url_loaded_swt = "show_url_loaded_swt", Invk_show_url_failed_swt = "show_url_failed_swt";
class Load_files_wkr implements Gfo_thread_wkr { }
private Xog_tab_itm tab; class Load_files_wkr implements Gfo_thread_wkr {
public Load_files_wkr(Xog_tab_itm tab) {this.tab = tab;} private Xog_tab_itm tab;
public String Thread__name() {return "xowa.load_files_wkr";} public Load_files_wkr(Xog_tab_itm tab) {this.tab = tab;}
public boolean Thread__resume() {return true;} public String Thread__name() {return "xowa.load_files_wkr";}
public void Thread__exec() { public boolean Thread__resume() {return true;}
try {Xog_async_wkr.Async(tab);} public void Thread__exec() {
catch (Exception e) { try {Xog_async_wkr.Async(tab);}
tab.Tab_mgr().Win().App().Usr_dlg().Warn_many("error while running file wkr; page=~{0} err=~{1}", tab.Page().Url().To_str(), Err_.Message_gplx_full(e)); catch (Exception e) {
} tab.Tab_mgr().Win().App().Usr_dlg().Warn_many("error while running file wkr; page=~{0} err=~{1}", tab.Page().Url().To_str(), Err_.Message_gplx_full(e));
} }
} }
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,148 +13,171 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.guis.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*; package gplx.xowa.guis.views;
import gplx.gfui.*; import gplx.gfui.controls.standards.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.htmls.*; import gplx.xowa.wikis.pages.*;
import gplx.xowa.wikis.nss.*; import gplx.Bry_;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.Bry_bfr;
public class Xog_tab_itm_edit_mgr { import gplx.Datetime_now;
public static void Save(Xog_tab_itm tab, boolean quick_save) { import gplx.Err_;
if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles ctrl+s being pressed in read/html modes import gplx.Gfo_usr_dlg_;
import gplx.String_;
// get text and save directly to text_db import gplx.gfui.controls.standards.Gfui_html;
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win(); import gplx.xowa.Xoa_page_;
byte[] new_text = Get_new_text(tab, page.Db().Text().Text_bry()); import gplx.xowa.Xoa_ttl;
int page_id = page.Db().Page().Id(); import gplx.xowa.Xoa_url;
if (page.Edit_mode() == Xoa_page_.Edit_mode_create) { import gplx.xowa.Xoae_page;
page_id = wiki.Db_mgr().Save_mgr().Data_create(wiki, page.Ttl(), new_text); import gplx.xowa.Xowe_wiki;
page.Db().Page().Id_(page_id); import gplx.xowa.htmls.Xoh_page_wtr_wkr;
page.Edit_mode_update_(); // set to update so that next save does not try to create import gplx.xowa.htmls.core.htmls.Xoh_wtr_ctx;
} import gplx.xowa.parsers.Xop_ctx;
else { import gplx.xowa.parsers.tmpls.Xot_defn_trace_dbg;
wiki.Db_mgr().Save_mgr().Data_update(page, new_text); import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
} import gplx.xowa.wikis.nss.Xow_ns_;
Invalidate(wiki); import gplx.xowa.wikis.pages.Xopg_view_mode_;
page.Db().Text().Text_bry_(new_text);
public class Xog_tab_itm_edit_mgr {
// refresh html public static void Save(Xog_tab_itm tab, boolean quick_save) {
wiki.Parser_mgr().Parse(page, true); if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles ctrl+s being pressed in read/html modes
if (wiki.Html__hdump_enabled()) wiki.Html__hdump_mgr().Save_mgr().Save(page); // must go after wiki.Parse
// get text and save directly to text_db
// NOTE: show message after Parse, b/c Parse will flash "Loading page"; DATE:2014-05-17 Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
win_itm.Usr_dlg().Prog_many("", "", "saved ~{0} (~{1})" byte[] new_text = Get_new_text(tab, page.Db().Text().Text_bry());
, String_.new_u8(page.Ttl().Full_txt_raw()) int page_id = page.Db().Page().Id();
, Datetime_now.Get().XtoStr_fmt("HH:mm:ss.fff") if (page.Edit_mode() == Xoa_page_.Edit_mode_create) {
); page_id = wiki.Db_mgr().Save_mgr().Data_create(wiki, page.Ttl(), new_text);
page.Db().Page().Id_(page_id);
// full_save; save page and go to read mode page.Edit_mode_update_(); // set to update so that next save does not try to create
if (!quick_save) { }
gplx.xowa.addons.wikis.pagebaks.Pagebaks_addon.On_page_saved(wiki.Appe(), wiki, page.Ttl(), new_text); else {
wiki.Db_mgr().Save_mgr().Data_update(page, new_text);
// update categories }
try { Invalidate(wiki);
wiki.Html_mgr().Page_wtr_mgr().Gen(page, Xopg_view_mode_.Tid__read); // NOTE: need to write html to fill Wtxt().Ctgs page.Db().Text().Text_bry_(new_text);
gplx.xowa.addons.wikis.ctgs.edits.Xoctg_edit_mgr.Update(wiki, page.Ttl().Page_db(), page_id, page.Wtxt().Ctgs__to_ary());
} catch (Exception e) { // refresh html
Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to update categories; err=~{0}", Err_.Message_gplx_log(e)); wiki.Parser_mgr().Parse(page, true);
} if (wiki.Html__hdump_enabled()) wiki.Html__hdump_mgr().Save_mgr().Save(page); // must go after wiki.Parse
// TODO: save html copy // NOTE: show message after Parse, b/c Parse will flash "Loading page"; DATE:2014-05-17
//wiki.Db_mgr().Hdump_mgr().Save(page); win_itm.Usr_dlg().Prog_many("", "", "saved ~{0} (~{1})"
, String_.new_u8(page.Ttl().Full_txt_raw())
// parse page and show it , Datetime_now.Get().XtoStr_fmt("HH:mm:ss.fff")
page.Html_data().Edit_preview_(Bry_.Empty); );
Xoae_page stack_page = tab.History_mgr().Cur_page(wiki); // NOTE: must be to CurPage() else changes will be lost when going Bwd,Fwd
stack_page.Db().Text().Text_bry_(page.Db().Text().Text_bry()); // NOTE: overwrite with "saved" changes // full_save; save page and go to read mode
stack_page.Wikie().Parser_mgr().Parse(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save if (!quick_save) {
page.Url_(Xoa_url.New(tab.Wiki().Domain_bry(), tab.Page().Ttl().Full_db())); gplx.xowa.addons.wikis.pagebaks.Pagebaks_addon.On_page_saved(wiki.Appe(), wiki, page.Ttl(), new_text);
// force full reload of page; needed to refresh page_modified; DATE:2017-03-06 // update categories
tab.Show_url_bgn(page.Url()); try {
// win_itm.Page__mode_(Xopg_view_mode_.Tid__read); wiki.Html_mgr().Page_wtr_mgr().Gen(page, Xopg_view_mode_.Tid__read); // NOTE: need to write html to fill Wtxt().Ctgs
// win_itm.Page__async__bgn(tab); gplx.xowa.addons.wikis.ctgs.edits.Xoctg_edit_mgr.Update(wiki, page.Ttl().Page_db(), page_id, page.Wtxt().Ctgs__to_ary());
} } catch (Exception e) {
} Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to update categories; err=~{0}", Err_.Message_gplx_log(e));
public static void Preview(Xog_tab_itm tab) { }
if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles preview somehow being called?
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win(); // reload html_db_id b/c it gets cleared in Xopg_db_page; ISSUE#:699; DATE:2020-08-06
Xog_html_itm html_itm = tab.Html_itm(); Xowd_page_itm rv = new Xowd_page_itm();
wiki.Data__core_mgr().Tbl__page().Select_by_ttl(rv, page.Ttl().Ns(), page.Ttl().Page_db());
byte[] new_text = Get_new_text(tab, null); page.Db().Page().Html_db_id_(rv.Html_db_id());
Xoae_page new_page = Xoae_page.New(wiki, page.Ttl());
new_page.Url_(page.Url()); // NOTE: must set Url explicitly, else new_page will not have same url_args as old_page; broken when going to action=edit; DATE:2018-11-25 // save html
new_page.Db().Page().Id_(page.Db().Page().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat) wiki.Html__hdump_mgr().Save_mgr().Save(page, true);
new_page.Db().Text().Text_bry_(new_text);
wiki.Parser_mgr().Parse(new_page, true); // refresh html // parse page and show it
tab.Page_(new_page); new_page.Tab_data().Tab_(tab); // replace old page with new_page; DATE:2014-10-09 page.Html_data().Edit_preview_(Bry_.Empty);
Xoae_page stack_page = tab.History_mgr().Cur_page(wiki); // NOTE: must be to CurPage() else changes will be lost when going Bwd,Fwd
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001(); stack_page.Db().Text().Text_bry_(page.Db().Text().Text_bry()); // NOTE: overwrite with "saved" changes
Xoh_page_wtr_wkr wkr = wiki.Html_mgr().Page_wtr_mgr().Wkr(Xopg_view_mode_.Tid__read); stack_page.Wikie().Parser_mgr().Parse(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
wkr.Write_body(tmp_bfr, wiki.Parser_mgr().Ctx(), Xoh_wtr_ctx.Basic, new_page); page.Url_(Xoa_url.New(tab.Wiki().Domain_bry(), tab.Page().Ttl().Full_db()));
byte[] new_html = tmp_bfr.To_bry_and_rls();
new_page.Html_data().Edit_preview_(new_html); // force full reload of page; needed to refresh page_modified; DATE:2017-03-06
tab.Show_url_bgn(page.Url());
Invalidate(wiki); // win_itm.Page__mode_(Xopg_view_mode_.Tid__read);
win_itm.Page__mode_(Xopg_view_mode_.Tid__edit); // win_itm.Page__async__bgn(tab);
html_itm.Scroll_page_by_id_gui(Xog_html_itm.Elem_id__first_heading);// NOTE: was originally directly; changed to call on thread; DATE:2014-05-03 }
win_itm.Page__async__bgn(tab); // NOTE: needed to show images during preview; DATE:2014-06-21 }
} public static void Preview(Xog_tab_itm tab) {
public static void Rename(Xog_tab_itm tab) { if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles preview somehow being called?
if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles ctrl+r being pressed Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win(); Xog_html_itm html_itm = tab.Html_itm();
if (Bry_.Eq(page.Ttl().Page_db(), wiki.Props().Main_page())) {
win_itm.Usr_dlg().Warn_many("", "", "The Main Page cannot be renamed"); byte[] new_text = Get_new_text(tab, null);
win_itm.Kit().Ask_ok("", "", "The Main Page cannot be renamed"); Xoae_page new_page = Xoae_page.New(wiki, page.Ttl());
return; new_page.Url_(page.Url()); // NOTE: must set Url explicitly, else new_page will not have same url_args as old_page; broken when going to action=edit; DATE:2018-11-25
} new_page.Db().Page().Id_(page.Db().Page().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat)
byte[] new_text = Bry_.new_u8(tab.Html_itm().Get_elem_value(Xog_html_itm.Elem_id__xowa_edit_rename_box)); new_page.Db().Text().Text_bry_(new_text);
if (Bry_.Len_eq_0(new_text)) return; // no ttl given; exit wiki.Parser_mgr().Parse(new_page, true); // refresh html
new_text = Xoa_ttl.Replace_spaces(new_text); // ttls cannot have spaces; only underscores tab.Page_(new_page); new_page.Tab_data().Tab_(tab); // replace old page with new_page; DATE:2014-10-09
Xoa_ttl new_ttl = Xoa_ttl.Parse(wiki, new_text);
int new_ns_id = new_ttl.Ns().Id(); Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
if (new_ns_id != Xow_ns_.Tid__main) { Xoh_page_wtr_wkr wkr = wiki.Html_mgr().Page_wtr_mgr().Wkr(Xopg_view_mode_.Tid__read);
win_itm.Usr_dlg().Warn_many("", "", "The new page name must remain in the same namespace"); wkr.Write_body(tmp_bfr, wiki.Parser_mgr().Ctx(), Xoh_wtr_ctx.Basic, new_page);
return; byte[] new_html = tmp_bfr.To_bry_and_rls();
} new_page.Html_data().Edit_preview_(new_html);
wiki.Db_mgr().Save_mgr().Data_rename(page, new_ns_id, new_text);
page.Ttl_(Xoa_ttl.Parse(wiki, Bry_.Add(page.Ttl().Ns().Name_db_w_colon(), new_text))); Invalidate(wiki);
win_itm.Page__mode_(Xopg_view_mode_.Tid__read); win_itm.Page__mode_(Xopg_view_mode_.Tid__edit);
win_itm.Usr_dlg().Prog_one("", "", "renamed page to {0}", String_.new_u8(page.Ttl().Full_txt_raw())); html_itm.Scroll_page_by_id_gui(Xog_html_itm.Elem_id__first_heading);// NOTE: was originally directly; changed to call on thread; DATE:2014-05-03
} win_itm.Page__async__bgn(tab); // NOTE: needed to show images during preview; DATE:2014-06-21
public static void Focus(Xog_win_itm win, String elem_focus_id) { }
Gfui_html html_box = win.Active_html_box(); public static void Rename(Xog_tab_itm tab) {
html_box.Focus(); if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles ctrl+r being pressed
html_box.Html_js_eval_proc_as_str(Xog_js_procs.Doc__elem_focus, elem_focus_id); Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
} if (Bry_.Eq(page.Ttl().Page_db(), wiki.Props().Main_page())) {
public static void Debug(Xog_win_itm win, byte view_tid) { win_itm.Usr_dlg().Warn_many("", "", "The Main Page cannot be renamed");
Xog_tab_itm tab = win.Tab_mgr().Active_tab(); Xoae_page page = tab.Page(); win_itm.Kit().Ask_ok("", "", "The Main Page cannot be renamed");
Xowe_wiki wiki = tab.Wiki(); Xop_ctx ctx = wiki.Parser_mgr().Ctx(); return;
ctx.Defn_trace().Clear(); // TODO_OLD: move_me }
ctx.Defn_trace_(Xot_defn_trace_dbg.Instance); byte[] new_text = Bry_.new_u8(tab.Html_itm().Get_elem_value(Xog_html_itm.Elem_id__xowa_edit_rename_box));
Xoa_ttl ttl = page.Ttl(); if (Bry_.Len_eq_0(new_text)) return; // no ttl given; exit
Xoae_page new_page = Xoae_page.New(wiki, ttl); new_text = Xoa_ttl.Replace_spaces(new_text); // ttls cannot have spaces; only underscores
new_page.Url_(page.Url()); // NOTE: must set Url explicitly, else new_page will not have same url_args as old_page; broken when going to action=edit; DATE:2018-12-09 Xoa_ttl new_ttl = Xoa_ttl.Parse(wiki, new_text);
byte[] data = tab.Html_itm().Get_elem_value_for_edit_box_as_bry(); int new_ns_id = new_ttl.Ns().Id();
new_page.Db().Text().Text_bry_(data); if (new_ns_id != Xow_ns_.Tid__main) {
wiki.Parser_mgr().Parse(new_page, true); win_itm.Usr_dlg().Warn_many("", "", "The new page name must remain in the same namespace");
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001(); return;
bfr.Add(new_page.Root().Root_src()); }
wiki.Parser_mgr().Ctx().Defn_trace().Print(data, bfr); wiki.Db_mgr().Save_mgr().Data_rename(page, new_ns_id, new_text);
new_page.Db().Text().Text_bry_(bfr.To_bry_and_rls()); page.Ttl_(Xoa_ttl.Parse(wiki, Bry_.Add(page.Ttl().Ns().Name_db_w_colon(), new_text)));
byte old = tab.View_mode(); win_itm.Page__mode_(Xopg_view_mode_.Tid__read);
tab.View_mode_(view_tid); win_itm.Usr_dlg().Prog_one("", "", "renamed page to {0}", String_.new_u8(page.Ttl().Full_txt_raw()));
Xog_tab_itm_read_mgr.Show_page(tab, new_page, false); }
tab.History_mgr().Add(new_page); public static void Focus(Xog_win_itm win, String elem_focus_id) {
tab.View_mode_(old); Gfui_html html_box = win.Active_html_box();
} html_box.Focus();
private static void Invalidate(Xowe_wiki wiki) {// invalidate everything on updates; especially needed for page transclusion; {{/my_subpage}} DATE:2014-04-10 html_box.Html_js_eval_proc_as_str(Xog_js_procs.Doc__elem_focus, elem_focus_id);
wiki.Parser_mgr().Scrib().Core_term(); }
wiki.Cache_mgr().Free_mem__all(); public static void Debug(Xog_win_itm win, byte view_tid) {
} Xog_tab_itm tab = win.Tab_mgr().Active_tab(); Xoae_page page = tab.Page();
private static byte[] Get_new_text(Xog_tab_itm tab, byte[] orig) { Xowe_wiki wiki = tab.Wiki(); Xop_ctx ctx = wiki.Parser_mgr().Ctx();
byte[] rv = tab.Html_itm().Get_elem_value_for_edit_box_as_bry(); ctx.Defn_trace().Clear(); // TODO_OLD: move_me
if (orig != null) // orig == null for Preview ctx.Defn_trace_(Xot_defn_trace_dbg.Instance);
rv = tab.Wiki().Parser_mgr().Hdr__section_editable__mgr().Merge_section(tab.Page().Url(), rv, orig); Xoa_ttl ttl = page.Ttl();
rv = Bry_.Trim(rv, 0, rv.length, false, true, Bry_.Trim_ary_ws, true); // MW: trim all trailing ws; REF:EditPage.php!safeUnicodeInput; DATE:2014-04-25 Xoae_page new_page = Xoae_page.New(wiki, ttl);
return rv; new_page.Url_(page.Url()); // NOTE: must set Url explicitly, else new_page will not have same url_args as old_page; broken when going to action=edit; DATE:2018-12-09
} byte[] data = tab.Html_itm().Get_elem_value_for_edit_box_as_bry();
} new_page.Db().Text().Text_bry_(data);
wiki.Parser_mgr().Parse(new_page, true);
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001();
bfr.Add(new_page.Root().Root_src());
wiki.Parser_mgr().Ctx().Defn_trace().Print(data, bfr);
new_page.Db().Text().Text_bry_(bfr.To_bry_and_rls());
byte old = tab.View_mode();
tab.View_mode_(view_tid);
Xog_tab_itm_read_mgr.Show_page(tab, new_page, false);
tab.History_mgr().Add(new_page);
tab.View_mode_(old);
}
private static void Invalidate(Xowe_wiki wiki) {// invalidate everything on updates; especially needed for page transclusion; {{/my_subpage}} DATE:2014-04-10
wiki.Parser_mgr().Scrib().Core_term();
wiki.Cache_mgr().Free_mem__all();
}
private static byte[] Get_new_text(Xog_tab_itm tab, byte[] orig) {
byte[] rv = tab.Html_itm().Get_elem_value_for_edit_box_as_bry();
if (orig != null) // orig == null for Preview
rv = tab.Wiki().Parser_mgr().Hdr__section_editable__mgr().Merge_section(tab.Page().Url(), rv, orig);
rv = Bry_.Trim(rv, 0, rv.length, false, true, Bry_.Trim_ary_ws, true); // MW: trim all trailing ws; REF:EditPage.php!safeUnicodeInput; DATE:2014-04-25
return rv;
}
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,74 +13,106 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.htmls.core; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; package gplx.xowa.htmls.core;
import gplx.xowa.htmls.core.htmls.*; import gplx.xowa.htmls.core.wkrs.*; import gplx.xowa.htmls.core.hzips.*; import gplx.xowa.htmls.heads.*; import gplx.xowa.htmls.core.dbs.*;
import gplx.core.ios.*; import gplx.core.primitives.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.pages.*; import gplx.core.ios.Io_stream_zip_mgr;
import gplx.xowa.addons.wikis.pages.syncs.core.parsers.*; import gplx.core.primitives.Bool_obj_ref;
public class Xow_hdump_mgr__save { import gplx.xowa.Xoae_page;
private final Xow_wiki wiki; private final Xoh_hzip_mgr hzip_mgr; private final Io_stream_zip_mgr zip_mgr; import gplx.xowa.Xow_wiki;
private final Xoh_page tmp_hpg; private final Xoh_hzip_bfr tmp_bfr = Xoh_hzip_bfr.New_txt(32); private Bool_obj_ref html_db_is_new = Bool_obj_ref.n_(); import gplx.xowa.htmls.Xoh_page;
private int dflt_zip_tid, dflt_hzip_tid; import gplx.xowa.htmls.core.dbs.Xowd_html_tbl;
public Xow_hdump_mgr__save(Xow_wiki wiki, Xoh_hzip_mgr hzip_mgr, Io_stream_zip_mgr zip_mgr, Xoh_page tmp_hpg) { import gplx.xowa.htmls.core.htmls.Xoh_wtr_ctx;
this.wiki = wiki; this.hzip_mgr = hzip_mgr; this.zip_mgr = zip_mgr; this.tmp_hpg = tmp_hpg; import gplx.xowa.htmls.core.hzips.Xoh_hzip_dict_;
} import gplx.xowa.htmls.core.hzips.Xoh_hzip_mgr;
public void Init_by_db(int dflt_zip_tid, int dflt_hzip_tid, boolean mode_is_b256) { import gplx.xowa.htmls.core.wkrs.Xoh_hzip_bfr;
this.dflt_zip_tid = dflt_zip_tid; this.dflt_hzip_tid = dflt_hzip_tid; tmp_bfr.Mode_is_b256_(mode_is_b256); import gplx.xowa.wikis.data.Xow_db_file;
} import gplx.xowa.wikis.data.Xow_db_file_;
public byte[] Src_as_hzip() {return src_as_hzip;} private byte[] src_as_hzip; import gplx.xowa.wikis.data.Xow_db_mgr;
public int Save(Xoae_page page) { import gplx.xowa.wikis.pages.Xopg_view_mode_;
synchronized (tmp_hpg) { import gplx.xowa.wikis.pages.dbs.Xopg_db_page;
Bld_hdump(page);
tmp_hpg.Ctor_by_hdiff(tmp_bfr, page, page.Wikie().Msg_mgr().Val_by_id(gplx.xowa.langs.msgs.Xol_msg_itm_.Id_toc)); public class Xow_hdump_mgr__save {
Xow_db_file html_db = Get_html_db(wiki, page, html_db_is_new.Val_n_()); private final Xow_wiki wiki; private final Xoh_hzip_mgr hzip_mgr; private final Io_stream_zip_mgr zip_mgr;
return Save(page, tmp_hpg, html_db.Tbl__html(), html_db_is_new.Val(), true); private final Xoh_page tmp_hpg; private final Xoh_hzip_bfr tmp_bfr = Xoh_hzip_bfr.New_txt(32); private Bool_obj_ref html_db_is_new = Bool_obj_ref.n_();
} private int dflt_zip_tid, dflt_hzip_tid;
} public Xow_hdump_mgr__save(Xow_wiki wiki, Xoh_hzip_mgr hzip_mgr, Io_stream_zip_mgr zip_mgr, Xoh_page tmp_hpg) {
public int Save(Xoae_page page, Xoh_page hpg, Xowd_html_tbl html_tbl, boolean insert, boolean use_hzip_dflt) { this.wiki = wiki; this.hzip_mgr = hzip_mgr; this.zip_mgr = zip_mgr; this.tmp_hpg = tmp_hpg;
int hzip_tid = use_hzip_dflt ? dflt_hzip_tid : Xoh_hzip_dict_.Hdb__htxt; }
byte[] db_body = Write(tmp_bfr, wiki, page, hpg, hzip_mgr, zip_mgr, dflt_zip_tid, hzip_tid, hpg.Db().Html().Html_bry()); public void Init_by_db(int dflt_zip_tid, int dflt_hzip_tid, boolean mode_is_b256) {
if (insert) html_tbl.Insert(hpg, dflt_zip_tid, dflt_hzip_tid, db_body); this.dflt_zip_tid = dflt_zip_tid; this.dflt_hzip_tid = dflt_hzip_tid; tmp_bfr.Mode_is_b256_(mode_is_b256);
else html_tbl.Update(hpg, dflt_zip_tid, dflt_hzip_tid, db_body); }
return db_body.length; public byte[] Src_as_hzip() {return src_as_hzip;} private byte[] src_as_hzip;
} public int Save(Xoae_page page) {return Save(page, false);}
public void Bld_hdump(Xoae_page page) { public int Save(Xoae_page page, boolean isEdit) {
page.File_queue().Clear(); // need to reset uid to 0, else xowa_file_# will keep incrementing upwards synchronized (tmp_hpg) {
Xoh_wtr_ctx hctx = Xoh_wtr_ctx.Hdump_by_hzip_tid(dflt_hzip_tid); Bld_hdump(page);
wiki.Html__wtr_mgr().Wkr(Xopg_view_mode_.Tid__read).Write_body(tmp_bfr, page.Wikie().Parser_mgr().Ctx(), hctx, page); // save as hdump_fmt tmp_hpg.Ctor_by_hdiff(tmp_bfr, page, page.Wikie().Msg_mgr().Val_by_id(gplx.xowa.langs.msgs.Xol_msg_itm_.Id_toc));
page.Db().Html().Html_bry_(tmp_bfr.To_bry_and_clear()); Xow_db_file html_db = Get_html_db(wiki, page, html_db_is_new.Val_n_(), isEdit);
} return Save(page, tmp_hpg, html_db.Tbl__html(), html_db_is_new.Val(), true);
private byte[] Write(Xoh_hzip_bfr bfr, Xow_wiki wiki, Xoae_page page, Xoh_page hpg, Xoh_hzip_mgr hzip_mgr, Io_stream_zip_mgr zip_mgr, int zip_tid, int hzip_tid, byte[] src) { }
switch (hzip_tid) { }
case Xoh_hzip_dict_.Hdb__htxt: public int Save(Xoae_page page, Xoh_page hpg, Xowd_html_tbl html_tbl, boolean insert, boolean use_hzip_dflt) {
break; int hzip_tid = use_hzip_dflt ? dflt_hzip_tid : Xoh_hzip_dict_.Hdb__htxt;
case Xoh_hzip_dict_.Hdb__hzip: byte[] db_body = Write(tmp_bfr, wiki, page, hpg, hzip_mgr, zip_mgr, dflt_zip_tid, hzip_tid, hpg.Db().Html().Html_bry());
src = hzip_mgr.Encode_as_bry((Xoh_hzip_bfr)bfr.Clear(), wiki, hpg, src); if (insert) html_tbl.Insert(hpg, dflt_zip_tid, dflt_hzip_tid, db_body);
break; else html_tbl.Update(hpg, dflt_zip_tid, dflt_hzip_tid, db_body);
// TOMBSTONE: not used; Xosync_update_mgr calls save directly; unsure if this should be restored for parallelism return db_body.length;
// case Xoh_hzip_dict_.Hdb__page_sync: }
// src = plain_parser.Parse_hdoc(wiki.Domain_itm(), page.Url_bry_safe(), hpg.Hdump_mgr().Imgs(), src); public void Bld_hdump(Xoae_page page) {
// break; page.File_queue().Clear(); // need to reset uid to 0, else xowa_file_# will keep incrementing upwards
} Xoh_wtr_ctx hctx = Xoh_wtr_ctx.Hdump_by_hzip_tid(dflt_hzip_tid);
src_as_hzip = src; wiki.Html__wtr_mgr().Wkr(Xopg_view_mode_.Tid__read).Write_body(tmp_bfr, page.Wikie().Parser_mgr().Ctx(), hctx, page); // save as hdump_fmt
if (zip_tid > gplx.core.ios.streams.Io_stream_tid_.Tid__raw) page.Db().Html().Html_bry_(tmp_bfr.To_bry_and_clear());
src = zip_mgr.Zip((byte)zip_tid, src); }
return src; private byte[] Write(Xoh_hzip_bfr bfr, Xow_wiki wiki, Xoae_page page, Xoh_page hpg, Xoh_hzip_mgr hzip_mgr, Io_stream_zip_mgr zip_mgr, int zip_tid, int hzip_tid, byte[] src) {
} switch (hzip_tid) {
private static Xow_db_file Get_html_db(Xow_wiki wiki, Xoae_page page, Bool_obj_ref html_db_is_new) { case Xoh_hzip_dict_.Hdb__htxt:
Xow_db_file rv = Xow_db_file.Null; break;
Xow_db_mgr core_data_mgr = wiki.Data__core_mgr(); case Xoh_hzip_dict_.Hdb__hzip:
int html_db_id = page.Db().Page().Html_db_id(); src = hzip_mgr.Encode_as_bry((Xoh_hzip_bfr)bfr.Clear(), wiki, hpg, src);
if (html_db_id == -1) { break;
html_db_is_new.Val_y_(); // TOMBSTONE: not used; Xosync_update_mgr calls save directly; unsure if this should be restored for parallelism
rv = core_data_mgr.Db__html(); // case Xoh_hzip_dict_.Hdb__page_sync:
if (rv == null) rv = core_data_mgr.Dbs__make_by_tid(Xow_db_file_.Tid__html_data); // src = plain_parser.Parse_hdoc(wiki.Domain_itm(), page.Url_bry_safe(), hpg.Hdump_mgr().Imgs(), src);
html_db_id = rv.Id(); // break;
page.Db().Page().Html_db_id_(html_db_id); }
core_data_mgr.Tbl__page().Update__html_db_id(page.Db().Page().Id(), html_db_id); src_as_hzip = src;
} if (zip_tid > gplx.core.ios.streams.Io_stream_tid_.Tid__raw)
else { src = zip_mgr.Zip((byte)zip_tid, src);
rv = core_data_mgr.Dbs__get_by_id_or_fail(html_db_id); return src;
} }
return rv; private static Xow_db_file Get_html_db(Xow_wiki wiki, Xoae_page page, Bool_obj_ref html_db_is_new, boolean isEdit) {
} Xow_db_file rv = Xow_db_file.Null;
} Xow_db_mgr core_data_mgr = wiki.Data__core_mgr();
int html_db_id = page.Db().Page().Html_db_id();
if (html_db_id == Xopg_db_page.HTML_DB_ID_NULL) {
html_db_is_new.Val_y_();
// get htmlDbTid; NOTE: probably do not need Tid__html_data b/c xomp_wkr and sync_mgr should be building the databases; ISSUE#:699; DATE:2020-08-06
byte htmlDbTid = isEdit ? Xow_db_file_.Tid__html_user : Xow_db_file_.Tid__html_data;
// get htmlDb
if (isEdit) {
rv = core_data_mgr.Dbs__get_by_tid_or_null(htmlDbTid);
}
else {
rv = core_data_mgr.Db__html();
}
// make htmlDb if not available
if (rv == null) {
rv = core_data_mgr.Dbs__make_by_tid(htmlDbTid);
Xowd_html_tbl html_tbl = new Xowd_html_tbl(rv.Conn());
html_tbl.Create_tbl();
}
html_db_id = rv.Id();
page.Db().Page().Html_db_id_(html_db_id);
core_data_mgr.Tbl__page().Update__html_db_id(page.Db().Page().Id(), html_db_id);
}
else {
rv = core_data_mgr.Dbs__get_by_id_or_fail(html_db_id);
}
return rv;
}
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,85 +13,111 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.htmls.hxtns.blobs; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.hxtns.*; package gplx.xowa.htmls.hxtns.blobs;
import gplx.dbs.*;
import gplx.core.ios.*; import gplx.Bry_bfr;
public class Hxtn_blob_tbl implements Rls_able { import gplx.Hash_adp_bry;
private static final String tbl_name = "hxtn_blob"; private static final Dbmeta_fld_list flds = new Dbmeta_fld_list(); import gplx.Rls_able;
private static final String import gplx.String_;
fld_blob_tid = flds.Add_int("blob_tid"), fld_wiki_id = flds.Add_int("wiki_id"), fld_blob_id = flds.Add_int("blob_id") import gplx.core.ios.Io_stream_zip_mgr;
, fld_zip_tid = flds.Add_byte("zip_tid"), fld_blob_data = flds.Add_bry("blob_data"); import gplx.dbs.Db_conn;
private final Db_conn conn; private Db_stmt stmt_insert; import gplx.dbs.Db_rdr;
private final byte zip_tid_default; import gplx.dbs.Db_rdr_;
private final Io_stream_zip_mgr zip_mgr = new Io_stream_zip_mgr(); import gplx.dbs.Db_stmt;
public Hxtn_blob_tbl(Db_conn conn, byte zip_tid_default) { import gplx.dbs.Db_stmt_;
this.conn = conn; import gplx.dbs.Dbmeta_fld_list;
conn.Rls_reg(this); import gplx.dbs.Dbmeta_idx_itm;
this.zip_tid_default = zip_tid_default; import gplx.dbs.Dbmeta_tbl_itm;
}
public String Tbl_name() {return tbl_name;} public class Hxtn_blob_tbl implements Rls_able {
public Db_conn Conn() {return conn;} private static final String tbl_name = "hxtn_blob"; private static final Dbmeta_fld_list flds = new Dbmeta_fld_list();
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));} private static final String
public void Rls() { fld_blob_tid = flds.Add_int("blob_tid"), fld_wiki_id = flds.Add_int("wiki_id"), fld_blob_id = flds.Add_int("blob_id")
stmt_insert = Db_stmt_.Rls(stmt_insert); , fld_zip_tid = flds.Add_byte("zip_tid"), fld_blob_data = flds.Add_bry("blob_data");
} private final Db_conn conn; private Db_stmt stmt_insert;
public void Stmt_bgn() { private final byte zip_tid_default;
stmt_insert = conn.Stmt_insert(tbl_name, flds); private final Io_stream_zip_mgr zip_mgr = new Io_stream_zip_mgr();
} public Hxtn_blob_tbl(Db_conn conn, byte zip_tid_default) {
public void Stmt_end() { this.conn = conn;
this.Rls(); conn.Rls_reg(this);
if (!conn.Meta_idx_exists(tbl_name, "pkey")) this.zip_tid_default = zip_tid_default;
conn.Meta_idx_create(Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "pkey", fld_blob_id, fld_wiki_id, fld_blob_tid)); }
} public String Tbl_name() {return tbl_name;}
public void Insert_by_rdr(Db_rdr rdr) { public Db_conn Conn() {return conn;}
Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert); public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
} public void Rls() {
public void Insert_exec(int blob_tid, int wiki_id, int blob_id, byte[] blob_data) { stmt_insert = Db_stmt_.Rls(stmt_insert);
blob_data = zip_mgr.Zip(zip_tid_default, blob_data); }
stmt_insert.Clear() public void Stmt_bgn() {
.Val_int(fld_blob_tid , blob_tid) stmt_insert = conn.Stmt_insert(tbl_name, flds);
.Val_int(fld_wiki_id , wiki_id) }
.Val_int(fld_blob_id , blob_id) public void Stmt_end() {
.Val_byte(fld_zip_tid , zip_tid_default) this.Rls();
.Val_bry(fld_blob_data , blob_data) if (!conn.Meta_idx_exists(tbl_name, "pkey"))
.Exec_insert(); conn.Meta_idx_create(Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "pkey", fld_blob_id, fld_wiki_id, fld_blob_tid));
} }
public void Select_to_regy(Bry_bfr temp_bfr, Hash_adp_bry blob_data_hash) { public void Insert_by_rdr(Db_rdr rdr) {
Db_rdr rdr = conn.Stmt_select(tbl_name, String_.Ary(fld_wiki_id, fld_blob_id, fld_blob_tid)) Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert);
.Exec_select__rls_auto(); }
try { public void Insert_exec(int blob_tid, int wiki_id, int blob_id, byte[] blob_data) {
while (rdr.Move_next()) { blob_data = zip_mgr.Zip(zip_tid_default, blob_data);
byte[] key = Make_key(temp_bfr, rdr.Read_int(fld_wiki_id), rdr.Read_int(fld_blob_id), rdr.Read_int(fld_blob_tid)); stmt_insert.Clear()
blob_data_hash.Add_as_key_and_val(key); .Val_int(fld_blob_tid , blob_tid)
} .Val_int(fld_wiki_id , wiki_id)
} finally { .Val_int(fld_blob_id , blob_id)
rdr.Rls(); .Val_byte(fld_zip_tid , zip_tid_default)
} .Val_bry(fld_blob_data , blob_data)
} .Exec_insert();
public byte[] Select_text(int blob_tid, int wiki_id, int blob_id) { }
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_blob_id, fld_wiki_id, fld_blob_tid) public boolean Exists(int blob_tid, int wiki_id, int blob_id) {
.Crt_int(fld_blob_id, blob_id) Db_rdr rdr = Db_rdr_.Empty;
.Crt_int(fld_wiki_id, wiki_id) try {
.Crt_int(fld_blob_tid, blob_tid) rdr = conn.Stmt_select(tbl_name, flds, fld_blob_tid, fld_wiki_id, fld_blob_id)
.Exec_select__rls_auto(); .Crt_int(fld_blob_tid, blob_tid)
try { .Crt_int(fld_wiki_id, wiki_id)
if (rdr.Move_next()) { .Crt_int(fld_blob_id, blob_id)
byte[] rv = rdr.Read_bry(fld_blob_data); .Exec_select__rls_auto();
byte zip_type = rdr.Read_byte(fld_zip_tid); return rdr.Move_next();
rv = zip_mgr.Unzip(zip_type, rv); } finally {
return rv; rdr.Rls();
} }
else { }
return null; public void Select_to_regy(Bry_bfr temp_bfr, Hash_adp_bry blob_data_hash) {
} Db_rdr rdr = conn.Stmt_select(tbl_name, String_.Ary(fld_wiki_id, fld_blob_id, fld_blob_tid))
} finally { .Exec_select__rls_auto();
rdr.Rls(); try {
} while (rdr.Move_next()) {
} byte[] key = Make_key(temp_bfr, rdr.Read_int(fld_wiki_id), rdr.Read_int(fld_blob_id), rdr.Read_int(fld_blob_tid));
blob_data_hash.Add_as_key_and_val(key);
public static byte[] Make_key(Bry_bfr temp_bfr, int blob_id, int wiki_id, int blob_tid) { }
return temp_bfr.Add_int_variable(blob_id).Add_byte_pipe().Add_int_variable(wiki_id).Add_byte_pipe().Add_int_variable(blob_tid).To_bry_and_clear(); } finally {
} rdr.Rls();
}
public static final int Blob_tid__wtxt = 0, Blob_tid__html = 1; }
public byte[] Select_text(int blob_tid, int wiki_id, int blob_id) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_blob_id, fld_wiki_id, fld_blob_tid)
.Crt_int(fld_blob_id, blob_id)
.Crt_int(fld_wiki_id, wiki_id)
.Crt_int(fld_blob_tid, blob_tid)
.Exec_select__rls_auto();
try {
if (rdr.Move_next()) {
byte[] rv = rdr.Read_bry(fld_blob_data);
byte zip_type = rdr.Read_byte(fld_zip_tid);
rv = zip_mgr.Unzip(zip_type, rv);
return rv;
}
else {
return null;
}
} finally {
rdr.Rls();
}
}
public static byte[] Make_key(Bry_bfr temp_bfr, int blob_id, int wiki_id, int blob_tid) {
return temp_bfr.Add_int_variable(blob_id).Add_byte_pipe().Add_int_variable(wiki_id).Add_byte_pipe().Add_int_variable(blob_tid).To_bry_and_clear();
}
public static final int Blob_tid__wtxt = 0, Blob_tid__html = 1;
} }

View File

@ -1,122 +1,124 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis. for your project on a case-by-case basis.
The terms of each license can be found in the source code repository: The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.htmls.hxtns.pages; package gplx.xowa.htmls.hxtns.pages;
import gplx.Bry_bfr; import gplx.Bry_bfr;
import gplx.Bry_bfr_; import gplx.Bry_bfr_;
import gplx.Gfo_usr_dlg_; import gplx.Gfo_usr_dlg_;
import gplx.Hash_adp_bry; import gplx.Hash_adp_bry;
import gplx.Io_mgr; import gplx.Io_mgr;
import gplx.Io_url; import gplx.Io_url;
import gplx.List_adp; import gplx.List_adp;
import gplx.core.lists.hashs.Hash_adp__int; import gplx.core.lists.hashs.Hash_adp__int;
import gplx.dbs.Db_conn; import gplx.dbs.Db_conn;
import gplx.dbs.Db_conn_bldr; import gplx.dbs.Db_conn_bldr;
import gplx.xowa.Xoa_ttl; import gplx.xowa.Xoa_ttl;
import gplx.xowa.Xow_wiki; import gplx.xowa.Xow_wiki;
import gplx.xowa.htmls.Xoh_page; import gplx.xowa.htmls.Xoh_page;
import gplx.xowa.htmls.hxtns.blobs.Hxtn_blob_tbl; import gplx.xowa.htmls.hxtns.blobs.Hxtn_blob_tbl;
import gplx.xowa.htmls.hxtns.wikis.Hxtn_wiki_mgr; import gplx.xowa.htmls.hxtns.wikis.Hxtn_wiki_mgr;
import gplx.xowa.htmls.hxtns.wkrs.Hxtn_wkr_mgr; import gplx.xowa.htmls.hxtns.wkrs.Hxtn_wkr_mgr;
public class Hxtn_page_mgr {
private Hxtn_page_tbl page_tbl; public class Hxtn_page_mgr {
private Hxtn_blob_tbl blob_tbl; private Hxtn_page_tbl page_tbl;
private Hash_adp_bry blob_hash; private Hxtn_blob_tbl blob_tbl;
private final Hash_adp__int wkrs = new Hash_adp__int(); private Hash_adp_bry blob_hash = Hash_adp_bry.cs();
private boolean dbs_missing = true; private final Hash_adp__int wkrs = new Hash_adp__int();
private Bry_bfr temp_bfr; private boolean dbs_missing = true;
public Hxtn_page_tbl Page_tbl() {return page_tbl;} private Bry_bfr temp_bfr = Bry_bfr_.New();
public Hxtn_blob_tbl Blob_tbl() {return blob_tbl;} public Hxtn_page_tbl Page_tbl() {return page_tbl;}
public Hxtn_blob_tbl Blob_tbl() {return blob_tbl;}
public void Init_by_xomp_wkr(Db_conn wkr_db_conn, byte zip_tid) {
// init tbls and other members public void Init_by_xomp_wkr(Db_conn wkr_db_conn, byte zip_tid) {
this.page_tbl = new Hxtn_page_tbl(wkr_db_conn); // init tbls and other members
this.blob_tbl = new Hxtn_blob_tbl(wkr_db_conn, zip_tid); this.page_tbl = new Hxtn_page_tbl(wkr_db_conn);
this.blob_hash = Hash_adp_bry.cs(); this.blob_tbl = new Hxtn_blob_tbl(wkr_db_conn, zip_tid);
this.temp_bfr = Bry_bfr_.New();
// if tbl exists, xomp_resume has run; load known blobs to prevent dupes
// if tbl exists, xomp_resume has run; load known blobs to prevent dupes if (wkr_db_conn.Meta_tbl_exists(page_tbl.Tbl_name())) {
if (wkr_db_conn.Meta_tbl_exists(page_tbl.Tbl_name())) { blob_tbl.Select_to_regy(temp_bfr, blob_hash);
blob_tbl.Select_to_regy(temp_bfr, blob_hash); }
} // else tbl doesn't exist, so create them
// else tbl doesn't exist, so create them else {
else { page_tbl.Create_tbl();
page_tbl.Create_tbl(); blob_tbl.Create_tbl();
blob_tbl.Create_tbl(); }
} }
} public void Init_by_wiki(Xow_wiki wiki, boolean is_merge) {
public void Init_by_wiki(Xow_wiki wiki, boolean is_merge) { Io_url core_db_url = Make_url(wiki, "-html.hxtn-core.xowa");
Io_url core_db_url = Make_url(wiki, "-html.hxtn-core.xowa"); if (!is_merge && !Io_mgr.Instance.ExistsFil(core_db_url)) return;
if (!is_merge && !Io_mgr.Instance.ExistsFil(core_db_url)) return; dbs_missing = false;
dbs_missing = false; Db_conn page_conn = Db_conn_bldr.Instance.Get_or_new(core_db_url).Conn();
Db_conn page_conn = Db_conn_bldr.Instance.Get_or_new(core_db_url).Conn(); this.page_tbl = new Hxtn_page_tbl(page_conn);
this.page_tbl = new Hxtn_page_tbl(page_conn);
Io_url blob_db_url = Make_url(wiki, "-html.hxtn-blob.xowa");
Io_url blob_db_url = Make_url(wiki, "-html.hxtn-blob.xowa"); this.blob_tbl = new Hxtn_blob_tbl(Db_conn_bldr.Instance.Get_or_new(blob_db_url).Conn(), gplx.core.ios.streams.Io_stream_tid_.Tid__raw);
this.blob_tbl = new Hxtn_blob_tbl(Db_conn_bldr.Instance.Get_or_new(blob_db_url).Conn(), gplx.core.ios.streams.Io_stream_tid_.Tid__raw);
if (is_merge) {
if (is_merge) { page_tbl.Create_tbl();
page_tbl.Create_tbl(); blob_tbl.Create_tbl();
blob_tbl.Create_tbl();
Hxtn_wkr_mgr wkr_mgr = new Hxtn_wkr_mgr();
Hxtn_wkr_mgr wkr_mgr = new Hxtn_wkr_mgr(); wkr_mgr.Init_by_xomp_merge(page_conn);
wkr_mgr.Init_by_xomp_merge(page_conn);
Hxtn_wiki_mgr wiki_mgr = new Hxtn_wiki_mgr();
Hxtn_wiki_mgr wiki_mgr = new Hxtn_wiki_mgr(); wiki_mgr.Init_by_xomp_merge(page_conn, wiki.Domain_str());
wiki_mgr.Init_by_xomp_merge(page_conn, wiki.Domain_str()); }
} }
} public void Insert_bgn(boolean is_merge) {
public void Insert_bgn(boolean is_merge) { page_tbl.Stmt_bgn();
page_tbl.Stmt_bgn(); blob_tbl.Stmt_bgn();
blob_tbl.Stmt_bgn(); }
} public void Insert_end(boolean is_merge) {
public void Insert_end(boolean is_merge) { page_tbl.Stmt_end();
page_tbl.Stmt_end(); blob_tbl.Stmt_end();
blob_tbl.Stmt_end(); }
} public void Page_tbl__insert(int page_id, int wkr_id, int data_id) {
public void Page_tbl__insert(int page_id, int wkr_id, int data_id) { if (!page_tbl.Exists(page_id, wkr_id, data_id))
page_tbl.Insert_exec(page_id, wkr_id, data_id); page_tbl.Insert_exec(page_id, wkr_id, data_id);
} }
public void Blob_tbl__insert(int blob_tid, int wiki_id, int blob_id, byte[] blob_text) { public void Blob_tbl__insert(int blob_tid, int wiki_id, int blob_id, byte[] blob_text) {
byte[] key = Hxtn_blob_tbl.Make_key(temp_bfr, blob_tid, wiki_id, blob_id); byte[] key = Hxtn_blob_tbl.Make_key(temp_bfr, blob_tid, wiki_id, blob_id);
if (!blob_hash.Has(key)) {// multiple pages can refer to same template; only insert if not seen if (!blob_hash.Has(key)) {// multiple pages can refer to same template; only insert if not seen
blob_hash.Add_as_key_and_val(key); blob_hash.Add_as_key_and_val(key);
blob_tbl.Insert_exec(blob_tid, wiki_id, blob_id, blob_text); if (!blob_tbl.Exists(blob_tid, wiki_id, blob_id)) {
} blob_tbl.Insert_exec(blob_tid, wiki_id, blob_id, blob_text);
} }
public void Reg_wkr(Hxtn_page_wkr wkr) { }
wkrs.Add(wkr.Id(), wkr); }
} public void Reg_wkr(Hxtn_page_wkr wkr) {
public void Load_by_page(Xoh_page hpg, Xoa_ttl ttl) { wkrs.Add(wkr.Id(), wkr);
if (dbs_missing) return; // PERF:do not call SELECT if dbs don't exist }
List_adp list = page_tbl.Select_by_page(hpg.Page_id()); public void Load_by_page(Xoh_page hpg, Xoa_ttl ttl) {
int len = list.Len(); if (dbs_missing) return; // PERF:do not call SELECT if dbs don't exist
for (int i = 0; i < len; i++) { List_adp list = page_tbl.Select_by_page(hpg.Page_id());
Hxtn_page_itm itm = (Hxtn_page_itm)list.Get_at(i); int len = list.Len();
Hxtn_page_wkr wkr = (Hxtn_page_wkr)wkrs.Get_by_or_null(itm.Wkr_id()); for (int i = 0; i < len; i++) {
if (wkr == null) { // ignore unknown wkrs so other devs can add new xtns; ISSUE#:634; DATE:2020-03-08 Hxtn_page_itm itm = (Hxtn_page_itm)list.Get_at(i);
Gfo_usr_dlg_.Instance.Warn_many("", "", "hxtn.unknown wkr: page_id=~{0} wkr_id=~{1}", itm.Page_id(), itm.Wkr_id()); Hxtn_page_wkr wkr = (Hxtn_page_wkr)wkrs.Get_by_or_null(itm.Wkr_id());
continue; if (wkr == null) { // ignore unknown wkrs so other devs can add new xtns; ISSUE#:634; DATE:2020-03-08
} Gfo_usr_dlg_.Instance.Warn_many("", "", "hxtn.unknown wkr: page_id=~{0} wkr_id=~{1}", itm.Page_id(), itm.Wkr_id());
wkr.Load_by_page(hpg, ttl, itm.Data_id()); continue;
} }
} wkr.Load_by_page(hpg, ttl, itm.Data_id());
private static Io_url Make_url(Xow_wiki wiki, String file_name) {return wiki.Fsys_mgr().Root_dir().GenSubFil(wiki.Domain_str() + file_name);} }
public static final int }
Id__template_styles = 0 private static Io_url Make_url(Xow_wiki wiki, String file_name) {return wiki.Fsys_mgr().Root_dir().GenSubFil(wiki.Domain_str() + file_name);}
, Id__indicators = 2 public static final int
; Id__template_styles = 0
} , Id__indicators = 2
;
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,57 +13,82 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.htmls.hxtns.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.hxtns.*; package gplx.xowa.htmls.hxtns.pages;
import gplx.dbs.*;
public class Hxtn_page_tbl implements Rls_able { import gplx.List_adp;
private static final String tbl_name = "hxtn_page"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list(); import gplx.List_adp_;
private final String fld_page_id, fld_wkr_id, fld_data_id; import gplx.Rls_able;
private final Db_conn conn; private Db_stmt stmt_insert; import gplx.dbs.Db_conn;
public Hxtn_page_tbl(Db_conn conn) { import gplx.dbs.Db_rdr;
this.conn = conn; import gplx.dbs.Db_rdr_;
conn.Rls_reg(this); import gplx.dbs.Db_stmt;
flds.Add_int_pkey_autonum("id"); import gplx.dbs.Db_stmt_;
this.fld_page_id = flds.Add_int("page_id"); import gplx.dbs.Dbmeta_fld_list;
this.fld_wkr_id = flds.Add_int("wkr_id"); import gplx.dbs.Dbmeta_idx_itm;
this.fld_data_id = flds.Add_int("data_id"); import gplx.dbs.Dbmeta_tbl_itm;
}
public String Tbl_name() {return tbl_name;} public class Hxtn_page_tbl implements Rls_able {
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));} private static final String tbl_name = "hxtn_page"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
public Db_conn Conn() {return conn;} private final String fld_page_id, fld_wkr_id, fld_data_id;
public void Rls() { private final Db_conn conn; private Db_stmt stmt_insert;
stmt_insert = Db_stmt_.Rls(stmt_insert); public Hxtn_page_tbl(Db_conn conn) {
} this.conn = conn;
public void Stmt_bgn() { conn.Rls_reg(this);
stmt_insert = conn.Stmt_insert(tbl_name, flds); flds.Add_int_pkey_autonum("id");
} this.fld_page_id = flds.Add_int("page_id");
public void Stmt_end() { this.fld_wkr_id = flds.Add_int("wkr_id");
this.Rls(); this.fld_data_id = flds.Add_int("data_id");
if (!conn.Meta_idx_exists(tbl_name, "pkey")) }
conn.Meta_idx_create(Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "pkey", fld_page_id, fld_wkr_id, fld_data_id)); public String Tbl_name() {return tbl_name;}
} public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
public void Insert_by_rdr(Db_rdr rdr) { public Db_conn Conn() {return conn;}
Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert); public void Rls() {
} stmt_insert = Db_stmt_.Rls(stmt_insert);
public void Insert_exec(int page_id, int wkr_id, int data_id) { }
stmt_insert.Clear() public void Stmt_bgn() {
.Val_int(fld_page_id , page_id) stmt_insert = conn.Stmt_insert(tbl_name, flds);
.Val_int(fld_wkr_id , wkr_id) }
.Val_int(fld_data_id , data_id) public void Stmt_end() {
.Exec_insert(); this.Rls();
} if (!conn.Meta_idx_exists(tbl_name, "pkey"))
public List_adp Select_by_page(int page_id) { conn.Meta_idx_create(Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "pkey", fld_page_id, fld_wkr_id, fld_data_id));
List_adp rv = List_adp_.New(); }
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_page_id) public void Insert_by_rdr(Db_rdr rdr) {
.Crt_int(fld_page_id, page_id) Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert);
.Exec_select__rls_auto(); }
try { public void Insert_exec(int page_id, int wkr_id, int data_id) {
while (rdr.Move_next()) { stmt_insert.Clear()
Hxtn_page_itm itm = new Hxtn_page_itm(rdr.Read_int(fld_page_id), rdr.Read_int(fld_wkr_id), rdr.Read_int(fld_data_id)); .Val_int(fld_page_id , page_id)
rv.Add(itm); .Val_int(fld_wkr_id , wkr_id)
} .Val_int(fld_data_id , data_id)
} finally { .Exec_insert();
rdr.Rls(); }
} public boolean Exists(int page_id, int wkr_id, int data_id) {
return rv; Db_rdr rdr = Db_rdr_.Empty;
} try {
} rdr = conn.Stmt_select(tbl_name, flds, fld_page_id, fld_wkr_id, fld_data_id)
.Crt_int(fld_page_id, page_id)
.Crt_int(fld_wkr_id, wkr_id)
.Crt_int(fld_data_id, data_id)
.Exec_select__rls_auto();
return rdr.Move_next();
} finally {
rdr.Rls();
}
}
public List_adp Select_by_page(int page_id) {
List_adp rv = List_adp_.New();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_page_id)
.Crt_int(fld_page_id, page_id)
.Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
Hxtn_page_itm itm = new Hxtn_page_itm(rdr.Read_int(fld_page_id), rdr.Read_int(fld_wkr_id), rdr.Read_int(fld_data_id));
rv.Add(itm);
}
} finally {
rdr.Rls();
}
return rv;
}
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,49 +13,52 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.wikis.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; package gplx.xowa.wikis.data;
public class Xow_db_file_ {
public static final int Uid__core = 0; import gplx.Err_;
public static final byte
Tid__core = 1, Tid__text = 2, Tid__cat = 3, Tid__search_core = 4, Tid__wbase = 5 // SERIALIZED:v1 public class Xow_db_file_ {
, Tid__cat_core = 6, Tid__cat_link = 7 // SERIALIZED:v2 public static final int Uid__core = 0;
, Tid__wiki_solo = 8, Tid__text_solo = 9 public static final byte
, Tid__html_solo = 10, Tid__html_data = 11 Tid__core = 1, Tid__text = 2, Tid__cat = 3, Tid__search_core = 4, Tid__wbase = 5 // SERIALIZED:v1
, Tid__file_solo = 12, Tid__file_core = 13, Tid__file_data = 14, Tid__file_user = 15 , Tid__cat_core = 6, Tid__cat_link = 7 // SERIALIZED:v2
, Tid__search_link = 16, Tid__random = 17, Tid__css = 18 , Tid__wiki_solo = 8, Tid__text_solo = 9
, Tid__html_user = 19 , Tid__html_solo = 10, Tid__html_data = 11
; , Tid__file_solo = 12, Tid__file_core = 13, Tid__file_data = 14, Tid__file_user = 15
private static final String , Tid__search_link = 16, Tid__random = 17, Tid__css = 18
Key__core = "core", Key__text = "text", Key__cat = "xtn.category", Key__search_core = "xtn.search.core", Key__wbase = "core.wbase" , Tid__html_user = 19
, Key__cat_core = "xtn.category.core", Key__cat_link = "xtn.category.link" ;
, Key__text_solo = "text.solo", Key__wiki_solo = "wiki.solo" private static final String
, Key__html_solo = "html.solo", Key__html_data = "html" Key__core = "core", Key__text = "text", Key__cat = "xtn.category", Key__search_core = "xtn.search.core", Key__wbase = "core.wbase"
, Key__file_solo = "file.solo", Key__file_core = "file.core", Key__file_data = "file.data", Key__file_user = "file.user" , Key__cat_core = "xtn.category.core", Key__cat_link = "xtn.category.link"
, Key__search_link = "xtn.search.link", Key__random = "xtn.random", Key__css = "xtn.css" , Key__text_solo = "text.solo", Key__wiki_solo = "wiki.solo"
, Key__html_user = "html.user" , Key__html_solo = "html.solo", Key__html_data = "html"
; , Key__file_solo = "file.solo", Key__file_core = "file.core", Key__file_data = "file.data", Key__file_user = "file.user"
public static String To_key(byte v) { , Key__search_link = "xtn.search.link", Key__random = "xtn.random", Key__css = "xtn.css"
switch (v) { , Key__html_user = "html.user"
case Tid__core: return Key__core; ;
case Tid__text: return Key__text; public static String To_key(byte v) {
case Tid__cat: return Key__cat; switch (v) {
case Tid__search_core: return Key__search_core; case Tid__core: return Key__core;
case Tid__wbase: return Key__wbase; case Tid__text: return Key__text;
case Tid__cat_core: return Key__cat_core; case Tid__cat: return Key__cat;
case Tid__cat_link: return Key__cat_link; case Tid__search_core: return Key__search_core;
case Tid__wiki_solo: return Key__wiki_solo; case Tid__wbase: return Key__wbase;
case Tid__text_solo: return Key__text_solo; case Tid__cat_core: return Key__cat_core;
case Tid__html_solo: return Key__html_solo; case Tid__cat_link: return Key__cat_link;
case Tid__html_data: return Key__html_data; case Tid__wiki_solo: return Key__wiki_solo;
case Tid__file_solo: return Key__file_solo; case Tid__text_solo: return Key__text_solo;
case Tid__file_core: return Key__file_core; case Tid__html_solo: return Key__html_solo;
case Tid__file_data: return Key__file_data; case Tid__html_data: return Key__html_data;
case Tid__file_user: return Key__file_user; case Tid__file_solo: return Key__file_solo;
case Tid__search_link: return Key__search_link; case Tid__file_core: return Key__file_core;
case Tid__random: return Key__random; case Tid__file_data: return Key__file_data;
case Tid__css: return Key__css; case Tid__file_user: return Key__file_user;
case Tid__html_user: return Key__html_user; case Tid__search_link: return Key__search_link;
default: throw Err_.new_unhandled(v); case Tid__random: return Key__random;
} case Tid__css: return Key__css;
} case Tid__html_user: return Key__html_user;
} default: throw Err_.new_unhandled(v);
}
}
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,218 +13,240 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.wikis.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; package gplx.xowa.wikis.data;
import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.core.lists.hashs.*;
import gplx.xowa.wikis.dbs.*; import gplx.xowa.wikis.data.tbls.*; import gplx.Byte_;
import gplx.xowa.wikis.domains.*; import gplx.xowa.bldrs.infos.*; import gplx.xowa.wikis.metas.*; import gplx.DateAdp;
public class Xow_db_mgr { import gplx.Err_;
private final Io_url wiki_root_dir; import gplx.Guid_adp_;
private final String domain_str; // needed for generating new files; EX: en.wikipedia.org-text.ns.001.xowa import gplx.Int_;
private final Ordered_hash hash_by_id = Ordered_hash_.New(); private final Xow_db_file_hash hash_by_tids = new Xow_db_file_hash(); import gplx.Int_ary_;
private int db_id_next = 0; import gplx.Io_mgr;
public Xow_db_mgr(Io_url wiki_root_dir, String domain_str) { import gplx.Io_url;
this.wiki_root_dir = wiki_root_dir; import gplx.List_adp;
this.domain_str = domain_str; import gplx.List_adp_;
} import gplx.Ordered_hash;
public Xowd_core_db_props Props() {return props;} private Xowd_core_db_props props = Xowd_core_db_props.Test; import gplx.Ordered_hash_;
public Db_cfg_tbl Tbl__cfg() {return db__core.Tbl__cfg();} import gplx.String_;
public Xowd_page_tbl Tbl__page() {return db__core.Tbl__page();} import gplx.dbs.Db_cmd_mode;
public Xow_db_file Db__core() {return db__core;} private Xow_db_file db__core; import gplx.dbs.Db_conn;
public Xow_db_file Db__text() {return db__text;} private Xow_db_file db__text; import gplx.dbs.Db_conn_bldr;
public Xow_db_file Db__html() {return db__html;} private Xow_db_file db__html; import gplx.dbs.cfgs.Db_cfg_tbl;
public Xow_db_file Db__cat_core() {return db__cat_core;} private Xow_db_file db__cat_core; import gplx.xowa.Xoa_app_;
public Xow_db_file Db__wbase() {return db__wbase;} private Xow_db_file db__wbase; public void Db__wbase_(Xow_db_file v) {db__wbase = v;} import gplx.xowa.Xow_wiki;
public void Init_by_load(Io_url core_url) { import gplx.xowa.bldrs.infos.Xob_info_file;
// clear lists import gplx.xowa.bldrs.infos.Xob_info_session;
hash_by_id.Clear(); import gplx.xowa.wikis.data.tbls.Xowd_page_tbl;
hash_by_tids.Clear(); import gplx.xowa.wikis.data.tbls.Xowd_text_tbl;
// create core_conn / core_db public class Xow_db_mgr {
Db_conn core_conn = Db_conn_bldr.Instance.Get(core_url); private final Io_url wiki_root_dir;
props = Xowd_core_db_props.Cfg_load(core_conn); // load props to get layout_text private final String domain_str; // needed for generating new files; EX: en.wikipedia.org-text.ns.001.xowa
Dbs__set_by_tid(Xow_db_file.Load(props, Xow_db_file_.Uid__core, Xow_db_file__core_.Core_db_tid(props.Layout_text()), core_url, Xob_info_file.Ns_ids_empty, Xob_info_file.Part_id_1st, Guid_adp_.Empty)); private final Ordered_hash hash_by_id = Ordered_hash_.New(); private final Xow_db_file_hash hash_by_tids = new Xow_db_file_hash();
private int db_id_next = 0;
// load dbs from "xowa_db" tbl public Xow_db_mgr(Io_url wiki_root_dir, String domain_str) {
Xow_db_file[] ary = db__core.Tbl__db().Select_all(props, core_url.OwnerDir()); this.wiki_root_dir = wiki_root_dir;
int len = ary.length; this.domain_str = domain_str;
for (int i = 0; i < len; i++) { }
Xow_db_file db = ary[i]; public Xowd_core_db_props Props() {return props;} private Xowd_core_db_props props = Xowd_core_db_props.Test;
Dbs__set_by_tid(db); public Db_cfg_tbl Tbl__cfg() {return db__core.Tbl__cfg();}
Dbs__add(db); public Xowd_page_tbl Tbl__page() {return db__core.Tbl__page();}
} public Xow_db_file Db__core() {return db__core;} private Xow_db_file db__core;
} public Xow_db_file Db__text() {return db__text;} private Xow_db_file db__text;
public void Init_by_make(Xowd_core_db_props props, Xob_info_session info_session) { public Xow_db_file Db__html() {return db__html;} private Xow_db_file db__html;
this.props = props; public Xow_db_file Db__cat_core() {return db__cat_core;} private Xow_db_file db__cat_core;
public Xow_db_file Db__wbase() {return db__wbase;} private Xow_db_file db__wbase; public void Db__wbase_(Xow_db_file v) {db__wbase = v;}
// save data public void Init_by_load(Io_url core_url) {
Xow_db_file core_db = Xow_db_file__core_.Make_core_db(props, info_session, wiki_root_dir, domain_str); // clear lists
Dbs__set_by_tid(core_db); hash_by_id.Clear();
Dbs__add_and_save(core_db); hash_by_tids.Clear();
props.Cfg_save(db__core.Tbl__cfg()); // NOTE: must save cfg now, especially zip_tid; latter will be reloaded after import is done;
} // create core_conn / core_db
public void Rls() { Db_conn core_conn = Db_conn_bldr.Instance.Get(core_url);
int len = hash_by_id.Len(); props = Xowd_core_db_props.Cfg_load(core_conn); // load props to get layout_text
for (int i = 0; i < len; i++) { Dbs__set_by_tid(Xow_db_file.Load(props, Xow_db_file_.Uid__core, Xow_db_file__core_.Core_db_tid(props.Layout_text()), core_url, Xob_info_file.Ns_ids_empty, Xob_info_file.Part_id_1st, Guid_adp_.Empty));
Xow_db_file db_file = (Xow_db_file)hash_by_id.Get_at(i);
db_file.Rls(); // load dbs from "xowa_db" tbl
} Xow_db_file[] ary = db__core.Tbl__db().Select_all(props, core_url.OwnerDir());
} int len = ary.length;
for (int i = 0; i < len; i++) {
public int Dbs__len() {return hash_by_id.Len();} Xow_db_file db = ary[i];
public Xow_db_file Dbs__get_at(int i) {return (Xow_db_file)hash_by_id.Get_at(i);} Dbs__set_by_tid(db);
public Xow_db_file Dbs__get_by_id_or_fail(int id) {return (Xow_db_file)hash_by_id.Get_by_or_fail(id);} Dbs__add(db);
public Xow_db_file Dbs__get_by_id_or_null(int id) {return (Xow_db_file)hash_by_id.Get_by(id);} }
public Xow_db_file Dbs__get_by_tid_or_core(byte... tids_ary) {Xow_db_file rv = Dbs__get_by_tid_or_null(tids_ary); return rv == null ? db__core : rv;} }
public Xow_db_file Dbs__get_by_tid_or_null(byte... tids_ary) { public void Init_by_make(Xowd_core_db_props props, Xob_info_session info_session) {
int tids_len = tids_ary.length; this.props = props;
for (int i = 0; i < tids_len; ++i) {
byte tid = tids_ary[i]; // save data
Ordered_hash tid_dbs = hash_by_tids.Get_by_tid_or_null(tid); if (tid_dbs == null) continue; Xow_db_file core_db = Xow_db_file__core_.Make_core_db(props, info_session, wiki_root_dir, domain_str);
int tid_dbs_len = tid_dbs.Len(); Dbs__set_by_tid(core_db);
if (tid_dbs_len != 1) { // NOTE: occurs when multiple search imports fail; DATE:2016-04-04 Dbs__add_and_save(core_db);
Xoa_app_.Usr_dlg().Warn_many("", "", "expecting only 1 db for tid; tid=~{0} len=~{1} db_api=~{2}", tid, tid_dbs.Len(), db__core.Conn().Conn_info().Db_api()); props.Cfg_save(db__core.Tbl__cfg()); // NOTE: must save cfg now, especially zip_tid; latter will be reloaded after import is done;
} }
return (Xow_db_file)tid_dbs.Get_at(tid_dbs_len - 1); // get last idx; public void Rls() {
} int len = hash_by_id.Len();
return null; for (int i = 0; i < len; i++) {
} Xow_db_file db_file = (Xow_db_file)hash_by_id.Get_at(i);
public Xow_db_file Dbs__assert_by_tid(byte tid) { db_file.Rls();
Xow_db_file rv = Dbs__get_by_tid_or_null(tid); }
if (rv == null) { }
rv = Dbs__make_by_tid(tid);
} public int Dbs__len() {return hash_by_id.Len();}
return rv; public Xow_db_file Dbs__get_at(int i) {return (Xow_db_file)hash_by_id.Get_at(i);}
} public Xow_db_file Dbs__get_by_id_or_fail(int id) {return (Xow_db_file)hash_by_id.Get_by_or_fail(id);}
public Ordered_hash Dbs__get_hash_by_tid(int tid) {return hash_by_tids.Get_by_tid_or_null((byte)tid);} public Xow_db_file Dbs__get_by_id_or_null(int id) {return (Xow_db_file)hash_by_id.Get_by(id);}
public Xow_db_file Dbs__make_by_tid(byte tid) { public Xow_db_file Dbs__get_by_tid_or_core(byte... tids_ary) {Xow_db_file rv = Dbs__get_by_tid_or_null(tids_ary); return rv == null ? db__core : rv;}
int tid_idx = Get_tid_idx(hash_by_tids, tid); public Xow_db_file Dbs__get_by_tid_or_null(byte... tids_ary) {
return Dbs__make_by_tid(tid, Xob_info_file.Ns_ids_empty, tid_idx, Get_tid_name(tid_idx, tid)); int tids_len = tids_ary.length;
} for (int i = 0; i < tids_len; ++i) {
public Xow_db_file Dbs__make_by_tid(byte tid, String ns_ids, int part_id, String file_name_suffix) { byte tid = tids_ary[i];
return Dbs__make_by_id(db_id_next++, tid, ns_ids, part_id, file_name_suffix); Ordered_hash tid_dbs = hash_by_tids.Get_by_tid_or_null(tid); if (tid_dbs == null) continue;
} int tid_dbs_len = tid_dbs.Len();
public Xow_db_file Dbs__make_by_id(int id, byte tid, String ns_ids, int part_id, String file_name_suffix) { if (tid_dbs_len != 1) { // NOTE: occurs when multiple search imports fail; DATE:2016-04-04
Io_url url = wiki_root_dir.GenSubFil(domain_str + file_name_suffix); Xoa_app_.Usr_dlg().Warn_many("", "", "expecting only 1 db for tid; tid=~{0} len=~{1} db_api=~{2}", tid, tid_dbs.Len(), db__core.Conn().Conn_info().Db_api());
Xow_db_file rv = Xow_db_file.Make(db__core.Info_session(), props, id, tid, url, ns_ids, part_id, db__core.Url().NameAndExt(), Db_conn_bldr.Instance.New(url)); }
Dbs__add_and_save(rv); return (Xow_db_file)tid_dbs.Get_at(tid_dbs_len - 1); // get last idx;
Dbs__set_by_tid(rv); }
return rv; return null;
} }
public Xow_db_file Dbs__remake_by_tid(byte tid) { public Xow_db_file Dbs__assert_by_tid(byte tid) {
Dbs__delete_by_tid(tid); Xow_db_file rv = Dbs__get_by_tid_or_null(tid);
return Dbs__make_by_tid(tid); if (rv == null) {
} rv = Dbs__make_by_tid(tid);
public void Dbs__delete_by_tid(byte... tids) { }
int len = hash_by_id.Len(); return rv;
for (int i = 0; i < len; ++i) { }
Xow_db_file db = (Xow_db_file)hash_by_id.Get_at(i); public Ordered_hash Dbs__get_hash_by_tid(int tid) {return hash_by_tids.Get_by_tid_or_null((byte)tid);}
if (!Byte_.Match_any(db.Tid(), tids)) continue; public Xow_db_file Dbs__make_by_tid(byte tid) {
db.Rls(); int tid_idx = Get_tid_idx(hash_by_tids, tid);
Io_mgr.Instance.DeleteFil_args(db.Url()).MissingFails_off().Exec(); return Dbs__make_by_tid(tid, Xob_info_file.Ns_ids_empty, tid_idx, Get_tid_name(tid_idx, tid));
db.Cmd_mode_(Db_cmd_mode.Tid_delete); }
} public Xow_db_file Dbs__make_by_tid(byte tid, String ns_ids, int part_id, String file_name_suffix) {
db__core.Tbl__db().Commit_all(this); return Dbs__make_by_id(db_id_next++, tid, ns_ids, part_id, file_name_suffix);
}
// call init again to regen list of dbs public Xow_db_file Dbs__make_by_id(int id, byte tid, String ns_ids, int part_id, String file_name_suffix) {
this.Init_by_load(db__core.Url()); Io_url url = wiki_root_dir.GenSubFil(domain_str + file_name_suffix);
} Xow_db_file rv = Xow_db_file.Make(db__core.Info_session(), props, id, tid, url, ns_ids, part_id, db__core.Url().NameAndExt(), Db_conn_bldr.Instance.New(url));
public Xow_db_file Dbs__get_for_create(byte tid, int ns_id) { Dbs__add_and_save(rv);
Xow_db_file[] ary = Dbs__get_ary(tid, ns_id); Dbs__set_by_tid(rv);
if (ary.length == 0) throw Err_.new_wo_type("no dbs exist; wiki=~{0} type=~{1}", domain_str, tid); return rv;
return ary[ary.length - 1]; }
} public Xow_db_file Dbs__remake_by_tid(byte tid) {
public Xow_db_file[] Dbs__get_ary(byte tid, int ns_id) { Dbs__delete_by_tid(tid);
List_adp rv = List_adp_.New(); return Dbs__make_by_tid(tid);
}
// loop all dbs public void Dbs__delete_by_tid(byte... tids) {
int len = this.Dbs__len(); int len = hash_by_id.Len();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; ++i) {
boolean add = false; Xow_db_file db = (Xow_db_file)hash_by_id.Get_at(i);
Xow_db_file db = this.Dbs__get_at(i); if (!Byte_.Match_any(db.Tid(), tids)) continue;
switch (tid) { db.Rls();
// cat_link requested Io_mgr.Instance.DeleteFil_args(db.Url()).MissingFails_off().Exec();
case Xow_db_file_.Tid__cat_link: db.Cmd_mode_(Db_cmd_mode.Tid_delete);
switch (db.Tid()) { }
case Xow_db_file_.Tid__core: db__core.Tbl__db().Commit_all(this);
add = props.Layout_text().Tid_is_all_or_few(); // cat_link will be in "core" if "all" or "few" (-text, -html, -file)
break; // call init again to regen list of dbs
case Xow_db_file_.Tid__cat_link: this.Init_by_load(db__core.Url());
add = true; }
break; public Xow_db_file Dbs__get_for_create(byte tid, int ns_id) {
} Xow_db_file[] ary = Dbs__get_ary(tid, ns_id);
break; if (ary.length == 0) throw Err_.new_wo_type("no dbs exist; wiki=~{0} type=~{1}", domain_str, tid);
// text requested return ary[ary.length - 1];
case Xow_db_file_.Tid__text: }
switch (db.Tid()) { public Xow_db_file[] Dbs__get_ary(byte tid, int ns_id) {
case Xow_db_file_.Tid__core: List_adp rv = List_adp_.New();
add = props.Layout_text().Tid_is_all(); // text will be in "core" if "all"
break; // loop all dbs
case Xow_db_file_.Tid__text_solo: // EX: "en.wikipedia.org-text.xowa" int len = this.Dbs__len();
add = true; // text will be in db if solo; for (int i = 0; i < len; i++) {
break; boolean add = false;
case Xow_db_file_.Tid__text: // EX: "en.wikipedia.org-text-ns.000.xowa" Xow_db_file db = this.Dbs__get_at(i);
int[] db_ns_ids = Int_ary_.Parse(db.Ns_ids(), "|"); // need to handle both "0" and "0|4" switch (tid) {
for (int db_ns_id : db_ns_ids) { // cat_link requested
if (db_ns_id == ns_id) { case Xow_db_file_.Tid__cat_link:
add = true; // text will be in db if ns matches; EX: en.wikipedia.org-text-ns.014.xowa switch (db.Tid()) {
break; case Xow_db_file_.Tid__core:
} add = props.Layout_text().Tid_is_all_or_few(); // cat_link will be in "core" if "all" or "few" (-text, -html, -file)
} break;
break; case Xow_db_file_.Tid__cat_link:
} add = true;
break; break;
} }
if (add) break;
rv.Add(db); // text requested
} case Xow_db_file_.Tid__text:
switch (db.Tid()) {
return (Xow_db_file[])rv.To_ary_and_clear(Xow_db_file.class); case Xow_db_file_.Tid__core:
} add = props.Layout_text().Tid_is_all(); // text will be in "core" if "all"
public void Create_page(Xowd_page_tbl core_tbl, Xowd_text_tbl text_tbl, int page_id, int ns_id, byte[] ttl_wo_ns, boolean redirect, DateAdp modified_on, byte[] text_zip_data, int text_raw_len, int random_int, int text_db_id, int html_db_id) { break;
core_tbl.Insert_cmd_by_batch(page_id, ns_id, ttl_wo_ns, redirect, modified_on, text_raw_len, random_int, text_db_id, html_db_id, -1); case Xow_db_file_.Tid__text_solo: // EX: "en.wikipedia.org-text.xowa"
text_tbl.Insert_cmd_by_batch(page_id, text_zip_data); add = true; // text will be in db if solo;
} break;
private void Dbs__set_by_tid(Xow_db_file db) { case Xow_db_file_.Tid__text: // EX: "en.wikipedia.org-text-ns.000.xowa"
switch (db.Tid()) { int[] db_ns_ids = Int_ary_.Parse(db.Ns_ids(), "|"); // need to handle both "0" and "0|4"
case Xow_db_file_.Tid__wiki_solo: for (int db_ns_id : db_ns_ids) {
case Xow_db_file_.Tid__text_solo: if (db_ns_id == ns_id) {
case Xow_db_file_.Tid__core : {db__core = db; if (props.Layout_text().Tid_is_all_or_few()) db__cat_core = db__text = db; break;} add = true; // text will be in db if ns matches; EX: en.wikipedia.org-text-ns.014.xowa
case Xow_db_file_.Tid__text : {db__text = db; break;} break;
case Xow_db_file_.Tid__html_data : {db__html = db; break;} }
case Xow_db_file_.Tid__wbase : {if (db__wbase == null) db__wbase = db; break;} }
case Xow_db_file_.Tid__cat_core : break;
case Xow_db_file_.Tid__cat : {if (db__cat_core == null) db__cat_core = db; break;} }
} break;
} }
private void Dbs__add(Xow_db_file db_file) { if (add)
int db_id = db_file.Id(); rv.Add(db);
hash_by_id.Add(db_id, db_file); }
hash_by_tids.Add_or_new(db_file);
if (db_id >= db_id_next) // always set db_id_next to largest value in given set of dbs; EX: dbs=[0,1,10]; db_id_next should be 11 return (Xow_db_file[])rv.To_ary_and_clear(Xow_db_file.class);
db_id_next = db_id + 1; }
} public void Create_page(Xowd_page_tbl core_tbl, Xowd_text_tbl text_tbl, int page_id, int ns_id, byte[] ttl_wo_ns, boolean redirect, DateAdp modified_on, byte[] text_zip_data, int text_raw_len, int random_int, int text_db_id, int html_db_id) {
private void Dbs__add_and_save(Xow_db_file db_file) { core_tbl.Insert_cmd_by_batch(page_id, ns_id, ttl_wo_ns, redirect, modified_on, text_raw_len, random_int, text_db_id, html_db_id, -1);
Dbs__add(db_file); text_tbl.Insert_cmd_by_batch(page_id, text_zip_data);
}
db__core.Tbl__db().Commit_all(this); private void Dbs__set_by_tid(Xow_db_file db) {
db_file.Info_file().Save(db_file.Tbl__cfg()); switch (db.Tid()) {
db_file.Info_session().Save(db_file.Tbl__cfg()); case Xow_db_file_.Tid__wiki_solo:
} case Xow_db_file_.Tid__text_solo:
private int Get_tid_idx(Xow_db_file_hash hash, byte tid) {return hash.Count_of_tid(tid) + Int_.Base1;} case Xow_db_file_.Tid__core : {db__core = db; if (props.Layout_text().Tid_is_all_or_few()) db__cat_core = db__text = db; break;}
private static String Get_tid_name(int tid_idx, byte tid) { case Xow_db_file_.Tid__text : {db__text = db; break;}
String tid_name = Xow_db_file_.To_key(tid); case Xow_db_file_.Tid__html_data : {db__html = db; break;}
String tid_idx_str = ""; case Xow_db_file_.Tid__wbase : {if (db__wbase == null) db__wbase = db; break;}
switch (tid) { case Xow_db_file_.Tid__cat_core :
case Xow_db_file_.Tid__cat_core : break; case Xow_db_file_.Tid__cat : {if (db__cat_core == null) db__cat_core = db; break;}
case Xow_db_file_.Tid__cat_link : tid_idx_str = "-db." + Int_.To_str_pad_bgn_zero(tid_idx, 3); break; }
default : tid_idx_str = tid_idx == 1 ? "" : "-db." + Int_.To_str_pad_bgn_zero(tid_idx, 3); break; }
} private void Dbs__add(Xow_db_file db_file) {
return String_.Format("-{0}{1}.xowa", tid_name, tid_idx_str); // EX: en.wikipedia.org-text-001.sqlite3 int db_id = db_file.Id();
} hash_by_id.Add(db_id, db_file);
hash_by_tids.Add_or_new(db_file);
// helper method for wikis to (a) init db_mgr; (b) load wiki.props; should probably be moved to more generic "wiki.Init_by_db()" if (db_id >= db_id_next) // always set db_id_next to largest value in given set of dbs; EX: dbs=[0,1,10]; db_id_next should be 11
public static void Init_by_load(Xow_wiki wiki, Io_url core_url) { db_id_next = db_id + 1;
wiki.Data__core_mgr().Init_by_load(core_url); }
wiki.Props().Init_by_load(wiki.App(), wiki.Data__core_mgr().Tbl__cfg()); // load Main_page private void Dbs__add_and_save(Xow_db_file db_file) {
} Dbs__add(db_file);
}
db__core.Tbl__db().Commit_all(this);
db_file.Info_file().Save(db_file.Tbl__cfg());
db_file.Info_session().Save(db_file.Tbl__cfg());
}
private int Get_tid_idx(Xow_db_file_hash hash, byte tid) {return hash.Count_of_tid(tid) + Int_.Base1;}
private static String Get_tid_name(int tid_idx, byte tid) {
String tid_name = Xow_db_file_.To_key(tid);
String tid_idx_str = "";
switch (tid) {
case Xow_db_file_.Tid__cat_core : break;
case Xow_db_file_.Tid__cat_link : tid_idx_str = "-db." + Int_.To_str_pad_bgn_zero(tid_idx, 3); break;
default : tid_idx_str = tid_idx == 1 ? "" : "-db." + Int_.To_str_pad_bgn_zero(tid_idx, 3); break;
}
return String_.Format("-{0}{1}.xowa", tid_name, tid_idx_str); // EX: en.wikipedia.org-text-001.sqlite3
}
// helper method for wikis to (a) init db_mgr; (b) load wiki.props; should probably be moved to more generic "wiki.Init_by_db()"
public static void Init_by_load(Xow_wiki wiki, Io_url core_url) {
wiki.Data__core_mgr().Init_by_load(core_url);
wiki.Props().Init_by_load(wiki.App(), wiki.Data__core_mgr().Tbl__cfg()); // load Main_page
}
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,66 +13,81 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.wikis.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; package gplx.xowa.wikis.dbs;
import gplx.core.ios.*; import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.dbs.qrys.*;
import gplx.xowa.wikis.*; import gplx.DateAdp;
public class Xodb_save_mgr_sql implements Xodb_save_mgr { import gplx.Datetime_now;
private final Xodb_mgr_sql db_mgr; import gplx.String_;
public Xodb_save_mgr_sql(Xodb_mgr_sql db_mgr) {this.db_mgr = db_mgr;} import gplx.dbs.Db_rdr;
public boolean Create_enabled() {return create_enabled;} public void Create_enabled_(boolean v) {create_enabled = v;} private boolean create_enabled; import gplx.dbs.Dbmeta_fld_itm;
public boolean Update_modified_on_enabled() {return update_modified_on_enabled;} public void Update_modified_on_enabled_(boolean v) {update_modified_on_enabled = v;} private boolean update_modified_on_enabled; import gplx.xowa.Xoa_ttl;
public int Page_id_next() {return page_id_next;} public void Page_id_next_(int v) {page_id_next = v;} private int page_id_next; import gplx.xowa.Xoae_page;
public int Data_create(Xowe_wiki wiki, Xoa_ttl ttl, byte[] text_raw) { import gplx.xowa.Xowe_wiki;
int ns_id = ttl.Ns().Id(); import gplx.xowa.wikis.data.Xow_db_file;
Xow_db_file db_file = db_mgr.Core_data_mgr().Db__core(); import gplx.xowa.wikis.data.Xow_db_mgr;
int ns_count = db_file.Tbl__ns().Select_ns_count(ns_id) + 1; import gplx.xowa.wikis.data.Xowd_cfg_key_;
int page_id = db_file.Tbl__cfg().Select_int_or(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, -1); import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
if (page_id == -1) { // HACK: changed for tests; was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;") import gplx.xowa.wikis.data.tbls.Xowd_page_tbl;
Db_rdr rdr = db_mgr.Core_data_mgr().Tbl__page().Conn().Stmt_select(db_file.Tbl__page().Tbl_name(), String_.Ary(db_file.Tbl__page().Fld_page_id()), Dbmeta_fld_itm.Str_ary_empty).Exec_select__rls_auto(); import gplx.xowa.wikis.data.tbls.Xowd_text_tbl;
try {
int max_page_id = -1; public class Xodb_save_mgr_sql implements Xodb_save_mgr {
while (rdr.Move_next()) { private final Xodb_mgr_sql db_mgr;
int cur_page_id = rdr.Read_int("page_id"); public Xodb_save_mgr_sql(Xodb_mgr_sql db_mgr) {this.db_mgr = db_mgr;}
if (cur_page_id > max_page_id) max_page_id = cur_page_id; public boolean Create_enabled() {return create_enabled;} public void Create_enabled_(boolean v) {create_enabled = v;} private boolean create_enabled;
} public boolean Update_modified_on_enabled() {return update_modified_on_enabled;} public void Update_modified_on_enabled_(boolean v) {update_modified_on_enabled = v;} private boolean update_modified_on_enabled;
page_id = max_page_id + 1; public int Page_id_next() {return page_id_next;} public void Page_id_next_(int v) {page_id_next = v;} private int page_id_next;
db_mgr.Core_data_mgr().Tbl__cfg().Upsert_int(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, page_id + 1); public int Data_create(Xowe_wiki wiki, Xoa_ttl ttl, byte[] text_raw) {
} finally {rdr.Rls();} int ns_id = ttl.Ns().Id();
} Xow_db_file db_file = db_mgr.Core_data_mgr().Db__core();
Xow_db_mgr fsys_mgr = db_mgr.Core_data_mgr(); int ns_count = db_file.Tbl__ns().Select_ns_count(ns_id) + 1;
Xow_db_file page_text_db = fsys_mgr.Db__text(); int page_id = db_file.Tbl__cfg().Select_int_or(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, -1);
if (page_text_db == null) page_text_db = fsys_mgr.Db__core(); // HACK: needed for create new wiki DATE:2016-10-29 if (page_id == -1) { // HACK: changed for tests; was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;")
Xowd_text_tbl page_text_tbl = page_text_db.Tbl__text(); Db_rdr rdr = db_mgr.Core_data_mgr().Tbl__page().Conn().Stmt_select(db_file.Tbl__page().Tbl_name(), String_.Ary(db_file.Tbl__page().Fld_page_id()), Dbmeta_fld_itm.Str_ary_empty).Exec_select__rls_auto();
byte[] text_zip = page_text_tbl.Zip(text_raw); try {
boolean redirect = wiki.Redirect_mgr().Is_redirect(text_raw, text_raw.length); int max_page_id = -1;
Xowd_page_tbl page_core_tbl = db_mgr.Core_data_mgr().Tbl__page(); while (rdr.Move_next()) {
page_core_tbl.Insert_bgn(); int cur_page_id = rdr.Read_int("page_id");
page_text_tbl.Insert_bgn(); if (cur_page_id > max_page_id) max_page_id = cur_page_id;
try { }
db_mgr.Core_data_mgr().Create_page(page_core_tbl, page_text_tbl, page_id, ns_id, ttl.Page_db(), redirect, Datetime_now.Get(), text_zip, text_raw.length, ns_count, page_text_db.Id(), -1); page_id = max_page_id + 1;
db_file.Tbl__ns().Update_ns_count(ns_id, ns_count); db_mgr.Core_data_mgr().Tbl__cfg().Upsert_int(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, page_id + 1);
db_file.Tbl__cfg().Update_int(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, page_id + 1); } finally {rdr.Rls();}
} finally { }
page_core_tbl.Insert_end(); Xow_db_mgr fsys_mgr = db_mgr.Core_data_mgr();
page_text_tbl.Insert_end(); Xow_db_file page_text_db = fsys_mgr.Db__text();
} if (page_text_db == null) page_text_db = fsys_mgr.Db__core(); // HACK: needed for create new wiki DATE:2016-10-29
return page_id; Xowd_text_tbl page_text_tbl = page_text_db.Tbl__text();
} byte[] text_zip = page_text_tbl.Zip(text_raw);
public void Data_update(Xoae_page page, byte[] text_raw) { boolean redirect = wiki.Redirect_mgr().Is_redirect(text_raw, text_raw.length);
boolean redirect = page.Wikie().Redirect_mgr().Is_redirect(text_raw, text_raw.length); Xowd_page_tbl page_core_tbl = db_mgr.Core_data_mgr().Tbl__page();
DateAdp modified = update_modified_on_enabled ? Datetime_now.Get() : page.Db().Page().Modified_on(); page_core_tbl.Insert_bgn();
int page_id = page.Db().Page().Id(); page_text_tbl.Insert_bgn();
db_mgr.Core_data_mgr().Tbl__page().Update__redirect__modified(page_id, redirect, modified); try {
Xowd_page_itm db_page = new Xowd_page_itm(); db_mgr.Core_data_mgr().Create_page(page_core_tbl, page_text_tbl, page_id, ns_id, ttl.Page_db(), redirect, Datetime_now.Get(), text_zip, text_raw.length, ns_count, page_text_db.Id(), -1);
db_mgr.Load_mgr().Load_by_id(db_page, page_id); db_file.Tbl__ns().Update_ns_count(ns_id, ns_count);
Xowd_text_tbl text_tbl = db_mgr.Core_data_mgr().Dbs__get_by_id_or_fail(db_page.Text_db_id()).Tbl__text(); db_file.Tbl__cfg().Update_int(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, page_id + 1);
text_tbl.Update(page_id, text_raw); } finally {
// int html_db_id = db_page.Html_db_id(); page_core_tbl.Insert_end();
// if (html_db_id != -1) page_text_tbl.Insert_end();
// db_mgr.Core_data_mgr().Tbl__page().Update__html_db_id(page_id, -1); // zap html_db_id so that next load will repopulate it }
} return page_id;
public void Data_rename(Xoae_page page, int trg_ns, byte[] trg_ttl) { }
db_mgr.Core_data_mgr().Tbl__page().Update__ns__ttl(page.Db().Page().Id(), trg_ns, trg_ttl); public void Data_update(Xoae_page page, byte[] text_raw) {
} boolean redirect = page.Wikie().Redirect_mgr().Is_redirect(text_raw, text_raw.length);
public void Clear() {} DateAdp modified = update_modified_on_enabled ? Datetime_now.Get() : page.Db().Page().Modified_on();
} int page_id = page.Db().Page().Id();
db_mgr.Core_data_mgr().Tbl__page().Update__redirect__modified(page_id, redirect, modified);
Xowd_page_itm db_page = new Xowd_page_itm();
db_mgr.Load_mgr().Load_by_id(db_page, page_id);
Xowd_text_tbl text_tbl = db_mgr.Core_data_mgr().Dbs__get_by_id_or_fail(db_page.Text_db_id()).Tbl__text();
text_tbl.Update(page_id, text_raw);
// TOMBSTONE: do not set html_db_id to -1; editing wtxt will now save html; ISSUE#:699; DATE:2020-08-06
// if (db_page.Html_db_id() != -1)
// db_mgr.Core_data_mgr().Tbl__page().Update__html_db_id(page_id, -1); // zap html_db_id so that next load will repopulate it
}
public void Data_rename(Xoae_page page, int trg_ns, byte[] trg_ttl) {
db_mgr.Core_data_mgr().Tbl__page().Update__ns__ttl(page.Db().Page().Id(), trg_ns, trg_ttl);
}
public void Clear() {}
}

View File

@ -1,145 +1,146 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis. for your project on a case-by-case basis.
The terms of each license can be found in the source code repository: The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.wikis.pages; package gplx.xowa.wikis.pages;
import gplx.Bry_; import gplx.Bry_;
import gplx.Bry_bfr; import gplx.Bry_bfr;
import gplx.Bry_bfr_; import gplx.Bry_bfr_;
import gplx.Err_; import gplx.Err_;
import gplx.Gfo_usr_dlg_; import gplx.Gfo_usr_dlg_;
import gplx.core.net.qargs.Gfo_qarg_itm; import gplx.core.net.qargs.Gfo_qarg_itm;
import gplx.core.net.qargs.Gfo_qarg_mgr; import gplx.core.net.qargs.Gfo_qarg_mgr;
import gplx.xowa.Xoa_app; import gplx.xowa.Xoa_app;
import gplx.xowa.Xoa_app_; import gplx.xowa.Xoa_app_;
import gplx.xowa.Xoa_ttl; import gplx.xowa.Xoa_ttl;
import gplx.xowa.Xoa_url; import gplx.xowa.Xoa_url;
import gplx.xowa.Xoa_url_; import gplx.xowa.Xoa_url_;
import gplx.xowa.Xoae_page; import gplx.xowa.Xoae_page;
import gplx.xowa.Xowe_wiki; import gplx.xowa.Xowe_wiki;
import gplx.xowa.Xowe_wiki_; import gplx.xowa.Xowe_wiki_;
import gplx.xowa.addons.wikis.pages.syncs.core.Xosync_read_mgr; import gplx.xowa.addons.wikis.pages.syncs.core.Xosync_read_mgr;
import gplx.xowa.guis.views.Xog_tab_itm; import gplx.xowa.guis.views.Xog_tab_itm;
import gplx.xowa.wikis.data.tbls.Xowd_page_itm; import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
import gplx.xowa.wikis.pages.dbs.Xopg_db_page;
public class Xowe_page_mgr {
private final Xowe_wiki wiki; public class Xowe_page_mgr {
private final Bry_bfr tmp_bfr = Bry_bfr_.New(); private final Xowe_wiki wiki;
private final Gfo_qarg_mgr tmp_qarg_mgr = new Gfo_qarg_mgr(); private final Bry_bfr tmp_bfr = Bry_bfr_.New();
public Xowe_page_mgr(Xowe_wiki wiki) {this.wiki = wiki;} private final Gfo_qarg_mgr tmp_qarg_mgr = new Gfo_qarg_mgr();
public Xosync_read_mgr Sync_mgr() {return read_mgr;} private final Xosync_read_mgr read_mgr = new Xosync_read_mgr(); public Xowe_page_mgr(Xowe_wiki wiki) {this.wiki = wiki;}
public void Init_by_wiki(Xowe_wiki wiki) { public Xosync_read_mgr Sync_mgr() {return read_mgr;} private final Xosync_read_mgr read_mgr = new Xosync_read_mgr();
read_mgr.Init_by_wiki(wiki); public void Init_by_wiki(Xowe_wiki wiki) {
} read_mgr.Init_by_wiki(wiki);
}
public Xoae_page Load_page(Xoa_url url, Xoa_ttl ttl, Xog_tab_itm tab) { // NOTE: called by GUI and HTTP_SERVER; not called by MASS_PARSE
Xoa_app_.Usr_dlg().Log_many("", "", "page.load: url=~{0}", url.To_str()); public Xoae_page Load_page(Xoa_url url, Xoa_ttl ttl, Xog_tab_itm tab) { // NOTE: called by GUI and HTTP_SERVER; not called by MASS_PARSE
Wait_for_popups(wiki.App()); Xoa_app_.Usr_dlg().Log_many("", "", "page.load: url=~{0}", url.To_str());
Xowe_wiki_.Rls_mem_if_needed(wiki); Wait_for_popups(wiki.App());
Xowe_wiki_.Rls_mem_if_needed(wiki);
// handle curid query_arg; EX:en.wikipedia.org/wiki/?curid=303 DATE:2017-02-15
Gfo_qarg_itm[] qarg_ary = url.Qargs_ary(); // handle curid query_arg; EX:en.wikipedia.org/wiki/?curid=303 DATE:2017-02-15
// if qargs exist... Gfo_qarg_itm[] qarg_ary = url.Qargs_ary();
if (qarg_ary.length > 0) { // if qargs exist...
try { if (qarg_ary.length > 0) {
tmp_qarg_mgr.Init(qarg_ary); try {
byte[] curid_bry = tmp_qarg_mgr.Read_bry_or(Xoa_url_.Qarg__curid, null); tmp_qarg_mgr.Init(qarg_ary);
// if "curid" qarg exists.... byte[] curid_bry = tmp_qarg_mgr.Read_bry_or(Xoa_url_.Qarg__curid, null);
if (curid_bry != null) { // if "curid" qarg exists....
int curid = Bry_.To_int_or(curid_bry, -1); if (curid_bry != null) {
Xowd_page_itm tmp_page = wiki.Data__core_mgr().Db__core().Tbl__page().Select_by_id_or_null(curid); int curid = Bry_.To_int_or(curid_bry, -1);
// if curid exists in page tbl... Xowd_page_itm tmp_page = wiki.Data__core_mgr().Db__core().Tbl__page().Select_by_id_or_null(curid);
if (tmp_page != null) { // if curid exists in page tbl...
ttl = wiki.Ttl_parse(tmp_page.Ns_id(), tmp_page.Ttl_page_db()); if (tmp_page != null) {
// handle "home/wiki/?curid=123"; XO automatically changes to "home/wiki/Main_Page?curid=123"; change back to "home/wiki/?curid=123" ttl = wiki.Ttl_parse(tmp_page.Ns_id(), tmp_page.Ttl_page_db());
if (url.Page_is_main()) { // handle "home/wiki/?curid=123"; XO automatically changes to "home/wiki/Main_Page?curid=123"; change back to "home/wiki/?curid=123"
url.Page_bry_(Bry_.Empty); if (url.Page_is_main()) {
} url.Page_bry_(Bry_.Empty);
} }
} }
} catch (Exception exc) { }
Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to handle cur_id; url=~{0} err=~{1}", url.Raw(), Err_.Message_gplx_log(exc)); } catch (Exception exc) {
} Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to handle cur_id; url=~{0} err=~{1}", url.Raw(), Err_.Message_gplx_log(exc));
} }
}
// load page meta; wait_for_popups
Xoae_page page = wiki.Data_mgr().Load_page_and_parse(url, ttl, wiki.Lang(), tab, false); // load page meta; wait_for_popups
ttl = page.Ttl(); // note that Load_page_and_parse can redirect ttl; EX: Special:Random -> A; DATE:2017-01-05 Xoae_page page = wiki.Data_mgr().Load_page_and_parse(url, ttl, wiki.Lang(), tab, false);
Wait_for_popups(wiki.App()); ttl = page.Ttl(); // note that Load_page_and_parse can redirect ttl; EX: Special:Random -> A; DATE:2017-01-05
Wait_for_popups(wiki.App());
// auto-update
Xoa_ttl redirect_ttl = read_mgr.Auto_update(wiki, page, ttl); // auto-update
if (redirect_ttl != null) { Xoa_ttl redirect_ttl = read_mgr.Auto_update(wiki, page, ttl);
// page-sync occurred; update ttl to handle any redirection; DATE:2017-05-07 if (redirect_ttl != null) {
ttl = redirect_ttl; // page-sync occurred; update ttl to handle any redirection; DATE:2017-05-07
ttl = redirect_ttl;
// reload metadata, needed to pick up Html_db_id; DATE:2017-03-13
page = wiki.Data_mgr().Load_page_and_parse(url, ttl, wiki.Lang(), tab, false); // reload metadata, needed to pick up Html_db_id; DATE:2017-03-13
} page = wiki.Data_mgr().Load_page_and_parse(url, ttl, wiki.Lang(), tab, false);
}
// load from html_db
boolean from_html_db = page.Db().Page().Html_db_id() != -1; // load from html_db
boolean read_from_html_db_preferred = wiki.Html__hdump_mgr().Load_mgr().Read_preferred(); boolean from_html_db = page.Db().Page().Html_db_id() != Xopg_db_page.HTML_DB_ID_NULL;
boolean isCategoryPage = ttl.Ns().Id_is_ctg(); boolean read_from_html_db_preferred = wiki.Html__hdump_mgr().Load_mgr().Read_preferred();
if (from_html_db) { boolean isCategoryPage = ttl.Ns().Id_is_ctg();
if (read_from_html_db_preferred) { if (from_html_db) {
wiki.Html__hdump_mgr().Load_mgr().Load_by_xowe(page, !isCategoryPage); // NOTE: if loading for html_db, do not build page_box; will be built below; ISSUE#:722; DATE:2020-05-17 if (read_from_html_db_preferred) {
int html_len = Bry_.Len(page.Db().Html().Html_bry()); wiki.Html__hdump_mgr().Load_mgr().Load_by_xowe(page, !isCategoryPage); // NOTE: if loading for html_db, do not build page_box; will be built below; ISSUE#:722; DATE:2020-05-17
from_html_db = html_len > 0; // NOTE: archive.org has some wtxt_dbs which included page|html_db_id without actual html_dbs; DATE:2016-06-22 int html_len = Bry_.Len(page.Db().Html().Html_bry());
Gfo_usr_dlg_.Instance.Log_many("", "", "page_load: loaded html; page=~{0} html_len=~{1}", ttl.Full_db(), html_len); from_html_db = html_len > 0; // NOTE: archive.org has some wtxt_dbs which included page|html_db_id without actual html_dbs; DATE:2016-06-22
} Gfo_usr_dlg_.Instance.Log_many("", "", "page_load: loaded html; page=~{0} html_len=~{1}", ttl.Full_db(), html_len);
else }
from_html_db = false; else
} from_html_db = false;
}
// load from wtxt_db; occurs if (a) no html_db_id; (b) option says to use wtxt db; (c) html_db_id exists, but no html_db;
if (!from_html_db) { // load from wtxt_db; occurs if (a) no html_db_id; (b) option says to use wtxt db; (c) html_db_id exists, but no html_db;
wiki.Parser_mgr().Parse(page, false); if (!from_html_db) {
wiki.Parser_mgr().Parse(page, false);
// load from html_db if no wtxt found and option just marked as not read_preferred
if ( Bry_.Len_eq_0(page.Db().Text().Text_bry()) // no wtxt found // load from html_db if no wtxt found and option just marked as not read_preferred
&& !ttl.Ns().Id_is_special() // skip special if ( Bry_.Len_eq_0(page.Db().Text().Text_bry()) // no wtxt found
&& !read_from_html_db_preferred // read preferred not marked && !ttl.Ns().Id_is_special() // skip special
) { && !read_from_html_db_preferred // read preferred not marked
wiki.Html__hdump_mgr().Load_mgr().Load_by_xowe(page, true); ) {
from_html_db = Bry_.Len_gt_0(page.Db().Html().Html_bry()); wiki.Html__hdump_mgr().Load_mgr().Load_by_xowe(page, true);
} from_html_db = Bry_.Len_gt_0(page.Db().Html().Html_bry());
else { }
Gfo_usr_dlg_.Instance.Log_many("", "", "page_load: loaded wikitext; page=~{0} wikitext_len=~{1}", ttl.Full_db(), page.Db().Text().Text_bry().length); else {
} Gfo_usr_dlg_.Instance.Log_many("", "", "page_load: loaded wikitext; page=~{0} wikitext_len=~{1}", ttl.Full_db(), page.Db().Text().Text_bry().length);
} }
page.Html_data().Hdump_exists_(from_html_db); }
page.Html_data().Hdump_exists_(from_html_db);
// if [[Category]], generate catlinks (subc; page; file)
if (isCategoryPage) { // if [[Category]], generate catlinks (subc; page; file)
wiki.Ctg__catpage_mgr().Write_catpage(tmp_bfr, page); if (isCategoryPage) {
if (from_html_db) { wiki.Ctg__catpage_mgr().Write_catpage(tmp_bfr, page);
wiki.Ctg__pagebox_wtr().Write_pagebox(tmp_bfr, page); if (from_html_db) {
page.Db().Html().Html_bry_(Bry_.Add(page.Db().Html().Html_bry(), tmp_bfr.To_bry_and_clear())); wiki.Ctg__pagebox_wtr().Write_pagebox(tmp_bfr, page);
} page.Db().Html().Html_bry_(Bry_.Add(page.Db().Html().Html_bry(), tmp_bfr.To_bry_and_clear()));
else { }
page.Html_data().Catpage_data_(tmp_bfr.To_bry_and_clear()); else {
} page.Html_data().Catpage_data_(tmp_bfr.To_bry_and_clear());
} }
}
return page;
} return page;
private static void Wait_for_popups(Xoa_app app) {// HACK: wait for popups to finish, else thread errors due to popups and loader mutating cached items }
if (app.Mode().Tid_is_http()) return; private static void Wait_for_popups(Xoa_app app) {// HACK: wait for popups to finish, else thread errors due to popups and loader mutating cached items
int wait_count = 0; if (app.Mode().Tid_is_http()) return;
while (gplx.xowa.htmls.modules.popups.Xow_popup_mgr.Running() && ++wait_count < 100) int wait_count = 0;
gplx.core.threads.Thread_adp_.Sleep(10); while (gplx.xowa.htmls.modules.popups.Xow_popup_mgr.Running() && ++wait_count < 100)
} gplx.core.threads.Thread_adp_.Sleep(10);
} }
}

View File

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,54 +13,65 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.wikis.pages.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.pages.*; package gplx.xowa.wikis.pages.dbs;
import gplx.xowa.wikis.nss.*;
public class Xopg_db_page { import gplx.Bool_;
public Xopg_db_page() {this.Clear();} import gplx.DateAdp;
// from page table import gplx.DateAdp_;
public boolean Exists() {return exists;} private boolean exists; import gplx.xowa.Xoa_ttl;
public boolean Exists_n() {return !exists;} import gplx.xowa.Xow_wiki;
public int Id() {return id;} private int id; import gplx.xowa.wikis.nss.Xow_ns;
public int Ns_id() {return ns_id;} private int ns_id;
public byte[] Ttl_bry() {return ttl_bry;} private byte[] ttl_bry; public class Xopg_db_page {
public DateAdp Modified_on() {return modified_on;} private DateAdp modified_on; public Xopg_db_page() {this.Clear();}
public int Text_len() {return text_len;} private int text_len; // from page table
public int Text_db_id() {return text_db_id;} private int text_db_id; public boolean Exists() {return exists;} private boolean exists;
public int Html_db_id() {return html_db_id;} private int html_db_id; public boolean Exists_n() {return !exists;}
public int Redirect_to_id() {return redirect_to_id;} private int redirect_to_id; public int Id() {return id;} private int id;
public int Score() {return score;} private int score; public int Ns_id() {return ns_id;} private int ns_id;
public byte[] Ttl_bry() {return ttl_bry;} private byte[] ttl_bry;
public void Exists_y_() {this.Exists_(Bool_.Y);} public DateAdp Modified_on() {return modified_on;} private DateAdp modified_on;
public void Exists_n_() {this.Exists_(Bool_.N);} public int Text_len() {return text_len;} private int text_len;
public void Exists_(boolean v) {this.exists = v;} public int Text_db_id() {return text_db_id;} private int text_db_id;
public Xopg_db_page Id_(int v) {this.id = v; return this;} public int Html_db_id() {return html_db_id;} private int html_db_id;
public Xopg_db_page Score_(int v) {this.score = v; return this;} public int Redirect_to_id() {return redirect_to_id;} private int redirect_to_id;
public Xopg_db_page Modified_on_(DateAdp v) {this.modified_on = v; return this;} public int Score() {return score;} private int score;
public Xopg_db_page Html_db_id_(int v) {this.html_db_id = v; return this;}
public void Exists_y_() {this.Exists_(Bool_.Y);}
// wiki-related public void Exists_n_() {this.Exists_(Bool_.N);}
public Xow_ns Ns() {return ns;} private Xow_ns ns; public void Exists_(boolean v) {this.exists = v;}
public Xoa_ttl Ttl() {return ttl;} private Xoa_ttl ttl; public Xopg_db_page Id_(int v) {this.id = v; return this;}
public Xopg_db_page Score_(int v) {this.score = v; return this;}
// init methods public Xopg_db_page Modified_on_(DateAdp v) {this.modified_on = v; return this;}
public Xopg_db_page Init_by_db(int id, int ns_id, byte[] ttl_bry, DateAdp modified_on, int text_len, int text_db_id, int html_db_id, int redirect_to_id, int score) { public Xopg_db_page Html_db_id_(int v) {this.html_db_id = v; return this;}
this.id = id; this.ns_id = ns_id; this.ttl_bry = ttl_bry; this.modified_on = modified_on;
this.text_len = text_len; this.text_db_id = text_db_id; this.html_db_id = html_db_id; this.redirect_to_id = redirect_to_id; this.score = score; // wiki-related
this.ns = null; this.ttl = null; public Xow_ns Ns() {return ns;} private Xow_ns ns;
return this; public Xoa_ttl Ttl() {return ttl;} private Xoa_ttl ttl;
}
public Xopg_db_page Init_by_wiki(Xow_wiki wiki) { // init methods
this.ns = wiki.Ns_mgr().Ids_get_or_null(ns_id); public Xopg_db_page Init_by_db(int id, int ns_id, byte[] ttl_bry, DateAdp modified_on, int text_len, int text_db_id, int html_db_id, int redirect_to_id, int score) {
this.ttl = wiki.Ttl_parse(ns_id, ttl_bry); this.id = id; this.ns_id = ns_id; this.ttl_bry = ttl_bry; this.modified_on = modified_on;
return this; this.text_len = text_len; this.text_db_id = text_db_id; this.html_db_id = html_db_id; this.redirect_to_id = redirect_to_id; this.score = score;
} this.ns = null; this.ttl = null;
public void Init_by_mp(int id, int score) { return this;
this.id = id; }
this.score = score; public Xopg_db_page Init_by_wiki(Xow_wiki wiki) {
} this.ns = wiki.Ns_mgr().Ids_get_or_null(ns_id);
public void Clear() { this.ttl = wiki.Ttl_parse(ns_id, ttl_bry);
this.exists = true; return this;
this.modified_on = DateAdp_.MinValue; // NOTE: must set to MinValue else some tests will fail }
this.html_db_id = -1; // NOTE: must set to -1 b/c code checks for -1 to indicate no html; DATE:2016-07-14 public void Init_by_mp(int id, int score) {
} this.id = id;
} this.score = score;
}
public void Clear() {
this.exists = true;
this.modified_on = DateAdp_.MinValue; // NOTE: must set to MinValue else some tests will fail
// NOTE: must set to -1 b/c code checks for -1 to indicate no html; DATE:2016-07-14;
// NOTE: this should probably be removed, but would need to change all the checks; DATE:2020-08-06
this.html_db_id = Xopg_db_page.HTML_DB_ID_NULL;
}
public static final int HTML_DB_ID_NULL = -1;
}