mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Edit: Save compiled HTML when editing pages [#699]
This commit is contained in:
parent
dc374fa7fc
commit
0aced904a5
@ -1,309 +1,310 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
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.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
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
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.guis.views;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_find_;
|
||||
import gplx.Err_;
|
||||
import gplx.GfoMsg;
|
||||
import gplx.Gfo_evt_mgr_;
|
||||
import gplx.Gfo_invk;
|
||||
import gplx.Gfo_invk_;
|
||||
import gplx.Gfo_usr_dlg;
|
||||
import gplx.GfsCtx;
|
||||
import gplx.Int_;
|
||||
import gplx.List_adp;
|
||||
import gplx.String_;
|
||||
import gplx.core.envs.Env_;
|
||||
import gplx.core.threads.Gfo_thread_wkr;
|
||||
import gplx.gfui.controls.elems.GfuiElem;
|
||||
import gplx.gfui.controls.elems.GfuiElemKeys;
|
||||
import gplx.gfui.controls.standards.Gfui_html;
|
||||
import gplx.gfui.controls.standards.Gfui_tab_itm;
|
||||
import gplx.gfui.controls.standards.Gfui_tab_itm_data;
|
||||
import gplx.gfui.ipts.IptBnd_;
|
||||
import gplx.gfui.ipts.IptCfg_;
|
||||
import gplx.gfui.ipts.IptEventType_;
|
||||
import gplx.gfui.ipts.IptKey_;
|
||||
import gplx.gfui.ipts.IptMouseBtn_;
|
||||
import gplx.gfui.kits.core.Gfui_kit;
|
||||
import gplx.xowa.Xoa_app;
|
||||
import gplx.xowa.Xoa_page;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xoa_url;
|
||||
import gplx.xowa.Xoa_url_;
|
||||
import gplx.xowa.Xoae_app;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.files.Xof_file_wkr;
|
||||
import gplx.xowa.files.Xog_redlink_thread;
|
||||
import gplx.xowa.guis.Xoa_gui_mgr;
|
||||
import gplx.xowa.guis.bnds.Xog_bnd_box_;
|
||||
import gplx.xowa.guis.history.Xog_history_mgr;
|
||||
import gplx.xowa.wikis.pages.Xopg_view_mode_;
|
||||
|
||||
public class Xog_tab_itm implements Gfo_invk {
|
||||
private Xog_win_itm win;
|
||||
public Xog_tab_itm(Xog_tab_mgr tab_mgr, Gfui_tab_itm_data tab_data, Xowe_wiki wiki, Xoae_page page) {
|
||||
this.tab_mgr = tab_mgr; this.tab_data = tab_data; this.wiki = wiki; this.page = page;
|
||||
this.win = tab_mgr.Win();
|
||||
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 void Make_html_box(int uid, Gfui_tab_itm tab_box, Xog_win_itm win, GfuiElem owner) {
|
||||
this.tab_box = tab_box;
|
||||
Xoae_app app = win.App(); Xoa_gui_mgr gui_mgr = win.Gui_mgr(); Gfui_kit kit = win.Kit();
|
||||
Gfui_html html_box = kit.New_html("html_box" + Int_.To_str(uid), owner);
|
||||
html_box.Html_js_enabled_(tab_mgr.Javascript_enabled());
|
||||
html_box.Html_invk_src_(win);
|
||||
html_itm.Html_box_(html_box);
|
||||
if (app.Mode().Tid_is_gui()) { // NOTE: only run for gui; will cause firefox_addon to fail; DATE:2014-05-03
|
||||
// NOTE: must set source, else control will be empty, and key events will not be raised; DATE:2014-04-30
|
||||
// NOTE: use load_by_url for nightmode else load_by_mem causes "white flashing" DATE:2017-03-04
|
||||
if (app.Gui_mgr().Nightmode_mgr().Enabled()) {
|
||||
html_box.Html_doc_html_load_by_url
|
||||
( 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("");
|
||||
}
|
||||
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
|
||||
Gfo_evt_mgr_.Sub_same(html_box, GfuiElemKeys.Evt_menu_detected, html_itm);
|
||||
gui_mgr.Bnd_mgr().Bind(Xog_bnd_box_.Tid_browser_html, html_box);
|
||||
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
|
||||
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;
|
||||
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;
|
||||
this.page = comp.page;
|
||||
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;
|
||||
this.wiki = comp.wiki;
|
||||
comp.wiki = temp_wiki;
|
||||
|
||||
// switch .view_mode to match .page
|
||||
byte temp_view_mode = 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;
|
||||
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 int Tab_idx() {return tab_data.Idx();} public void Tab_idx_(int v) {tab_data.Idx_(v);}
|
||||
public Xog_tab_mgr Tab_mgr() {return tab_mgr;} private Xog_tab_mgr tab_mgr;
|
||||
public Gfui_tab_itm Tab_box() {return tab_box;} private Gfui_tab_itm tab_box;
|
||||
public boolean Tab_is_loading() {return tab_is_loading;} private boolean tab_is_loading;
|
||||
public Xog_html_itm Html_itm() {return html_itm;} private Xog_html_itm html_itm;
|
||||
public Gfui_html Html_box() {return html_itm.Html_box();}
|
||||
public Xoae_page Page() {return page;}
|
||||
public void Page_ref_(Xoae_page v) {
|
||||
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);
|
||||
this.Page_update_ui(); // force tab button to update when page changes
|
||||
} private Xoae_page page;
|
||||
public void Page_update_ui() {
|
||||
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
|
||||
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());
|
||||
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 void View_mode_(byte v) {
|
||||
view_mode = 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) {
|
||||
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
|
||||
if (url.Page_is_main()) url.Page_bry_(wiki.Props().Main_page()); // NOTE: must go before ttl.Make; DATE:2016-07-31
|
||||
Xoa_ttl ttl = wiki.Ttl_parse(url.Page_bry());
|
||||
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
|
||||
&& url.Eq_page(page.Url()) // url has same page_name as existing page
|
||||
&& 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;
|
||||
}
|
||||
if (win.Page__async__working(url)) return;
|
||||
if (page != null) page.Tab_data().Close_mgr().When_close(this, url); // cancel any current search cmds
|
||||
app.Log_wtr().Queue_enabled_(true);
|
||||
usr_dlg.Gui_wkr().Clear();
|
||||
if (url.Vnt_bry() != null) {
|
||||
byte[] vnt = url.Vnt_bry();
|
||||
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()));
|
||||
|
||||
// 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())
|
||||
// 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();
|
||||
}
|
||||
private void Show_url_loaded(Load_page_wkr wkr) {
|
||||
Xowe_wiki wiki = wkr.Wiki(); Xoae_page page = wkr.Page();
|
||||
Xoa_url url = page.Url(); Xoa_ttl ttl = page.Ttl();
|
||||
Xoae_app app = wiki.Appe(); Gfo_usr_dlg usr_dlg = app.Usr_dlg();
|
||||
try {
|
||||
if (page.Tab_data().Cancel_show()) return; // Special:Search canceled show; NOTE: must be inside try b/c finally handles thread
|
||||
wiki.Parser_mgr().Ctx().Page_(page);
|
||||
if ( page.Db().Page().Exists_n()
|
||||
&& !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 (wiki.Db_mgr().Save_mgr().Create_enabled()
|
||||
|| wiki.Page_mgr().Sync_mgr().Auto_enabled()) {
|
||||
page = Xoae_page.New_edit(wiki, ttl);
|
||||
page.Url_(url); // NOTE: need to set url else query args like action=edit will be lost; DATE:2019-03-20
|
||||
view_mode = Xopg_view_mode_.Tid__edit;
|
||||
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
|
||||
if (page.Redirect_trail().Itms__len() > 0)
|
||||
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());
|
||||
else {
|
||||
if (ttl.Ns().Id_is_file())
|
||||
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
|
||||
else
|
||||
usr_dlg.Prog_one("", "", "could not find page in wiki: ~{0}", String_.new_u8(url.Raw()));
|
||||
}
|
||||
}
|
||||
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
|
||||
history_mgr.Add(page);
|
||||
Xog_tab_itm_read_mgr.Show_page(this, page, true);
|
||||
if (app.Usere().History_mgr().Enabled()) {
|
||||
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
|
||||
// win.Page__async__bgn(this);
|
||||
Gfo_thread_wkr async_wkr = null;
|
||||
if (page.Html_data().Hdump_exists()) {
|
||||
// wiki.File_mgr().Init_file_mgr_by_load(wiki);
|
||||
// Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr();
|
||||
// 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());
|
||||
async_wkr = new Load_files_wkr(this);
|
||||
if (wiki.Html__hdump_enabled() && page.Db().Page().Html_db_id() == -1) {
|
||||
wiki.Html__hdump_mgr().Save_mgr().Save(page);
|
||||
}
|
||||
}
|
||||
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();
|
||||
// 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();
|
||||
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) {
|
||||
Xof_file_wkr file_thread = new Xof_file_wkr
|
||||
( 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();
|
||||
}
|
||||
if (redlink_ary.length > 0) {
|
||||
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") + "\"}");
|
||||
}
|
||||
@gplx.Internal protected void Show_url_failed(Load_page_wkr wkr) {
|
||||
try {
|
||||
Xog_tab_itm_read_mgr.Show_page_err(win, this, wkr.Wiki(), wkr.Url(), wkr.Ttl(), wkr.Exec_err());
|
||||
} 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"));
|
||||
else if (ctx.Match(k, Invk_show_url_failed_swt)) this.Show_url_failed((Load_page_wkr)m.ReadObj("v"));
|
||||
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";
|
||||
}
|
||||
class Load_files_wkr implements Gfo_thread_wkr {
|
||||
private Xog_tab_itm tab;
|
||||
public Load_files_wkr(Xog_tab_itm tab) {this.tab = tab;}
|
||||
public String Thread__name() {return "xowa.load_files_wkr";}
|
||||
public boolean Thread__resume() {return true;}
|
||||
public void Thread__exec() {
|
||||
try {Xog_async_wkr.Async(tab);}
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
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.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
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
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.guis.views;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_find_;
|
||||
import gplx.Err_;
|
||||
import gplx.GfoMsg;
|
||||
import gplx.Gfo_evt_mgr_;
|
||||
import gplx.Gfo_invk;
|
||||
import gplx.Gfo_invk_;
|
||||
import gplx.Gfo_usr_dlg;
|
||||
import gplx.GfsCtx;
|
||||
import gplx.Int_;
|
||||
import gplx.List_adp;
|
||||
import gplx.String_;
|
||||
import gplx.core.envs.Env_;
|
||||
import gplx.core.threads.Gfo_thread_wkr;
|
||||
import gplx.gfui.controls.elems.GfuiElem;
|
||||
import gplx.gfui.controls.elems.GfuiElemKeys;
|
||||
import gplx.gfui.controls.standards.Gfui_html;
|
||||
import gplx.gfui.controls.standards.Gfui_tab_itm;
|
||||
import gplx.gfui.controls.standards.Gfui_tab_itm_data;
|
||||
import gplx.gfui.ipts.IptBnd_;
|
||||
import gplx.gfui.ipts.IptCfg_;
|
||||
import gplx.gfui.ipts.IptEventType_;
|
||||
import gplx.gfui.ipts.IptKey_;
|
||||
import gplx.gfui.ipts.IptMouseBtn_;
|
||||
import gplx.gfui.kits.core.Gfui_kit;
|
||||
import gplx.xowa.Xoa_app;
|
||||
import gplx.xowa.Xoa_page;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xoa_url;
|
||||
import gplx.xowa.Xoa_url_;
|
||||
import gplx.xowa.Xoae_app;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.files.Xof_file_wkr;
|
||||
import gplx.xowa.files.Xog_redlink_thread;
|
||||
import gplx.xowa.guis.Xoa_gui_mgr;
|
||||
import gplx.xowa.guis.bnds.Xog_bnd_box_;
|
||||
import gplx.xowa.guis.history.Xog_history_mgr;
|
||||
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 Xog_tab_itm(Xog_tab_mgr tab_mgr, Gfui_tab_itm_data tab_data, Xowe_wiki wiki, Xoae_page page) {
|
||||
this.tab_mgr = tab_mgr; this.tab_data = tab_data; this.wiki = wiki; this.page = page;
|
||||
this.win = tab_mgr.Win();
|
||||
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 void Make_html_box(int uid, Gfui_tab_itm tab_box, Xog_win_itm win, GfuiElem owner) {
|
||||
this.tab_box = tab_box;
|
||||
Xoae_app app = win.App(); Xoa_gui_mgr gui_mgr = win.Gui_mgr(); Gfui_kit kit = win.Kit();
|
||||
Gfui_html html_box = kit.New_html("html_box" + Int_.To_str(uid), owner);
|
||||
html_box.Html_js_enabled_(tab_mgr.Javascript_enabled());
|
||||
html_box.Html_invk_src_(win);
|
||||
html_itm.Html_box_(html_box);
|
||||
if (app.Mode().Tid_is_gui()) { // NOTE: only run for gui; will cause firefox_addon to fail; DATE:2014-05-03
|
||||
// NOTE: must set source, else control will be empty, and key events will not be raised; DATE:2014-04-30
|
||||
// NOTE: use load_by_url for nightmode else load_by_mem causes "white flashing" DATE:2017-03-04
|
||||
if (app.Gui_mgr().Nightmode_mgr().Enabled()) {
|
||||
html_box.Html_doc_html_load_by_url
|
||||
( 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("");
|
||||
}
|
||||
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
|
||||
Gfo_evt_mgr_.Sub_same(html_box, GfuiElemKeys.Evt_menu_detected, html_itm);
|
||||
gui_mgr.Bnd_mgr().Bind(Xog_bnd_box_.Tid_browser_html, html_box);
|
||||
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
|
||||
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;
|
||||
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;
|
||||
this.page = comp.page;
|
||||
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;
|
||||
this.wiki = comp.wiki;
|
||||
comp.wiki = temp_wiki;
|
||||
|
||||
// switch .view_mode to match .page
|
||||
byte temp_view_mode = 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;
|
||||
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 int Tab_idx() {return tab_data.Idx();} public void Tab_idx_(int v) {tab_data.Idx_(v);}
|
||||
public Xog_tab_mgr Tab_mgr() {return tab_mgr;} private Xog_tab_mgr tab_mgr;
|
||||
public Gfui_tab_itm Tab_box() {return tab_box;} private Gfui_tab_itm tab_box;
|
||||
public boolean Tab_is_loading() {return tab_is_loading;} private boolean tab_is_loading;
|
||||
public Xog_html_itm Html_itm() {return html_itm;} private Xog_html_itm html_itm;
|
||||
public Gfui_html Html_box() {return html_itm.Html_box();}
|
||||
public Xoae_page Page() {return page;}
|
||||
public void Page_ref_(Xoae_page v) {
|
||||
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);
|
||||
this.Page_update_ui(); // force tab button to update when page changes
|
||||
} private Xoae_page page;
|
||||
public void Page_update_ui() {
|
||||
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
|
||||
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());
|
||||
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 void View_mode_(byte v) {
|
||||
view_mode = 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) {
|
||||
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
|
||||
if (url.Page_is_main()) url.Page_bry_(wiki.Props().Main_page()); // NOTE: must go before ttl.Make; DATE:2016-07-31
|
||||
Xoa_ttl ttl = wiki.Ttl_parse(url.Page_bry());
|
||||
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
|
||||
&& url.Eq_page(page.Url()) // url has same page_name as existing page
|
||||
&& 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;
|
||||
}
|
||||
if (win.Page__async__working(url)) return;
|
||||
if (page != null) page.Tab_data().Close_mgr().When_close(this, url); // cancel any current search cmds
|
||||
app.Log_wtr().Queue_enabled_(true);
|
||||
usr_dlg.Gui_wkr().Clear();
|
||||
if (url.Vnt_bry() != null) {
|
||||
byte[] vnt = url.Vnt_bry();
|
||||
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()));
|
||||
|
||||
// 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())
|
||||
// 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();
|
||||
}
|
||||
private void Show_url_loaded(Load_page_wkr wkr) {
|
||||
Xowe_wiki wiki = wkr.Wiki(); Xoae_page page = wkr.Page();
|
||||
Xoa_url url = page.Url(); Xoa_ttl ttl = page.Ttl();
|
||||
Xoae_app app = wiki.Appe(); Gfo_usr_dlg usr_dlg = app.Usr_dlg();
|
||||
try {
|
||||
if (page.Tab_data().Cancel_show()) return; // Special:Search canceled show; NOTE: must be inside try b/c finally handles thread
|
||||
wiki.Parser_mgr().Ctx().Page_(page);
|
||||
if ( page.Db().Page().Exists_n()
|
||||
&& !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 (wiki.Db_mgr().Save_mgr().Create_enabled()
|
||||
|| wiki.Page_mgr().Sync_mgr().Auto_enabled()) {
|
||||
page = Xoae_page.New_edit(wiki, ttl);
|
||||
page.Url_(url); // NOTE: need to set url else query args like action=edit will be lost; DATE:2019-03-20
|
||||
view_mode = Xopg_view_mode_.Tid__edit;
|
||||
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
|
||||
if (page.Redirect_trail().Itms__len() > 0)
|
||||
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());
|
||||
else {
|
||||
if (ttl.Ns().Id_is_file())
|
||||
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
|
||||
else
|
||||
usr_dlg.Prog_one("", "", "could not find page in wiki: ~{0}", String_.new_u8(url.Raw()));
|
||||
}
|
||||
}
|
||||
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
|
||||
history_mgr.Add(page);
|
||||
Xog_tab_itm_read_mgr.Show_page(this, page, true);
|
||||
if (app.Usere().History_mgr().Enabled()) {
|
||||
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
|
||||
// win.Page__async__bgn(this);
|
||||
Gfo_thread_wkr async_wkr = null;
|
||||
if (page.Html_data().Hdump_exists()) {
|
||||
// wiki.File_mgr().Init_file_mgr_by_load(wiki);
|
||||
// Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr();
|
||||
// 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());
|
||||
async_wkr = new Load_files_wkr(this);
|
||||
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);
|
||||
|
||||
page.Html_data().Mode_wtxt_shown_y_();
|
||||
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();
|
||||
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) {
|
||||
Xof_file_wkr file_thread = new Xof_file_wkr
|
||||
( 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();
|
||||
}
|
||||
if (redlink_ary.length > 0) {
|
||||
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") + "\"}");
|
||||
}
|
||||
@gplx.Internal protected void Show_url_failed(Load_page_wkr wkr) {
|
||||
try {
|
||||
Xog_tab_itm_read_mgr.Show_page_err(win, this, wkr.Wiki(), wkr.Url(), wkr.Ttl(), wkr.Exec_err());
|
||||
} 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"));
|
||||
else if (ctx.Match(k, Invk_show_url_failed_swt)) this.Show_url_failed((Load_page_wkr)m.ReadObj("v"));
|
||||
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";
|
||||
}
|
||||
class Load_files_wkr implements Gfo_thread_wkr {
|
||||
private Xog_tab_itm tab;
|
||||
public Load_files_wkr(Xog_tab_itm tab) {this.tab = tab;}
|
||||
public String Thread__name() {return "xowa.load_files_wkr";}
|
||||
public boolean Thread__resume() {return true;}
|
||||
public void Thread__exec() {
|
||||
try {Xog_async_wkr.Async(tab);}
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
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.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
|
||||
public class Xog_tab_itm_edit_mgr {
|
||||
public static void Save(Xog_tab_itm tab, boolean quick_save) {
|
||||
if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles ctrl+s being pressed in read/html modes
|
||||
|
||||
// get text and save directly to text_db
|
||||
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
|
||||
byte[] new_text = Get_new_text(tab, page.Db().Text().Text_bry());
|
||||
int page_id = page.Db().Page().Id();
|
||||
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);
|
||||
page.Edit_mode_update_(); // set to update so that next save does not try to create
|
||||
}
|
||||
else {
|
||||
wiki.Db_mgr().Save_mgr().Data_update(page, new_text);
|
||||
}
|
||||
Invalidate(wiki);
|
||||
page.Db().Text().Text_bry_(new_text);
|
||||
|
||||
// refresh html
|
||||
wiki.Parser_mgr().Parse(page, true);
|
||||
if (wiki.Html__hdump_enabled()) wiki.Html__hdump_mgr().Save_mgr().Save(page); // must go after wiki.Parse
|
||||
|
||||
// NOTE: show message after Parse, b/c Parse will flash "Loading page"; DATE:2014-05-17
|
||||
win_itm.Usr_dlg().Prog_many("", "", "saved ~{0} (~{1})"
|
||||
, String_.new_u8(page.Ttl().Full_txt_raw())
|
||||
, Datetime_now.Get().XtoStr_fmt("HH:mm:ss.fff")
|
||||
);
|
||||
|
||||
// full_save; save page and go to read mode
|
||||
if (!quick_save) {
|
||||
gplx.xowa.addons.wikis.pagebaks.Pagebaks_addon.On_page_saved(wiki.Appe(), wiki, page.Ttl(), new_text);
|
||||
|
||||
// update categories
|
||||
try {
|
||||
wiki.Html_mgr().Page_wtr_mgr().Gen(page, Xopg_view_mode_.Tid__read); // NOTE: need to write html to fill Wtxt().Ctgs
|
||||
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));
|
||||
}
|
||||
|
||||
// TODO: save html copy
|
||||
//wiki.Db_mgr().Hdump_mgr().Save(page);
|
||||
|
||||
// parse page and show it
|
||||
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
|
||||
stack_page.Wikie().Parser_mgr().Parse(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
|
||||
page.Url_(Xoa_url.New(tab.Wiki().Domain_bry(), tab.Page().Ttl().Full_db()));
|
||||
|
||||
// force full reload of page; needed to refresh page_modified; DATE:2017-03-06
|
||||
tab.Show_url_bgn(page.Url());
|
||||
// win_itm.Page__mode_(Xopg_view_mode_.Tid__read);
|
||||
// win_itm.Page__async__bgn(tab);
|
||||
}
|
||||
}
|
||||
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();
|
||||
Xog_html_itm html_itm = tab.Html_itm();
|
||||
|
||||
byte[] new_text = Get_new_text(tab, null);
|
||||
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
|
||||
new_page.Db().Page().Id_(page.Db().Page().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat)
|
||||
new_page.Db().Text().Text_bry_(new_text);
|
||||
wiki.Parser_mgr().Parse(new_page, true); // refresh html
|
||||
tab.Page_(new_page); new_page.Tab_data().Tab_(tab); // replace old page with new_page; DATE:2014-10-09
|
||||
|
||||
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
|
||||
Xoh_page_wtr_wkr wkr = wiki.Html_mgr().Page_wtr_mgr().Wkr(Xopg_view_mode_.Tid__read);
|
||||
wkr.Write_body(tmp_bfr, wiki.Parser_mgr().Ctx(), Xoh_wtr_ctx.Basic, new_page);
|
||||
byte[] new_html = tmp_bfr.To_bry_and_rls();
|
||||
new_page.Html_data().Edit_preview_(new_html);
|
||||
|
||||
Invalidate(wiki);
|
||||
win_itm.Page__mode_(Xopg_view_mode_.Tid__edit);
|
||||
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 Rename(Xog_tab_itm tab) {
|
||||
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();
|
||||
if (Bry_.Eq(page.Ttl().Page_db(), wiki.Props().Main_page())) {
|
||||
win_itm.Usr_dlg().Warn_many("", "", "The Main Page cannot be renamed");
|
||||
win_itm.Kit().Ask_ok("", "", "The Main Page cannot be renamed");
|
||||
return;
|
||||
}
|
||||
byte[] new_text = Bry_.new_u8(tab.Html_itm().Get_elem_value(Xog_html_itm.Elem_id__xowa_edit_rename_box));
|
||||
if (Bry_.Len_eq_0(new_text)) return; // no ttl given; exit
|
||||
new_text = Xoa_ttl.Replace_spaces(new_text); // ttls cannot have spaces; only underscores
|
||||
Xoa_ttl new_ttl = Xoa_ttl.Parse(wiki, new_text);
|
||||
int new_ns_id = new_ttl.Ns().Id();
|
||||
if (new_ns_id != Xow_ns_.Tid__main) {
|
||||
win_itm.Usr_dlg().Warn_many("", "", "The new page name must remain in the same namespace");
|
||||
return;
|
||||
}
|
||||
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)));
|
||||
win_itm.Page__mode_(Xopg_view_mode_.Tid__read);
|
||||
win_itm.Usr_dlg().Prog_one("", "", "renamed page to {0}", String_.new_u8(page.Ttl().Full_txt_raw()));
|
||||
}
|
||||
public static void Focus(Xog_win_itm win, String elem_focus_id) {
|
||||
Gfui_html html_box = win.Active_html_box();
|
||||
html_box.Focus();
|
||||
html_box.Html_js_eval_proc_as_str(Xog_js_procs.Doc__elem_focus, elem_focus_id);
|
||||
}
|
||||
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();
|
||||
Xowe_wiki wiki = tab.Wiki(); Xop_ctx ctx = wiki.Parser_mgr().Ctx();
|
||||
ctx.Defn_trace().Clear(); // TODO_OLD: move_me
|
||||
ctx.Defn_trace_(Xot_defn_trace_dbg.Instance);
|
||||
Xoa_ttl ttl = page.Ttl();
|
||||
Xoae_page new_page = Xoae_page.New(wiki, 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-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;
|
||||
}
|
||||
}
|
||||
package gplx.xowa.guis.views;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Datetime_now;
|
||||
import gplx.Err_;
|
||||
import gplx.Gfo_usr_dlg_;
|
||||
import gplx.String_;
|
||||
import gplx.gfui.controls.standards.Gfui_html;
|
||||
import gplx.xowa.Xoa_page_;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xoa_url;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.htmls.Xoh_page_wtr_wkr;
|
||||
import gplx.xowa.htmls.core.htmls.Xoh_wtr_ctx;
|
||||
import gplx.xowa.parsers.Xop_ctx;
|
||||
import gplx.xowa.parsers.tmpls.Xot_defn_trace_dbg;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
|
||||
import gplx.xowa.wikis.nss.Xow_ns_;
|
||||
import gplx.xowa.wikis.pages.Xopg_view_mode_;
|
||||
|
||||
public class Xog_tab_itm_edit_mgr {
|
||||
public static void Save(Xog_tab_itm tab, boolean quick_save) {
|
||||
if (tab.View_mode() != Xopg_view_mode_.Tid__edit) return; // exit if not edit; handles ctrl+s being pressed in read/html modes
|
||||
|
||||
// get text and save directly to text_db
|
||||
Xoae_page page = tab.Page(); Xowe_wiki wiki = tab.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
|
||||
byte[] new_text = Get_new_text(tab, page.Db().Text().Text_bry());
|
||||
int page_id = page.Db().Page().Id();
|
||||
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);
|
||||
page.Edit_mode_update_(); // set to update so that next save does not try to create
|
||||
}
|
||||
else {
|
||||
wiki.Db_mgr().Save_mgr().Data_update(page, new_text);
|
||||
}
|
||||
Invalidate(wiki);
|
||||
page.Db().Text().Text_bry_(new_text);
|
||||
|
||||
// refresh html
|
||||
wiki.Parser_mgr().Parse(page, true);
|
||||
if (wiki.Html__hdump_enabled()) wiki.Html__hdump_mgr().Save_mgr().Save(page); // must go after wiki.Parse
|
||||
|
||||
// NOTE: show message after Parse, b/c Parse will flash "Loading page"; DATE:2014-05-17
|
||||
win_itm.Usr_dlg().Prog_many("", "", "saved ~{0} (~{1})"
|
||||
, String_.new_u8(page.Ttl().Full_txt_raw())
|
||||
, Datetime_now.Get().XtoStr_fmt("HH:mm:ss.fff")
|
||||
);
|
||||
|
||||
// full_save; save page and go to read mode
|
||||
if (!quick_save) {
|
||||
gplx.xowa.addons.wikis.pagebaks.Pagebaks_addon.On_page_saved(wiki.Appe(), wiki, page.Ttl(), new_text);
|
||||
|
||||
// update categories
|
||||
try {
|
||||
wiki.Html_mgr().Page_wtr_mgr().Gen(page, Xopg_view_mode_.Tid__read); // NOTE: need to write html to fill Wtxt().Ctgs
|
||||
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));
|
||||
}
|
||||
|
||||
// reload html_db_id b/c it gets cleared in Xopg_db_page; ISSUE#:699; DATE:2020-08-06
|
||||
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());
|
||||
page.Db().Page().Html_db_id_(rv.Html_db_id());
|
||||
|
||||
// save html
|
||||
wiki.Html__hdump_mgr().Save_mgr().Save(page, true);
|
||||
|
||||
// parse page and show it
|
||||
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
|
||||
stack_page.Wikie().Parser_mgr().Parse(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
|
||||
page.Url_(Xoa_url.New(tab.Wiki().Domain_bry(), tab.Page().Ttl().Full_db()));
|
||||
|
||||
// force full reload of page; needed to refresh page_modified; DATE:2017-03-06
|
||||
tab.Show_url_bgn(page.Url());
|
||||
// win_itm.Page__mode_(Xopg_view_mode_.Tid__read);
|
||||
// win_itm.Page__async__bgn(tab);
|
||||
}
|
||||
}
|
||||
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();
|
||||
Xog_html_itm html_itm = tab.Html_itm();
|
||||
|
||||
byte[] new_text = Get_new_text(tab, null);
|
||||
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
|
||||
new_page.Db().Page().Id_(page.Db().Page().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat)
|
||||
new_page.Db().Text().Text_bry_(new_text);
|
||||
wiki.Parser_mgr().Parse(new_page, true); // refresh html
|
||||
tab.Page_(new_page); new_page.Tab_data().Tab_(tab); // replace old page with new_page; DATE:2014-10-09
|
||||
|
||||
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
|
||||
Xoh_page_wtr_wkr wkr = wiki.Html_mgr().Page_wtr_mgr().Wkr(Xopg_view_mode_.Tid__read);
|
||||
wkr.Write_body(tmp_bfr, wiki.Parser_mgr().Ctx(), Xoh_wtr_ctx.Basic, new_page);
|
||||
byte[] new_html = tmp_bfr.To_bry_and_rls();
|
||||
new_page.Html_data().Edit_preview_(new_html);
|
||||
|
||||
Invalidate(wiki);
|
||||
win_itm.Page__mode_(Xopg_view_mode_.Tid__edit);
|
||||
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 Rename(Xog_tab_itm tab) {
|
||||
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();
|
||||
if (Bry_.Eq(page.Ttl().Page_db(), wiki.Props().Main_page())) {
|
||||
win_itm.Usr_dlg().Warn_many("", "", "The Main Page cannot be renamed");
|
||||
win_itm.Kit().Ask_ok("", "", "The Main Page cannot be renamed");
|
||||
return;
|
||||
}
|
||||
byte[] new_text = Bry_.new_u8(tab.Html_itm().Get_elem_value(Xog_html_itm.Elem_id__xowa_edit_rename_box));
|
||||
if (Bry_.Len_eq_0(new_text)) return; // no ttl given; exit
|
||||
new_text = Xoa_ttl.Replace_spaces(new_text); // ttls cannot have spaces; only underscores
|
||||
Xoa_ttl new_ttl = Xoa_ttl.Parse(wiki, new_text);
|
||||
int new_ns_id = new_ttl.Ns().Id();
|
||||
if (new_ns_id != Xow_ns_.Tid__main) {
|
||||
win_itm.Usr_dlg().Warn_many("", "", "The new page name must remain in the same namespace");
|
||||
return;
|
||||
}
|
||||
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)));
|
||||
win_itm.Page__mode_(Xopg_view_mode_.Tid__read);
|
||||
win_itm.Usr_dlg().Prog_one("", "", "renamed page to {0}", String_.new_u8(page.Ttl().Full_txt_raw()));
|
||||
}
|
||||
public static void Focus(Xog_win_itm win, String elem_focus_id) {
|
||||
Gfui_html html_box = win.Active_html_box();
|
||||
html_box.Focus();
|
||||
html_box.Html_js_eval_proc_as_str(Xog_js_procs.Doc__elem_focus, elem_focus_id);
|
||||
}
|
||||
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();
|
||||
Xowe_wiki wiki = tab.Wiki(); Xop_ctx ctx = wiki.Parser_mgr().Ctx();
|
||||
ctx.Defn_trace().Clear(); // TODO_OLD: move_me
|
||||
ctx.Defn_trace_(Xot_defn_trace_dbg.Instance);
|
||||
Xoa_ttl ttl = page.Ttl();
|
||||
Xoae_page new_page = Xoae_page.New(wiki, 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-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;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
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.xowa.addons.wikis.pages.syncs.core.parsers.*;
|
||||
public class Xow_hdump_mgr__save {
|
||||
private final Xow_wiki wiki; private final Xoh_hzip_mgr hzip_mgr; private final Io_stream_zip_mgr zip_mgr;
|
||||
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) {
|
||||
this.wiki = wiki; this.hzip_mgr = hzip_mgr; this.zip_mgr = zip_mgr; this.tmp_hpg = tmp_hpg;
|
||||
}
|
||||
public void Init_by_db(int dflt_zip_tid, int dflt_hzip_tid, boolean mode_is_b256) {
|
||||
this.dflt_zip_tid = dflt_zip_tid; this.dflt_hzip_tid = dflt_hzip_tid; tmp_bfr.Mode_is_b256_(mode_is_b256);
|
||||
}
|
||||
public byte[] Src_as_hzip() {return src_as_hzip;} private byte[] src_as_hzip;
|
||||
public int Save(Xoae_page page) {
|
||||
synchronized (tmp_hpg) {
|
||||
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));
|
||||
Xow_db_file html_db = Get_html_db(wiki, page, html_db_is_new.Val_n_());
|
||||
return Save(page, tmp_hpg, html_db.Tbl__html(), html_db_is_new.Val(), true);
|
||||
}
|
||||
}
|
||||
public int Save(Xoae_page page, Xoh_page hpg, Xowd_html_tbl html_tbl, boolean insert, boolean use_hzip_dflt) {
|
||||
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());
|
||||
if (insert) html_tbl.Insert(hpg, dflt_zip_tid, dflt_hzip_tid, db_body);
|
||||
else html_tbl.Update(hpg, dflt_zip_tid, dflt_hzip_tid, db_body);
|
||||
return db_body.length;
|
||||
}
|
||||
public void Bld_hdump(Xoae_page page) {
|
||||
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);
|
||||
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
|
||||
page.Db().Html().Html_bry_(tmp_bfr.To_bry_and_clear());
|
||||
}
|
||||
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:
|
||||
break;
|
||||
case Xoh_hzip_dict_.Hdb__hzip:
|
||||
src = hzip_mgr.Encode_as_bry((Xoh_hzip_bfr)bfr.Clear(), wiki, hpg, src);
|
||||
break;
|
||||
// TOMBSTONE: not used; Xosync_update_mgr calls save directly; unsure if this should be restored for parallelism
|
||||
// case Xoh_hzip_dict_.Hdb__page_sync:
|
||||
// src = plain_parser.Parse_hdoc(wiki.Domain_itm(), page.Url_bry_safe(), hpg.Hdump_mgr().Imgs(), src);
|
||||
// break;
|
||||
}
|
||||
src_as_hzip = src;
|
||||
if (zip_tid > gplx.core.ios.streams.Io_stream_tid_.Tid__raw)
|
||||
src = zip_mgr.Zip((byte)zip_tid, src);
|
||||
return src;
|
||||
}
|
||||
private static Xow_db_file Get_html_db(Xow_wiki wiki, Xoae_page page, Bool_obj_ref html_db_is_new) {
|
||||
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 == -1) {
|
||||
html_db_is_new.Val_y_();
|
||||
rv = core_data_mgr.Db__html();
|
||||
if (rv == null) rv = core_data_mgr.Dbs__make_by_tid(Xow_db_file_.Tid__html_data);
|
||||
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;
|
||||
}
|
||||
}
|
||||
package gplx.xowa.htmls.core;
|
||||
|
||||
import gplx.core.ios.Io_stream_zip_mgr;
|
||||
import gplx.core.primitives.Bool_obj_ref;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.htmls.Xoh_page;
|
||||
import gplx.xowa.htmls.core.dbs.Xowd_html_tbl;
|
||||
import gplx.xowa.htmls.core.htmls.Xoh_wtr_ctx;
|
||||
import gplx.xowa.htmls.core.hzips.Xoh_hzip_dict_;
|
||||
import gplx.xowa.htmls.core.hzips.Xoh_hzip_mgr;
|
||||
import gplx.xowa.htmls.core.wkrs.Xoh_hzip_bfr;
|
||||
import gplx.xowa.wikis.data.Xow_db_file;
|
||||
import gplx.xowa.wikis.data.Xow_db_file_;
|
||||
import gplx.xowa.wikis.data.Xow_db_mgr;
|
||||
import gplx.xowa.wikis.pages.Xopg_view_mode_;
|
||||
import gplx.xowa.wikis.pages.dbs.Xopg_db_page;
|
||||
|
||||
public class Xow_hdump_mgr__save {
|
||||
private final Xow_wiki wiki; private final Xoh_hzip_mgr hzip_mgr; private final Io_stream_zip_mgr zip_mgr;
|
||||
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) {
|
||||
this.wiki = wiki; this.hzip_mgr = hzip_mgr; this.zip_mgr = zip_mgr; this.tmp_hpg = tmp_hpg;
|
||||
}
|
||||
public void Init_by_db(int dflt_zip_tid, int dflt_hzip_tid, boolean mode_is_b256) {
|
||||
this.dflt_zip_tid = dflt_zip_tid; this.dflt_hzip_tid = dflt_hzip_tid; tmp_bfr.Mode_is_b256_(mode_is_b256);
|
||||
}
|
||||
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 int Save(Xoae_page page, boolean isEdit) {
|
||||
synchronized (tmp_hpg) {
|
||||
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));
|
||||
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);
|
||||
}
|
||||
}
|
||||
public int Save(Xoae_page page, Xoh_page hpg, Xowd_html_tbl html_tbl, boolean insert, boolean use_hzip_dflt) {
|
||||
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());
|
||||
if (insert) html_tbl.Insert(hpg, dflt_zip_tid, dflt_hzip_tid, db_body);
|
||||
else html_tbl.Update(hpg, dflt_zip_tid, dflt_hzip_tid, db_body);
|
||||
return db_body.length;
|
||||
}
|
||||
public void Bld_hdump(Xoae_page page) {
|
||||
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);
|
||||
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
|
||||
page.Db().Html().Html_bry_(tmp_bfr.To_bry_and_clear());
|
||||
}
|
||||
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:
|
||||
break;
|
||||
case Xoh_hzip_dict_.Hdb__hzip:
|
||||
src = hzip_mgr.Encode_as_bry((Xoh_hzip_bfr)bfr.Clear(), wiki, hpg, src);
|
||||
break;
|
||||
// TOMBSTONE: not used; Xosync_update_mgr calls save directly; unsure if this should be restored for parallelism
|
||||
// case Xoh_hzip_dict_.Hdb__page_sync:
|
||||
// src = plain_parser.Parse_hdoc(wiki.Domain_itm(), page.Url_bry_safe(), hpg.Hdump_mgr().Imgs(), src);
|
||||
// break;
|
||||
}
|
||||
src_as_hzip = src;
|
||||
if (zip_tid > gplx.core.ios.streams.Io_stream_tid_.Tid__raw)
|
||||
src = zip_mgr.Zip((byte)zip_tid, src);
|
||||
return src;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
import gplx.dbs.*;
|
||||
import gplx.core.ios.*;
|
||||
public class Hxtn_blob_tbl implements Rls_able {
|
||||
private static final String tbl_name = "hxtn_blob"; private static final Dbmeta_fld_list flds = new Dbmeta_fld_list();
|
||||
private static final 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")
|
||||
, 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;
|
||||
private final byte zip_tid_default;
|
||||
private final Io_stream_zip_mgr zip_mgr = new Io_stream_zip_mgr();
|
||||
public Hxtn_blob_tbl(Db_conn conn, byte zip_tid_default) {
|
||||
this.conn = conn;
|
||||
conn.Rls_reg(this);
|
||||
this.zip_tid_default = zip_tid_default;
|
||||
}
|
||||
public String Tbl_name() {return tbl_name;}
|
||||
public Db_conn Conn() {return conn;}
|
||||
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
|
||||
public void Rls() {
|
||||
stmt_insert = Db_stmt_.Rls(stmt_insert);
|
||||
}
|
||||
public void Stmt_bgn() {
|
||||
stmt_insert = conn.Stmt_insert(tbl_name, flds);
|
||||
}
|
||||
public void Stmt_end() {
|
||||
this.Rls();
|
||||
if (!conn.Meta_idx_exists(tbl_name, "pkey"))
|
||||
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 Insert_by_rdr(Db_rdr rdr) {
|
||||
Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert);
|
||||
}
|
||||
public void Insert_exec(int blob_tid, int wiki_id, int blob_id, byte[] blob_data) {
|
||||
blob_data = zip_mgr.Zip(zip_tid_default, blob_data);
|
||||
stmt_insert.Clear()
|
||||
.Val_int(fld_blob_tid , blob_tid)
|
||||
.Val_int(fld_wiki_id , wiki_id)
|
||||
.Val_int(fld_blob_id , blob_id)
|
||||
.Val_byte(fld_zip_tid , zip_tid_default)
|
||||
.Val_bry(fld_blob_data , blob_data)
|
||||
.Exec_insert();
|
||||
}
|
||||
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))
|
||||
.Exec_select__rls_auto();
|
||||
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);
|
||||
}
|
||||
} finally {
|
||||
rdr.Rls();
|
||||
}
|
||||
}
|
||||
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;
|
||||
package gplx.xowa.htmls.hxtns.blobs;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Hash_adp_bry;
|
||||
import gplx.Rls_able;
|
||||
import gplx.String_;
|
||||
import gplx.core.ios.Io_stream_zip_mgr;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_rdr;
|
||||
import gplx.dbs.Db_rdr_;
|
||||
import gplx.dbs.Db_stmt;
|
||||
import gplx.dbs.Db_stmt_;
|
||||
import gplx.dbs.Dbmeta_fld_list;
|
||||
import gplx.dbs.Dbmeta_idx_itm;
|
||||
import gplx.dbs.Dbmeta_tbl_itm;
|
||||
|
||||
public class Hxtn_blob_tbl implements Rls_able {
|
||||
private static final String tbl_name = "hxtn_blob"; private static final Dbmeta_fld_list flds = new Dbmeta_fld_list();
|
||||
private static final 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")
|
||||
, 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;
|
||||
private final byte zip_tid_default;
|
||||
private final Io_stream_zip_mgr zip_mgr = new Io_stream_zip_mgr();
|
||||
public Hxtn_blob_tbl(Db_conn conn, byte zip_tid_default) {
|
||||
this.conn = conn;
|
||||
conn.Rls_reg(this);
|
||||
this.zip_tid_default = zip_tid_default;
|
||||
}
|
||||
public String Tbl_name() {return tbl_name;}
|
||||
public Db_conn Conn() {return conn;}
|
||||
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
|
||||
public void Rls() {
|
||||
stmt_insert = Db_stmt_.Rls(stmt_insert);
|
||||
}
|
||||
public void Stmt_bgn() {
|
||||
stmt_insert = conn.Stmt_insert(tbl_name, flds);
|
||||
}
|
||||
public void Stmt_end() {
|
||||
this.Rls();
|
||||
if (!conn.Meta_idx_exists(tbl_name, "pkey"))
|
||||
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 Insert_by_rdr(Db_rdr rdr) {
|
||||
Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert);
|
||||
}
|
||||
public void Insert_exec(int blob_tid, int wiki_id, int blob_id, byte[] blob_data) {
|
||||
blob_data = zip_mgr.Zip(zip_tid_default, blob_data);
|
||||
stmt_insert.Clear()
|
||||
.Val_int(fld_blob_tid , blob_tid)
|
||||
.Val_int(fld_wiki_id , wiki_id)
|
||||
.Val_int(fld_blob_id , blob_id)
|
||||
.Val_byte(fld_zip_tid , zip_tid_default)
|
||||
.Val_bry(fld_blob_data , blob_data)
|
||||
.Exec_insert();
|
||||
}
|
||||
public boolean Exists(int blob_tid, int wiki_id, int blob_id) {
|
||||
Db_rdr rdr = Db_rdr_.Empty;
|
||||
try {
|
||||
rdr = conn.Stmt_select(tbl_name, flds, fld_blob_tid, fld_wiki_id, fld_blob_id)
|
||||
.Crt_int(fld_blob_tid, blob_tid)
|
||||
.Crt_int(fld_wiki_id, wiki_id)
|
||||
.Crt_int(fld_blob_id, blob_id)
|
||||
.Exec_select__rls_auto();
|
||||
return rdr.Move_next();
|
||||
} finally {
|
||||
rdr.Rls();
|
||||
}
|
||||
}
|
||||
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))
|
||||
.Exec_select__rls_auto();
|
||||
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);
|
||||
}
|
||||
} finally {
|
||||
rdr.Rls();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
@ -1,122 +1,124 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
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.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
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
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.htmls.hxtns.pages;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Gfo_usr_dlg_;
|
||||
import gplx.Hash_adp_bry;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Io_url;
|
||||
import gplx.List_adp;
|
||||
import gplx.core.lists.hashs.Hash_adp__int;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_conn_bldr;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.htmls.Xoh_page;
|
||||
import gplx.xowa.htmls.hxtns.blobs.Hxtn_blob_tbl;
|
||||
import gplx.xowa.htmls.hxtns.wikis.Hxtn_wiki_mgr;
|
||||
import gplx.xowa.htmls.hxtns.wkrs.Hxtn_wkr_mgr;
|
||||
public class Hxtn_page_mgr {
|
||||
private Hxtn_page_tbl page_tbl;
|
||||
private Hxtn_blob_tbl blob_tbl;
|
||||
private Hash_adp_bry blob_hash;
|
||||
private final Hash_adp__int wkrs = new Hash_adp__int();
|
||||
private boolean dbs_missing = true;
|
||||
private Bry_bfr temp_bfr;
|
||||
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
|
||||
this.page_tbl = new Hxtn_page_tbl(wkr_db_conn);
|
||||
this.blob_tbl = new Hxtn_blob_tbl(wkr_db_conn, zip_tid);
|
||||
this.blob_hash = Hash_adp_bry.cs();
|
||||
this.temp_bfr = Bry_bfr_.New();
|
||||
|
||||
// if tbl exists, xomp_resume has run; load known blobs to prevent dupes
|
||||
if (wkr_db_conn.Meta_tbl_exists(page_tbl.Tbl_name())) {
|
||||
blob_tbl.Select_to_regy(temp_bfr, blob_hash);
|
||||
}
|
||||
// else tbl doesn't exist, so create them
|
||||
else {
|
||||
page_tbl.Create_tbl();
|
||||
blob_tbl.Create_tbl();
|
||||
}
|
||||
}
|
||||
public void Init_by_wiki(Xow_wiki wiki, boolean is_merge) {
|
||||
Io_url core_db_url = Make_url(wiki, "-html.hxtn-core.xowa");
|
||||
if (!is_merge && !Io_mgr.Instance.ExistsFil(core_db_url)) return;
|
||||
dbs_missing = false;
|
||||
Db_conn page_conn = Db_conn_bldr.Instance.Get_or_new(core_db_url).Conn();
|
||||
this.page_tbl = new Hxtn_page_tbl(page_conn);
|
||||
|
||||
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);
|
||||
|
||||
if (is_merge) {
|
||||
page_tbl.Create_tbl();
|
||||
blob_tbl.Create_tbl();
|
||||
|
||||
Hxtn_wkr_mgr wkr_mgr = new Hxtn_wkr_mgr();
|
||||
wkr_mgr.Init_by_xomp_merge(page_conn);
|
||||
|
||||
Hxtn_wiki_mgr wiki_mgr = new Hxtn_wiki_mgr();
|
||||
wiki_mgr.Init_by_xomp_merge(page_conn, wiki.Domain_str());
|
||||
}
|
||||
}
|
||||
public void Insert_bgn(boolean is_merge) {
|
||||
page_tbl.Stmt_bgn();
|
||||
blob_tbl.Stmt_bgn();
|
||||
}
|
||||
public void Insert_end(boolean is_merge) {
|
||||
page_tbl.Stmt_end();
|
||||
blob_tbl.Stmt_end();
|
||||
}
|
||||
public void Page_tbl__insert(int page_id, int wkr_id, int 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) {
|
||||
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
|
||||
blob_hash.Add_as_key_and_val(key);
|
||||
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 Load_by_page(Xoh_page hpg, Xoa_ttl ttl) {
|
||||
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());
|
||||
int len = list.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Hxtn_page_itm itm = (Hxtn_page_itm)list.Get_at(i);
|
||||
Hxtn_page_wkr wkr = (Hxtn_page_wkr)wkrs.Get_by_or_null(itm.Wkr_id());
|
||||
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());
|
||||
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
|
||||
, Id__indicators = 2
|
||||
;
|
||||
}
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
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.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
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
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.htmls.hxtns.pages;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Gfo_usr_dlg_;
|
||||
import gplx.Hash_adp_bry;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Io_url;
|
||||
import gplx.List_adp;
|
||||
import gplx.core.lists.hashs.Hash_adp__int;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_conn_bldr;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.htmls.Xoh_page;
|
||||
import gplx.xowa.htmls.hxtns.blobs.Hxtn_blob_tbl;
|
||||
import gplx.xowa.htmls.hxtns.wikis.Hxtn_wiki_mgr;
|
||||
import gplx.xowa.htmls.hxtns.wkrs.Hxtn_wkr_mgr;
|
||||
|
||||
public class Hxtn_page_mgr {
|
||||
private Hxtn_page_tbl page_tbl;
|
||||
private Hxtn_blob_tbl blob_tbl;
|
||||
private Hash_adp_bry blob_hash = Hash_adp_bry.cs();
|
||||
private final Hash_adp__int wkrs = new Hash_adp__int();
|
||||
private boolean dbs_missing = true;
|
||||
private Bry_bfr temp_bfr = Bry_bfr_.New();
|
||||
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
|
||||
this.page_tbl = new Hxtn_page_tbl(wkr_db_conn);
|
||||
this.blob_tbl = new Hxtn_blob_tbl(wkr_db_conn, zip_tid);
|
||||
|
||||
// if tbl exists, xomp_resume has run; load known blobs to prevent dupes
|
||||
if (wkr_db_conn.Meta_tbl_exists(page_tbl.Tbl_name())) {
|
||||
blob_tbl.Select_to_regy(temp_bfr, blob_hash);
|
||||
}
|
||||
// else tbl doesn't exist, so create them
|
||||
else {
|
||||
page_tbl.Create_tbl();
|
||||
blob_tbl.Create_tbl();
|
||||
}
|
||||
}
|
||||
public void Init_by_wiki(Xow_wiki wiki, boolean is_merge) {
|
||||
Io_url core_db_url = Make_url(wiki, "-html.hxtn-core.xowa");
|
||||
if (!is_merge && !Io_mgr.Instance.ExistsFil(core_db_url)) return;
|
||||
dbs_missing = false;
|
||||
Db_conn page_conn = Db_conn_bldr.Instance.Get_or_new(core_db_url).Conn();
|
||||
this.page_tbl = new Hxtn_page_tbl(page_conn);
|
||||
|
||||
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);
|
||||
|
||||
if (is_merge) {
|
||||
page_tbl.Create_tbl();
|
||||
blob_tbl.Create_tbl();
|
||||
|
||||
Hxtn_wkr_mgr wkr_mgr = new Hxtn_wkr_mgr();
|
||||
wkr_mgr.Init_by_xomp_merge(page_conn);
|
||||
|
||||
Hxtn_wiki_mgr wiki_mgr = new Hxtn_wiki_mgr();
|
||||
wiki_mgr.Init_by_xomp_merge(page_conn, wiki.Domain_str());
|
||||
}
|
||||
}
|
||||
public void Insert_bgn(boolean is_merge) {
|
||||
page_tbl.Stmt_bgn();
|
||||
blob_tbl.Stmt_bgn();
|
||||
}
|
||||
public void Insert_end(boolean is_merge) {
|
||||
page_tbl.Stmt_end();
|
||||
blob_tbl.Stmt_end();
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
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 Load_by_page(Xoh_page hpg, Xoa_ttl ttl) {
|
||||
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());
|
||||
int len = list.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Hxtn_page_itm itm = (Hxtn_page_itm)list.Get_at(i);
|
||||
Hxtn_page_wkr wkr = (Hxtn_page_wkr)wkrs.Get_by_or_null(itm.Wkr_id());
|
||||
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());
|
||||
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
|
||||
, Id__indicators = 2
|
||||
;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
import gplx.dbs.*;
|
||||
public class Hxtn_page_tbl implements Rls_able {
|
||||
private static final String tbl_name = "hxtn_page"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
|
||||
private final String fld_page_id, fld_wkr_id, fld_data_id;
|
||||
private final Db_conn conn; private Db_stmt stmt_insert;
|
||||
public Hxtn_page_tbl(Db_conn conn) {
|
||||
this.conn = conn;
|
||||
conn.Rls_reg(this);
|
||||
flds.Add_int_pkey_autonum("id");
|
||||
this.fld_page_id = flds.Add_int("page_id");
|
||||
this.fld_wkr_id = flds.Add_int("wkr_id");
|
||||
this.fld_data_id = flds.Add_int("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 Db_conn Conn() {return conn;}
|
||||
public void Rls() {
|
||||
stmt_insert = Db_stmt_.Rls(stmt_insert);
|
||||
}
|
||||
public void Stmt_bgn() {
|
||||
stmt_insert = conn.Stmt_insert(tbl_name, flds);
|
||||
}
|
||||
public void Stmt_end() {
|
||||
this.Rls();
|
||||
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 void Insert_by_rdr(Db_rdr rdr) {
|
||||
Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert);
|
||||
}
|
||||
public void Insert_exec(int page_id, int wkr_id, int data_id) {
|
||||
stmt_insert.Clear()
|
||||
.Val_int(fld_page_id , page_id)
|
||||
.Val_int(fld_wkr_id , wkr_id)
|
||||
.Val_int(fld_data_id , data_id)
|
||||
.Exec_insert();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
package gplx.xowa.htmls.hxtns.pages;
|
||||
|
||||
import gplx.List_adp;
|
||||
import gplx.List_adp_;
|
||||
import gplx.Rls_able;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_rdr;
|
||||
import gplx.dbs.Db_rdr_;
|
||||
import gplx.dbs.Db_stmt;
|
||||
import gplx.dbs.Db_stmt_;
|
||||
import gplx.dbs.Dbmeta_fld_list;
|
||||
import gplx.dbs.Dbmeta_idx_itm;
|
||||
import gplx.dbs.Dbmeta_tbl_itm;
|
||||
|
||||
public class Hxtn_page_tbl implements Rls_able {
|
||||
private static final String tbl_name = "hxtn_page"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
|
||||
private final String fld_page_id, fld_wkr_id, fld_data_id;
|
||||
private final Db_conn conn; private Db_stmt stmt_insert;
|
||||
public Hxtn_page_tbl(Db_conn conn) {
|
||||
this.conn = conn;
|
||||
conn.Rls_reg(this);
|
||||
flds.Add_int_pkey_autonum("id");
|
||||
this.fld_page_id = flds.Add_int("page_id");
|
||||
this.fld_wkr_id = flds.Add_int("wkr_id");
|
||||
this.fld_data_id = flds.Add_int("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 Db_conn Conn() {return conn;}
|
||||
public void Rls() {
|
||||
stmt_insert = Db_stmt_.Rls(stmt_insert);
|
||||
}
|
||||
public void Stmt_bgn() {
|
||||
stmt_insert = conn.Stmt_insert(tbl_name, flds);
|
||||
}
|
||||
public void Stmt_end() {
|
||||
this.Rls();
|
||||
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 void Insert_by_rdr(Db_rdr rdr) {
|
||||
Db_stmt_.Insert_by_rdr(flds, rdr, stmt_insert);
|
||||
}
|
||||
public void Insert_exec(int page_id, int wkr_id, int data_id) {
|
||||
stmt_insert.Clear()
|
||||
.Val_int(fld_page_id , page_id)
|
||||
.Val_int(fld_wkr_id , wkr_id)
|
||||
.Val_int(fld_data_id , data_id)
|
||||
.Exec_insert();
|
||||
}
|
||||
public boolean Exists(int page_id, int wkr_id, int data_id) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
public class Xow_db_file_ {
|
||||
public static final int Uid__core = 0;
|
||||
public static final byte
|
||||
Tid__core = 1, Tid__text = 2, Tid__cat = 3, Tid__search_core = 4, Tid__wbase = 5 // SERIALIZED:v1
|
||||
, Tid__cat_core = 6, Tid__cat_link = 7 // SERIALIZED:v2
|
||||
, Tid__wiki_solo = 8, Tid__text_solo = 9
|
||||
, Tid__html_solo = 10, Tid__html_data = 11
|
||||
, Tid__file_solo = 12, Tid__file_core = 13, Tid__file_data = 14, Tid__file_user = 15
|
||||
, Tid__search_link = 16, Tid__random = 17, Tid__css = 18
|
||||
, Tid__html_user = 19
|
||||
;
|
||||
private static final String
|
||||
Key__core = "core", Key__text = "text", Key__cat = "xtn.category", Key__search_core = "xtn.search.core", Key__wbase = "core.wbase"
|
||||
, Key__cat_core = "xtn.category.core", Key__cat_link = "xtn.category.link"
|
||||
, Key__text_solo = "text.solo", Key__wiki_solo = "wiki.solo"
|
||||
, 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"
|
||||
, Key__search_link = "xtn.search.link", Key__random = "xtn.random", Key__css = "xtn.css"
|
||||
, Key__html_user = "html.user"
|
||||
;
|
||||
public static String To_key(byte v) {
|
||||
switch (v) {
|
||||
case Tid__core: return Key__core;
|
||||
case Tid__text: return Key__text;
|
||||
case Tid__cat: return Key__cat;
|
||||
case Tid__search_core: return Key__search_core;
|
||||
case Tid__wbase: return Key__wbase;
|
||||
case Tid__cat_core: return Key__cat_core;
|
||||
case Tid__cat_link: return Key__cat_link;
|
||||
case Tid__wiki_solo: return Key__wiki_solo;
|
||||
case Tid__text_solo: return Key__text_solo;
|
||||
case Tid__html_solo: return Key__html_solo;
|
||||
case Tid__html_data: return Key__html_data;
|
||||
case Tid__file_solo: return Key__file_solo;
|
||||
case Tid__file_core: return Key__file_core;
|
||||
case Tid__file_data: return Key__file_data;
|
||||
case Tid__file_user: return Key__file_user;
|
||||
case Tid__search_link: return Key__search_link;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
package gplx.xowa.wikis.data;
|
||||
|
||||
import gplx.Err_;
|
||||
|
||||
public class Xow_db_file_ {
|
||||
public static final int Uid__core = 0;
|
||||
public static final byte
|
||||
Tid__core = 1, Tid__text = 2, Tid__cat = 3, Tid__search_core = 4, Tid__wbase = 5 // SERIALIZED:v1
|
||||
, Tid__cat_core = 6, Tid__cat_link = 7 // SERIALIZED:v2
|
||||
, Tid__wiki_solo = 8, Tid__text_solo = 9
|
||||
, Tid__html_solo = 10, Tid__html_data = 11
|
||||
, Tid__file_solo = 12, Tid__file_core = 13, Tid__file_data = 14, Tid__file_user = 15
|
||||
, Tid__search_link = 16, Tid__random = 17, Tid__css = 18
|
||||
, Tid__html_user = 19
|
||||
;
|
||||
private static final String
|
||||
Key__core = "core", Key__text = "text", Key__cat = "xtn.category", Key__search_core = "xtn.search.core", Key__wbase = "core.wbase"
|
||||
, Key__cat_core = "xtn.category.core", Key__cat_link = "xtn.category.link"
|
||||
, Key__text_solo = "text.solo", Key__wiki_solo = "wiki.solo"
|
||||
, 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"
|
||||
, Key__search_link = "xtn.search.link", Key__random = "xtn.random", Key__css = "xtn.css"
|
||||
, Key__html_user = "html.user"
|
||||
;
|
||||
public static String To_key(byte v) {
|
||||
switch (v) {
|
||||
case Tid__core: return Key__core;
|
||||
case Tid__text: return Key__text;
|
||||
case Tid__cat: return Key__cat;
|
||||
case Tid__search_core: return Key__search_core;
|
||||
case Tid__wbase: return Key__wbase;
|
||||
case Tid__cat_core: return Key__cat_core;
|
||||
case Tid__cat_link: return Key__cat_link;
|
||||
case Tid__wiki_solo: return Key__wiki_solo;
|
||||
case Tid__text_solo: return Key__text_solo;
|
||||
case Tid__html_solo: return Key__html_solo;
|
||||
case Tid__html_data: return Key__html_data;
|
||||
case Tid__file_solo: return Key__file_solo;
|
||||
case Tid__file_core: return Key__file_core;
|
||||
case Tid__file_data: return Key__file_data;
|
||||
case Tid__file_user: return Key__file_user;
|
||||
case Tid__search_link: return Key__search_link;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
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.xowa.wikis.domains.*; import gplx.xowa.bldrs.infos.*; import gplx.xowa.wikis.metas.*;
|
||||
public class Xow_db_mgr {
|
||||
private final Io_url wiki_root_dir;
|
||||
private final String domain_str; // needed for generating new files; EX: en.wikipedia.org-text.ns.001.xowa
|
||||
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;
|
||||
public Xow_db_mgr(Io_url wiki_root_dir, String domain_str) {
|
||||
this.wiki_root_dir = wiki_root_dir;
|
||||
this.domain_str = domain_str;
|
||||
}
|
||||
public Xowd_core_db_props Props() {return props;} private Xowd_core_db_props props = Xowd_core_db_props.Test;
|
||||
public Db_cfg_tbl Tbl__cfg() {return db__core.Tbl__cfg();}
|
||||
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 Xow_db_file Db__html() {return db__html;} private Xow_db_file db__html;
|
||||
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;}
|
||||
public void Init_by_load(Io_url core_url) {
|
||||
// clear lists
|
||||
hash_by_id.Clear();
|
||||
hash_by_tids.Clear();
|
||||
|
||||
// create core_conn / core_db
|
||||
Db_conn core_conn = Db_conn_bldr.Instance.Get(core_url);
|
||||
props = Xowd_core_db_props.Cfg_load(core_conn); // load props to get layout_text
|
||||
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));
|
||||
|
||||
// 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++) {
|
||||
Xow_db_file db = ary[i];
|
||||
Dbs__set_by_tid(db);
|
||||
Dbs__add(db);
|
||||
}
|
||||
}
|
||||
public void Init_by_make(Xowd_core_db_props props, Xob_info_session info_session) {
|
||||
this.props = props;
|
||||
|
||||
// save data
|
||||
Xow_db_file core_db = Xow_db_file__core_.Make_core_db(props, info_session, wiki_root_dir, domain_str);
|
||||
Dbs__set_by_tid(core_db);
|
||||
Dbs__add_and_save(core_db);
|
||||
props.Cfg_save(db__core.Tbl__cfg()); // NOTE: must save cfg now, especially zip_tid; latter will be reloaded after import is done;
|
||||
}
|
||||
public void Rls() {
|
||||
int len = hash_by_id.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xow_db_file db_file = (Xow_db_file)hash_by_id.Get_at(i);
|
||||
db_file.Rls();
|
||||
}
|
||||
}
|
||||
|
||||
public int Dbs__len() {return hash_by_id.Len();}
|
||||
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 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) {
|
||||
int tids_len = tids_ary.length;
|
||||
for (int i = 0; i < tids_len; ++i) {
|
||||
byte tid = tids_ary[i];
|
||||
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();
|
||||
if (tid_dbs_len != 1) { // NOTE: occurs when multiple search imports fail; DATE:2016-04-04
|
||||
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());
|
||||
}
|
||||
return (Xow_db_file)tid_dbs.Get_at(tid_dbs_len - 1); // get last idx;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Xow_db_file Dbs__assert_by_tid(byte tid) {
|
||||
Xow_db_file rv = Dbs__get_by_tid_or_null(tid);
|
||||
if (rv == null) {
|
||||
rv = Dbs__make_by_tid(tid);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
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__make_by_tid(byte tid) {
|
||||
int tid_idx = Get_tid_idx(hash_by_tids, tid);
|
||||
return Dbs__make_by_tid(tid, Xob_info_file.Ns_ids_empty, tid_idx, Get_tid_name(tid_idx, tid));
|
||||
}
|
||||
public Xow_db_file Dbs__make_by_tid(byte tid, String ns_ids, int part_id, String file_name_suffix) {
|
||||
return Dbs__make_by_id(db_id_next++, tid, ns_ids, part_id, file_name_suffix);
|
||||
}
|
||||
public Xow_db_file Dbs__make_by_id(int id, byte tid, String ns_ids, int part_id, String file_name_suffix) {
|
||||
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));
|
||||
Dbs__add_and_save(rv);
|
||||
Dbs__set_by_tid(rv);
|
||||
return rv;
|
||||
}
|
||||
public Xow_db_file Dbs__remake_by_tid(byte tid) {
|
||||
Dbs__delete_by_tid(tid);
|
||||
return Dbs__make_by_tid(tid);
|
||||
}
|
||||
public void Dbs__delete_by_tid(byte... tids) {
|
||||
int len = hash_by_id.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Xow_db_file db = (Xow_db_file)hash_by_id.Get_at(i);
|
||||
if (!Byte_.Match_any(db.Tid(), tids)) continue;
|
||||
db.Rls();
|
||||
Io_mgr.Instance.DeleteFil_args(db.Url()).MissingFails_off().Exec();
|
||||
db.Cmd_mode_(Db_cmd_mode.Tid_delete);
|
||||
}
|
||||
db__core.Tbl__db().Commit_all(this);
|
||||
|
||||
// call init again to regen list of dbs
|
||||
this.Init_by_load(db__core.Url());
|
||||
}
|
||||
public Xow_db_file Dbs__get_for_create(byte tid, int ns_id) {
|
||||
Xow_db_file[] ary = Dbs__get_ary(tid, ns_id);
|
||||
if (ary.length == 0) throw Err_.new_wo_type("no dbs exist; wiki=~{0} type=~{1}", domain_str, tid);
|
||||
return ary[ary.length - 1];
|
||||
}
|
||||
public Xow_db_file[] Dbs__get_ary(byte tid, int ns_id) {
|
||||
List_adp rv = List_adp_.New();
|
||||
|
||||
// loop all dbs
|
||||
int len = this.Dbs__len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
boolean add = false;
|
||||
Xow_db_file db = this.Dbs__get_at(i);
|
||||
switch (tid) {
|
||||
// cat_link requested
|
||||
case Xow_db_file_.Tid__cat_link:
|
||||
switch (db.Tid()) {
|
||||
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;
|
||||
case Xow_db_file_.Tid__cat_link:
|
||||
add = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// text requested
|
||||
case Xow_db_file_.Tid__text:
|
||||
switch (db.Tid()) {
|
||||
case Xow_db_file_.Tid__core:
|
||||
add = props.Layout_text().Tid_is_all(); // text will be in "core" if "all"
|
||||
break;
|
||||
case Xow_db_file_.Tid__text_solo: // EX: "en.wikipedia.org-text.xowa"
|
||||
add = true; // text will be in db if solo;
|
||||
break;
|
||||
case Xow_db_file_.Tid__text: // EX: "en.wikipedia.org-text-ns.000.xowa"
|
||||
int[] db_ns_ids = Int_ary_.Parse(db.Ns_ids(), "|"); // need to handle both "0" and "0|4"
|
||||
for (int db_ns_id : db_ns_ids) {
|
||||
if (db_ns_id == ns_id) {
|
||||
add = true; // text will be in db if ns matches; EX: en.wikipedia.org-text-ns.014.xowa
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (add)
|
||||
rv.Add(db);
|
||||
}
|
||||
|
||||
return (Xow_db_file[])rv.To_ary_and_clear(Xow_db_file.class);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
text_tbl.Insert_cmd_by_batch(page_id, text_zip_data);
|
||||
}
|
||||
private void Dbs__set_by_tid(Xow_db_file db) {
|
||||
switch (db.Tid()) {
|
||||
case Xow_db_file_.Tid__wiki_solo:
|
||||
case Xow_db_file_.Tid__text_solo:
|
||||
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;}
|
||||
case Xow_db_file_.Tid__text : {db__text = db; 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 :
|
||||
case Xow_db_file_.Tid__cat : {if (db__cat_core == null) db__cat_core = db; break;}
|
||||
}
|
||||
}
|
||||
private void Dbs__add(Xow_db_file db_file) {
|
||||
int db_id = db_file.Id();
|
||||
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
|
||||
db_id_next = db_id + 1;
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
package gplx.xowa.wikis.data;
|
||||
|
||||
import gplx.Byte_;
|
||||
import gplx.DateAdp;
|
||||
import gplx.Err_;
|
||||
import gplx.Guid_adp_;
|
||||
import gplx.Int_;
|
||||
import gplx.Int_ary_;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Io_url;
|
||||
import gplx.List_adp;
|
||||
import gplx.List_adp_;
|
||||
import gplx.Ordered_hash;
|
||||
import gplx.Ordered_hash_;
|
||||
import gplx.String_;
|
||||
import gplx.dbs.Db_cmd_mode;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_conn_bldr;
|
||||
import gplx.dbs.cfgs.Db_cfg_tbl;
|
||||
import gplx.xowa.Xoa_app_;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.bldrs.infos.Xob_info_file;
|
||||
import gplx.xowa.bldrs.infos.Xob_info_session;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_page_tbl;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_text_tbl;
|
||||
|
||||
public class Xow_db_mgr {
|
||||
private final Io_url wiki_root_dir;
|
||||
private final String domain_str; // needed for generating new files; EX: en.wikipedia.org-text.ns.001.xowa
|
||||
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;
|
||||
public Xow_db_mgr(Io_url wiki_root_dir, String domain_str) {
|
||||
this.wiki_root_dir = wiki_root_dir;
|
||||
this.domain_str = domain_str;
|
||||
}
|
||||
public Xowd_core_db_props Props() {return props;} private Xowd_core_db_props props = Xowd_core_db_props.Test;
|
||||
public Db_cfg_tbl Tbl__cfg() {return db__core.Tbl__cfg();}
|
||||
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 Xow_db_file Db__html() {return db__html;} private Xow_db_file db__html;
|
||||
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;}
|
||||
public void Init_by_load(Io_url core_url) {
|
||||
// clear lists
|
||||
hash_by_id.Clear();
|
||||
hash_by_tids.Clear();
|
||||
|
||||
// create core_conn / core_db
|
||||
Db_conn core_conn = Db_conn_bldr.Instance.Get(core_url);
|
||||
props = Xowd_core_db_props.Cfg_load(core_conn); // load props to get layout_text
|
||||
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));
|
||||
|
||||
// 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++) {
|
||||
Xow_db_file db = ary[i];
|
||||
Dbs__set_by_tid(db);
|
||||
Dbs__add(db);
|
||||
}
|
||||
}
|
||||
public void Init_by_make(Xowd_core_db_props props, Xob_info_session info_session) {
|
||||
this.props = props;
|
||||
|
||||
// save data
|
||||
Xow_db_file core_db = Xow_db_file__core_.Make_core_db(props, info_session, wiki_root_dir, domain_str);
|
||||
Dbs__set_by_tid(core_db);
|
||||
Dbs__add_and_save(core_db);
|
||||
props.Cfg_save(db__core.Tbl__cfg()); // NOTE: must save cfg now, especially zip_tid; latter will be reloaded after import is done;
|
||||
}
|
||||
public void Rls() {
|
||||
int len = hash_by_id.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xow_db_file db_file = (Xow_db_file)hash_by_id.Get_at(i);
|
||||
db_file.Rls();
|
||||
}
|
||||
}
|
||||
|
||||
public int Dbs__len() {return hash_by_id.Len();}
|
||||
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 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) {
|
||||
int tids_len = tids_ary.length;
|
||||
for (int i = 0; i < tids_len; ++i) {
|
||||
byte tid = tids_ary[i];
|
||||
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();
|
||||
if (tid_dbs_len != 1) { // NOTE: occurs when multiple search imports fail; DATE:2016-04-04
|
||||
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());
|
||||
}
|
||||
return (Xow_db_file)tid_dbs.Get_at(tid_dbs_len - 1); // get last idx;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Xow_db_file Dbs__assert_by_tid(byte tid) {
|
||||
Xow_db_file rv = Dbs__get_by_tid_or_null(tid);
|
||||
if (rv == null) {
|
||||
rv = Dbs__make_by_tid(tid);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
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__make_by_tid(byte tid) {
|
||||
int tid_idx = Get_tid_idx(hash_by_tids, tid);
|
||||
return Dbs__make_by_tid(tid, Xob_info_file.Ns_ids_empty, tid_idx, Get_tid_name(tid_idx, tid));
|
||||
}
|
||||
public Xow_db_file Dbs__make_by_tid(byte tid, String ns_ids, int part_id, String file_name_suffix) {
|
||||
return Dbs__make_by_id(db_id_next++, tid, ns_ids, part_id, file_name_suffix);
|
||||
}
|
||||
public Xow_db_file Dbs__make_by_id(int id, byte tid, String ns_ids, int part_id, String file_name_suffix) {
|
||||
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));
|
||||
Dbs__add_and_save(rv);
|
||||
Dbs__set_by_tid(rv);
|
||||
return rv;
|
||||
}
|
||||
public Xow_db_file Dbs__remake_by_tid(byte tid) {
|
||||
Dbs__delete_by_tid(tid);
|
||||
return Dbs__make_by_tid(tid);
|
||||
}
|
||||
public void Dbs__delete_by_tid(byte... tids) {
|
||||
int len = hash_by_id.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Xow_db_file db = (Xow_db_file)hash_by_id.Get_at(i);
|
||||
if (!Byte_.Match_any(db.Tid(), tids)) continue;
|
||||
db.Rls();
|
||||
Io_mgr.Instance.DeleteFil_args(db.Url()).MissingFails_off().Exec();
|
||||
db.Cmd_mode_(Db_cmd_mode.Tid_delete);
|
||||
}
|
||||
db__core.Tbl__db().Commit_all(this);
|
||||
|
||||
// call init again to regen list of dbs
|
||||
this.Init_by_load(db__core.Url());
|
||||
}
|
||||
public Xow_db_file Dbs__get_for_create(byte tid, int ns_id) {
|
||||
Xow_db_file[] ary = Dbs__get_ary(tid, ns_id);
|
||||
if (ary.length == 0) throw Err_.new_wo_type("no dbs exist; wiki=~{0} type=~{1}", domain_str, tid);
|
||||
return ary[ary.length - 1];
|
||||
}
|
||||
public Xow_db_file[] Dbs__get_ary(byte tid, int ns_id) {
|
||||
List_adp rv = List_adp_.New();
|
||||
|
||||
// loop all dbs
|
||||
int len = this.Dbs__len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
boolean add = false;
|
||||
Xow_db_file db = this.Dbs__get_at(i);
|
||||
switch (tid) {
|
||||
// cat_link requested
|
||||
case Xow_db_file_.Tid__cat_link:
|
||||
switch (db.Tid()) {
|
||||
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;
|
||||
case Xow_db_file_.Tid__cat_link:
|
||||
add = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// text requested
|
||||
case Xow_db_file_.Tid__text:
|
||||
switch (db.Tid()) {
|
||||
case Xow_db_file_.Tid__core:
|
||||
add = props.Layout_text().Tid_is_all(); // text will be in "core" if "all"
|
||||
break;
|
||||
case Xow_db_file_.Tid__text_solo: // EX: "en.wikipedia.org-text.xowa"
|
||||
add = true; // text will be in db if solo;
|
||||
break;
|
||||
case Xow_db_file_.Tid__text: // EX: "en.wikipedia.org-text-ns.000.xowa"
|
||||
int[] db_ns_ids = Int_ary_.Parse(db.Ns_ids(), "|"); // need to handle both "0" and "0|4"
|
||||
for (int db_ns_id : db_ns_ids) {
|
||||
if (db_ns_id == ns_id) {
|
||||
add = true; // text will be in db if ns matches; EX: en.wikipedia.org-text-ns.014.xowa
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (add)
|
||||
rv.Add(db);
|
||||
}
|
||||
|
||||
return (Xow_db_file[])rv.To_ary_and_clear(Xow_db_file.class);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
text_tbl.Insert_cmd_by_batch(page_id, text_zip_data);
|
||||
}
|
||||
private void Dbs__set_by_tid(Xow_db_file db) {
|
||||
switch (db.Tid()) {
|
||||
case Xow_db_file_.Tid__wiki_solo:
|
||||
case Xow_db_file_.Tid__text_solo:
|
||||
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;}
|
||||
case Xow_db_file_.Tid__text : {db__text = db; 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 :
|
||||
case Xow_db_file_.Tid__cat : {if (db__cat_core == null) db__cat_core = db; break;}
|
||||
}
|
||||
}
|
||||
private void Dbs__add(Xow_db_file db_file) {
|
||||
int db_id = db_file.Id();
|
||||
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
|
||||
db_id_next = db_id + 1;
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
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.*;
|
||||
public class Xodb_save_mgr_sql implements Xodb_save_mgr {
|
||||
private final Xodb_mgr_sql db_mgr;
|
||||
public Xodb_save_mgr_sql(Xodb_mgr_sql db_mgr) {this.db_mgr = db_mgr;}
|
||||
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;
|
||||
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;
|
||||
public int Data_create(Xowe_wiki wiki, Xoa_ttl ttl, byte[] text_raw) {
|
||||
int ns_id = ttl.Ns().Id();
|
||||
Xow_db_file db_file = db_mgr.Core_data_mgr().Db__core();
|
||||
int ns_count = db_file.Tbl__ns().Select_ns_count(ns_id) + 1;
|
||||
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_id == -1) { // HACK: changed for tests; was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;")
|
||||
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();
|
||||
try {
|
||||
int max_page_id = -1;
|
||||
while (rdr.Move_next()) {
|
||||
int cur_page_id = rdr.Read_int("page_id");
|
||||
if (cur_page_id > max_page_id) max_page_id = cur_page_id;
|
||||
}
|
||||
page_id = max_page_id + 1;
|
||||
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);
|
||||
} finally {rdr.Rls();}
|
||||
}
|
||||
Xow_db_mgr fsys_mgr = db_mgr.Core_data_mgr();
|
||||
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
|
||||
Xowd_text_tbl page_text_tbl = page_text_db.Tbl__text();
|
||||
byte[] text_zip = page_text_tbl.Zip(text_raw);
|
||||
boolean redirect = wiki.Redirect_mgr().Is_redirect(text_raw, text_raw.length);
|
||||
Xowd_page_tbl page_core_tbl = db_mgr.Core_data_mgr().Tbl__page();
|
||||
page_core_tbl.Insert_bgn();
|
||||
page_text_tbl.Insert_bgn();
|
||||
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);
|
||||
db_file.Tbl__ns().Update_ns_count(ns_id, ns_count);
|
||||
db_file.Tbl__cfg().Update_int(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, page_id + 1);
|
||||
} finally {
|
||||
page_core_tbl.Insert_end();
|
||||
page_text_tbl.Insert_end();
|
||||
}
|
||||
return page_id;
|
||||
}
|
||||
public void Data_update(Xoae_page page, byte[] text_raw) {
|
||||
boolean redirect = page.Wikie().Redirect_mgr().Is_redirect(text_raw, text_raw.length);
|
||||
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);
|
||||
// int html_db_id = db_page.Html_db_id();
|
||||
// if (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() {}
|
||||
}
|
||||
package gplx.xowa.wikis.dbs;
|
||||
|
||||
import gplx.DateAdp;
|
||||
import gplx.Datetime_now;
|
||||
import gplx.String_;
|
||||
import gplx.dbs.Db_rdr;
|
||||
import gplx.dbs.Dbmeta_fld_itm;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.wikis.data.Xow_db_file;
|
||||
import gplx.xowa.wikis.data.Xow_db_mgr;
|
||||
import gplx.xowa.wikis.data.Xowd_cfg_key_;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_page_tbl;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_text_tbl;
|
||||
|
||||
public class Xodb_save_mgr_sql implements Xodb_save_mgr {
|
||||
private final Xodb_mgr_sql db_mgr;
|
||||
public Xodb_save_mgr_sql(Xodb_mgr_sql db_mgr) {this.db_mgr = db_mgr;}
|
||||
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;
|
||||
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;
|
||||
public int Data_create(Xowe_wiki wiki, Xoa_ttl ttl, byte[] text_raw) {
|
||||
int ns_id = ttl.Ns().Id();
|
||||
Xow_db_file db_file = db_mgr.Core_data_mgr().Db__core();
|
||||
int ns_count = db_file.Tbl__ns().Select_ns_count(ns_id) + 1;
|
||||
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_id == -1) { // HACK: changed for tests; was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;")
|
||||
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();
|
||||
try {
|
||||
int max_page_id = -1;
|
||||
while (rdr.Move_next()) {
|
||||
int cur_page_id = rdr.Read_int("page_id");
|
||||
if (cur_page_id > max_page_id) max_page_id = cur_page_id;
|
||||
}
|
||||
page_id = max_page_id + 1;
|
||||
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);
|
||||
} finally {rdr.Rls();}
|
||||
}
|
||||
Xow_db_mgr fsys_mgr = db_mgr.Core_data_mgr();
|
||||
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
|
||||
Xowd_text_tbl page_text_tbl = page_text_db.Tbl__text();
|
||||
byte[] text_zip = page_text_tbl.Zip(text_raw);
|
||||
boolean redirect = wiki.Redirect_mgr().Is_redirect(text_raw, text_raw.length);
|
||||
Xowd_page_tbl page_core_tbl = db_mgr.Core_data_mgr().Tbl__page();
|
||||
page_core_tbl.Insert_bgn();
|
||||
page_text_tbl.Insert_bgn();
|
||||
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);
|
||||
db_file.Tbl__ns().Update_ns_count(ns_id, ns_count);
|
||||
db_file.Tbl__cfg().Update_int(Xowd_cfg_key_.Grp__db, Xowd_cfg_key_.Key__wiki__page__id_next, page_id + 1);
|
||||
} finally {
|
||||
page_core_tbl.Insert_end();
|
||||
page_text_tbl.Insert_end();
|
||||
}
|
||||
return page_id;
|
||||
}
|
||||
public void Data_update(Xoae_page page, byte[] text_raw) {
|
||||
boolean redirect = page.Wikie().Redirect_mgr().Is_redirect(text_raw, text_raw.length);
|
||||
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() {}
|
||||
}
|
||||
|
@ -1,145 +1,146 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
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.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
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
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.wikis.pages;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Err_;
|
||||
import gplx.Gfo_usr_dlg_;
|
||||
import gplx.core.net.qargs.Gfo_qarg_itm;
|
||||
import gplx.core.net.qargs.Gfo_qarg_mgr;
|
||||
import gplx.xowa.Xoa_app;
|
||||
import gplx.xowa.Xoa_app_;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xoa_url;
|
||||
import gplx.xowa.Xoa_url_;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.Xowe_wiki_;
|
||||
import gplx.xowa.addons.wikis.pages.syncs.core.Xosync_read_mgr;
|
||||
import gplx.xowa.guis.views.Xog_tab_itm;
|
||||
import gplx.xowa.wikis.data.tbls.Xowd_page_itm;
|
||||
|
||||
public class Xowe_page_mgr {
|
||||
private final Xowe_wiki wiki;
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
|
||||
private final Gfo_qarg_mgr tmp_qarg_mgr = new Gfo_qarg_mgr();
|
||||
public Xowe_page_mgr(Xowe_wiki wiki) {this.wiki = wiki;}
|
||||
public Xosync_read_mgr Sync_mgr() {return read_mgr;} private final Xosync_read_mgr read_mgr = new Xosync_read_mgr();
|
||||
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());
|
||||
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();
|
||||
// if qargs exist...
|
||||
if (qarg_ary.length > 0) {
|
||||
try {
|
||||
tmp_qarg_mgr.Init(qarg_ary);
|
||||
byte[] curid_bry = tmp_qarg_mgr.Read_bry_or(Xoa_url_.Qarg__curid, null);
|
||||
// if "curid" qarg exists....
|
||||
if (curid_bry != null) {
|
||||
int curid = Bry_.To_int_or(curid_bry, -1);
|
||||
Xowd_page_itm tmp_page = wiki.Data__core_mgr().Db__core().Tbl__page().Select_by_id_or_null(curid);
|
||||
// if curid exists in page tbl...
|
||||
if (tmp_page != null) {
|
||||
ttl = wiki.Ttl_parse(tmp_page.Ns_id(), tmp_page.Ttl_page_db());
|
||||
// handle "home/wiki/?curid=123"; XO automatically changes to "home/wiki/Main_Page?curid=123"; change back to "home/wiki/?curid=123"
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
// load page meta; wait_for_popups
|
||||
Xoae_page page = wiki.Data_mgr().Load_page_and_parse(url, ttl, wiki.Lang(), tab, false);
|
||||
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);
|
||||
if (redirect_ttl != null) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
// load from html_db
|
||||
boolean from_html_db = page.Db().Page().Html_db_id() != -1;
|
||||
boolean read_from_html_db_preferred = wiki.Html__hdump_mgr().Load_mgr().Read_preferred();
|
||||
boolean isCategoryPage = ttl.Ns().Id_is_ctg();
|
||||
if (from_html_db) {
|
||||
if (read_from_html_db_preferred) {
|
||||
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
|
||||
int html_len = Bry_.Len(page.Db().Html().Html_bry());
|
||||
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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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
|
||||
&& !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());
|
||||
}
|
||||
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);
|
||||
|
||||
// if [[Category]], generate catlinks (subc; page; file)
|
||||
if (isCategoryPage) {
|
||||
wiki.Ctg__catpage_mgr().Write_catpage(tmp_bfr, page);
|
||||
if (from_html_db) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
int wait_count = 0;
|
||||
while (gplx.xowa.htmls.modules.popups.Xow_popup_mgr.Running() && ++wait_count < 100)
|
||||
gplx.core.threads.Thread_adp_.Sleep(10);
|
||||
}
|
||||
}
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
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.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
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
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.wikis.pages;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Err_;
|
||||
import gplx.Gfo_usr_dlg_;
|
||||
import gplx.core.net.qargs.Gfo_qarg_itm;
|
||||
import gplx.core.net.qargs.Gfo_qarg_mgr;
|
||||
import gplx.xowa.Xoa_app;
|
||||
import gplx.xowa.Xoa_app_;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xoa_url;
|
||||
import gplx.xowa.Xoa_url_;
|
||||
import gplx.xowa.Xoae_page;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.Xowe_wiki_;
|
||||
import gplx.xowa.addons.wikis.pages.syncs.core.Xosync_read_mgr;
|
||||
import gplx.xowa.guis.views.Xog_tab_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;
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
|
||||
private final Gfo_qarg_mgr tmp_qarg_mgr = new Gfo_qarg_mgr();
|
||||
public Xowe_page_mgr(Xowe_wiki wiki) {this.wiki = wiki;}
|
||||
public Xosync_read_mgr Sync_mgr() {return read_mgr;} private final Xosync_read_mgr read_mgr = new Xosync_read_mgr();
|
||||
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());
|
||||
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();
|
||||
// if qargs exist...
|
||||
if (qarg_ary.length > 0) {
|
||||
try {
|
||||
tmp_qarg_mgr.Init(qarg_ary);
|
||||
byte[] curid_bry = tmp_qarg_mgr.Read_bry_or(Xoa_url_.Qarg__curid, null);
|
||||
// if "curid" qarg exists....
|
||||
if (curid_bry != null) {
|
||||
int curid = Bry_.To_int_or(curid_bry, -1);
|
||||
Xowd_page_itm tmp_page = wiki.Data__core_mgr().Db__core().Tbl__page().Select_by_id_or_null(curid);
|
||||
// if curid exists in page tbl...
|
||||
if (tmp_page != null) {
|
||||
ttl = wiki.Ttl_parse(tmp_page.Ns_id(), tmp_page.Ttl_page_db());
|
||||
// handle "home/wiki/?curid=123"; XO automatically changes to "home/wiki/Main_Page?curid=123"; change back to "home/wiki/?curid=123"
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
// load page meta; wait_for_popups
|
||||
Xoae_page page = wiki.Data_mgr().Load_page_and_parse(url, ttl, wiki.Lang(), tab, false);
|
||||
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);
|
||||
if (redirect_ttl != null) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
// load from html_db
|
||||
boolean from_html_db = page.Db().Page().Html_db_id() != Xopg_db_page.HTML_DB_ID_NULL;
|
||||
boolean read_from_html_db_preferred = wiki.Html__hdump_mgr().Load_mgr().Read_preferred();
|
||||
boolean isCategoryPage = ttl.Ns().Id_is_ctg();
|
||||
if (from_html_db) {
|
||||
if (read_from_html_db_preferred) {
|
||||
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
|
||||
int html_len = Bry_.Len(page.Db().Html().Html_bry());
|
||||
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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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
|
||||
&& !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());
|
||||
}
|
||||
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);
|
||||
|
||||
// if [[Category]], generate catlinks (subc; page; file)
|
||||
if (isCategoryPage) {
|
||||
wiki.Ctg__catpage_mgr().Write_catpage(tmp_bfr, page);
|
||||
if (from_html_db) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
int wait_count = 0;
|
||||
while (gplx.xowa.htmls.modules.popups.Xow_popup_mgr.Running() && ++wait_count < 100)
|
||||
gplx.core.threads.Thread_adp_.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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.*;
|
||||
import gplx.xowa.wikis.nss.*;
|
||||
public class Xopg_db_page {
|
||||
public Xopg_db_page() {this.Clear();}
|
||||
// from page table
|
||||
public boolean Exists() {return exists;} private boolean exists;
|
||||
public boolean Exists_n() {return !exists;}
|
||||
public int Id() {return id;} private int id;
|
||||
public int Ns_id() {return ns_id;} private int ns_id;
|
||||
public byte[] Ttl_bry() {return ttl_bry;} private byte[] ttl_bry;
|
||||
public DateAdp Modified_on() {return modified_on;} private DateAdp modified_on;
|
||||
public int Text_len() {return text_len;} private int text_len;
|
||||
public int Text_db_id() {return text_db_id;} private int text_db_id;
|
||||
public int Html_db_id() {return html_db_id;} private int html_db_id;
|
||||
public int Redirect_to_id() {return redirect_to_id;} private int redirect_to_id;
|
||||
public int Score() {return score;} private int score;
|
||||
|
||||
public void Exists_y_() {this.Exists_(Bool_.Y);}
|
||||
public void Exists_n_() {this.Exists_(Bool_.N);}
|
||||
public void Exists_(boolean v) {this.exists = v;}
|
||||
public Xopg_db_page Id_(int v) {this.id = v; return this;}
|
||||
public Xopg_db_page Score_(int v) {this.score = v; return this;}
|
||||
public Xopg_db_page Modified_on_(DateAdp v) {this.modified_on = v; return this;}
|
||||
public Xopg_db_page Html_db_id_(int v) {this.html_db_id = v; return this;}
|
||||
|
||||
// wiki-related
|
||||
public Xow_ns Ns() {return ns;} private Xow_ns ns;
|
||||
public Xoa_ttl Ttl() {return ttl;} private Xoa_ttl ttl;
|
||||
|
||||
// init methods
|
||||
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.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;
|
||||
this.ns = null; this.ttl = null;
|
||||
return this;
|
||||
}
|
||||
public Xopg_db_page Init_by_wiki(Xow_wiki wiki) {
|
||||
this.ns = wiki.Ns_mgr().Ids_get_or_null(ns_id);
|
||||
this.ttl = wiki.Ttl_parse(ns_id, ttl_bry);
|
||||
return this;
|
||||
}
|
||||
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
|
||||
this.html_db_id = -1; // NOTE: must set to -1 b/c code checks for -1 to indicate no html; DATE:2016-07-14
|
||||
}
|
||||
}
|
||||
package gplx.xowa.wikis.pages.dbs;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.DateAdp;
|
||||
import gplx.DateAdp_;
|
||||
import gplx.xowa.Xoa_ttl;
|
||||
import gplx.xowa.Xow_wiki;
|
||||
import gplx.xowa.wikis.nss.Xow_ns;
|
||||
|
||||
public class Xopg_db_page {
|
||||
public Xopg_db_page() {this.Clear();}
|
||||
// from page table
|
||||
public boolean Exists() {return exists;} private boolean exists;
|
||||
public boolean Exists_n() {return !exists;}
|
||||
public int Id() {return id;} private int id;
|
||||
public int Ns_id() {return ns_id;} private int ns_id;
|
||||
public byte[] Ttl_bry() {return ttl_bry;} private byte[] ttl_bry;
|
||||
public DateAdp Modified_on() {return modified_on;} private DateAdp modified_on;
|
||||
public int Text_len() {return text_len;} private int text_len;
|
||||
public int Text_db_id() {return text_db_id;} private int text_db_id;
|
||||
public int Html_db_id() {return html_db_id;} private int html_db_id;
|
||||
public int Redirect_to_id() {return redirect_to_id;} private int redirect_to_id;
|
||||
public int Score() {return score;} private int score;
|
||||
|
||||
public void Exists_y_() {this.Exists_(Bool_.Y);}
|
||||
public void Exists_n_() {this.Exists_(Bool_.N);}
|
||||
public void Exists_(boolean v) {this.exists = v;}
|
||||
public Xopg_db_page Id_(int v) {this.id = v; return this;}
|
||||
public Xopg_db_page Score_(int v) {this.score = v; return this;}
|
||||
public Xopg_db_page Modified_on_(DateAdp v) {this.modified_on = v; return this;}
|
||||
public Xopg_db_page Html_db_id_(int v) {this.html_db_id = v; return this;}
|
||||
|
||||
// wiki-related
|
||||
public Xow_ns Ns() {return ns;} private Xow_ns ns;
|
||||
public Xoa_ttl Ttl() {return ttl;} private Xoa_ttl ttl;
|
||||
|
||||
// init methods
|
||||
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.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;
|
||||
this.ns = null; this.ttl = null;
|
||||
return this;
|
||||
}
|
||||
public Xopg_db_page Init_by_wiki(Xow_wiki wiki) {
|
||||
this.ns = wiki.Ns_mgr().Ids_get_or_null(ns_id);
|
||||
this.ttl = wiki.Ttl_parse(ns_id, ttl_bry);
|
||||
return this;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user