diff --git a/400_xowa/src/gplx/html/Html_entity_.java b/400_xowa/src/gplx/html/Html_entity_.java index 7a4df4f93..8036e1bcd 100644 --- a/400_xowa/src/gplx/html/Html_entity_.java +++ b/400_xowa/src/gplx/html/Html_entity_.java @@ -30,6 +30,6 @@ public class Html_entity_ { , Pipe_bry = Bry_.new_ascii_("|") , Colon_bry = Bry_.new_ascii_(":"), Underline_bry = Bry_.new_ascii_("_"), Asterisk_bry = Bry_.new_ascii_("*") , Brack_bgn_bry = Bry_.new_ascii_("["), Brack_end_bry = Bry_.new_ascii_("]") - , Nbsp_bry = Bry_.new_ascii_(" ") + , Nbsp_num_bry = Bry_.new_ascii_(" ") ; } diff --git a/400_xowa/src/gplx/html/Html_tag_.java b/400_xowa/src/gplx/html/Html_tag_.java index 5b8d7a7bb..5ea1c8cd5 100644 --- a/400_xowa/src/gplx/html/Html_tag_.java +++ b/400_xowa/src/gplx/html/Html_tag_.java @@ -41,6 +41,7 @@ public class Html_tag_ { , Script_lhs = Bry_.new_ascii_("") + , Span_rhs = Bry_.new_ascii_("") ; public static final String diff --git a/400_xowa/src/gplx/xowa/Xoa_app_.java b/400_xowa/src/gplx/xowa/Xoa_app_.java index b2aa71d7e..2996a368a 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app_.java +++ b/400_xowa/src/gplx/xowa/Xoa_app_.java @@ -24,7 +24,7 @@ public class Xoa_app_ { boot_mgr.Run(args); } public static final String Name = "xowa"; - public static final String Version = "1.10.2.1"; + public static final String Version = "1.10.3.1"; public static String Build_date = "2012-12-30 00:00:00"; public static String Op_sys; public static String User_agent = ""; diff --git a/400_xowa/src/gplx/xowa/apis/xowa/Xoapi_net.java b/400_xowa/src/gplx/xowa/apis/xowa/Xoapi_net.java index 548aa6977..f907df01f 100644 --- a/400_xowa/src/gplx/xowa/apis/xowa/Xoapi_net.java +++ b/400_xowa/src/gplx/xowa/apis/xowa/Xoapi_net.java @@ -21,7 +21,7 @@ public class Xoapi_net implements GfoInvkAble, GfoEvObj { public GfoEvMgr EvMgr() {return ev_mgr;} private GfoEvMgr ev_mgr; public void Init_by_kit(Xoa_app app) { } - public boolean Enabled() {return enabled;} private boolean enabled; + public boolean Enabled() {return enabled;} private boolean enabled = true; public void Enabled_(boolean v) { this.enabled = v; gplx.ios.IoEngine_system.Web_access_enabled = v; diff --git a/400_xowa/src/gplx/xowa/bldrs/Xob_cmd_mgr.java b/400_xowa/src/gplx/xowa/bldrs/Xob_cmd_mgr.java index cb356301d..afdb1a871 100644 --- a/400_xowa/src/gplx/xowa/bldrs/Xob_cmd_mgr.java +++ b/400_xowa/src/gplx/xowa/bldrs/Xob_cmd_mgr.java @@ -60,7 +60,7 @@ public class Xob_cmd_mgr implements GfoInvkAble { else if (String_.Eq(cmd_key, Xob_page_regy_cmd.KEY_oimg)) return Add(new Xob_page_regy_cmd(bldr, wiki)); else if (String_.Eq(cmd_key, Xob_cmd_exec_sql.KEY)) return Add(new Xob_cmd_exec_sql(bldr, wiki)); - else if (String_.Eq(cmd_key, Xob_wiki_redirect_cmd.KEY_redirect)) return Add(new Xob_wiki_redirect_cmd(bldr, wiki)); + else if (String_.Eq(cmd_key, Xob_redirect_cmd.KEY_redirect)) return Add(new Xob_redirect_cmd(bldr, wiki)); else if (String_.Eq(cmd_key, Xob_wiki_image_sql.KEY)) return Add(new Xob_wiki_image_sql(bldr, wiki)); else if (String_.Eq(cmd_key, Xob_fsdb_make.KEY_oimg)) return Add(new Xob_fsdb_make(bldr, wiki)); diff --git a/400_xowa/src/gplx/xowa/bldrs/files/Xob_lnki_temp_wkr.java b/400_xowa/src/gplx/xowa/bldrs/files/Xob_lnki_temp_wkr.java index eb6831b8a..795b5a397 100644 --- a/400_xowa/src/gplx/xowa/bldrs/files/Xob_lnki_temp_wkr.java +++ b/400_xowa/src/gplx/xowa/bldrs/files/Xob_lnki_temp_wkr.java @@ -27,10 +27,10 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xop_lnki_log private Xop_log_invoke_wkr invoke_wkr; private Xop_log_property_wkr property_wkr; private int[] ns_ids = Int_.Ary(Xow_ns_.Id_main);// , Xow_ns_.Id_category, Xow_ns_.Id_template private boolean wiki_ns_file_is_case_match_all = true; private Xow_wiki commons_wiki; - private Xob_hdump_bldr hdump_bldr; private long hdump_max = Io_mgr.Len_gb; + private Xob_hdump_bldr hdump_bldr; private long hdump_max = Io_mgr.Len_gb; public Xob_lnki_temp_wkr(Xob_bldr bldr, Xow_wiki wiki) {this.Cmd_ctor(bldr, wiki);} @Override public String Cmd_key() {return KEY_oimg;} public static final String KEY_oimg = "file.lnki_temp"; - @Override public byte Init_redirect() {return Bool_.N_byte;} // lnki will never be found in a redirect + @Override public byte Init_redirect() {return Bool_.N_byte;} @Override public int[] Init_ns_ary() {return ns_ids;} @Override protected void Init_reset(Db_provider p) { p.Exec_sql("DELETE FROM " + Xodb_xowa_cfg_tbl.Tbl_name); @@ -40,8 +40,8 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xop_lnki_log } @Override protected Db_provider Init_db_file() { ctx.Lnki().File_wkr_(this); - Xodb_db_file db_file = Xodb_db_file.init__file_make(wiki.Fsys_mgr().Root_dir()); - provider = db_file.Provider(); + Xodb_db_file make_db_file = Xodb_db_file.init__file_make(wiki.Fsys_mgr().Root_dir()); + provider = make_db_file.Provider(); Xob_lnki_temp_tbl.Create_table(provider); stmt = Xob_lnki_temp_tbl.Insert_stmt(provider); return provider; @@ -68,7 +68,9 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xop_lnki_log Fsdb_mnt_mgr trg_mnt_mgr = trg_fsdb_mgr.Mnt_mgr(); trg_mnt_mgr.Insert_to_mnt_(Fsdb_mnt_mgr.Mnt_idx_main); Fsdb_mnt_mgr.Patch(trg_mnt_mgr); // NOTE: see fsdb_make; DATE:2014-04-26 - if (gen_hdump) hdump_bldr = new Xob_hdump_bldr(wiki, provider, hdump_max); + if (gen_hdump) { + hdump_bldr = new Xob_hdump_bldr(wiki, provider, hdump_max); + } provider.Txn_mgr().Txn_bgn_if_none(); log_mgr.Txn_bgn(); } @@ -88,7 +90,8 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xop_lnki_log parser.Parse_page_all_clear(root, ctx, ctx.Tkn_mkr(), page_src); if (gen_html) { page.Root_(root); - wiki.Html_mgr().Page_wtr_mgr().Gen(ctx.Cur_page(), Xopg_view_mode.Tid_read); + if (!page.Redirected()) + wiki.Html_mgr().Page_wtr_mgr().Gen(ctx.Cur_page(), Xopg_view_mode.Tid_read); } if (gen_hdump) { page.Root_(root); diff --git a/400_xowa/src/gplx/xowa/bldrs/imports/Xob_import_marker.java b/400_xowa/src/gplx/xowa/bldrs/imports/Xob_import_marker.java index 3e5095661..50014d4c5 100644 --- a/400_xowa/src/gplx/xowa/bldrs/imports/Xob_import_marker.java +++ b/400_xowa/src/gplx/xowa/bldrs/imports/Xob_import_marker.java @@ -25,14 +25,8 @@ public class Xob_import_marker { if (!Io_mgr._.ExistsFil(url)) return true; Xoa_app app = wiki.App(); app.Usr_dlg().Log_many("", "", "import.marker: marker found: url=~{0}", url.Raw()); - int rslt = app.Gui_mgr().Kit().Ask_yes_no_cancel("", "", String_.Concat_lines_nl - ( "~{0} was not completely imported." - , "Please choose one of the following:" - , "" - , "* Yes\t: Delete the wiki. You will need to reimport again." - , "* No\t: Delete the warning. XOWA will continue, but may run into unexpected issues." - , "* Cancel\t: Do nothing and continue. This message will show whenever you restart the app and reopen this wiki." - ), wiki.Domain_str()); + byte[] incompete_msg_bry = app.User().Msg_mgr().Val_by_key_args(Bry_.new_ascii_("api-xowa.import.core.incomplete"), wiki.Domain_str()); + int rslt = app.Gui_mgr().Kit().Ask_yes_no_cancel("", "", String_.new_utf8_(incompete_msg_bry)); switch (rslt) { case Gfui_dlg_msg_.Btn_yes: Xobc_core_cleanup.Delete_wiki_sql(wiki); Import_end(wiki); return false; // delete wiki case Gfui_dlg_msg_.Btn_no: Import_end(wiki); return true; // delete marker diff --git a/400_xowa/src/gplx/xowa/bldrs/imports/Xob_page_sql.java b/400_xowa/src/gplx/xowa/bldrs/imports/Xob_page_sql.java index 14336c4bf..5fbbf340c 100644 --- a/400_xowa/src/gplx/xowa/bldrs/imports/Xob_page_sql.java +++ b/400_xowa/src/gplx/xowa/bldrs/imports/Xob_page_sql.java @@ -16,13 +16,14 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.bldrs.imports; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; -import gplx.dbs.*; import gplx.xowa.dbs.*; import gplx.xowa.dbs.tbls.*; import gplx.ios.*; +import gplx.dbs.*; import gplx.xowa.dbs.*; import gplx.xowa.dbs.tbls.*; import gplx.ios.*; import gplx.xowa.bldrs.wikis.redirects.*; public class Xob_page_sql extends Xob_itm_basic_base implements Xobd_wkr, GfoInvkAble { private Db_idx_mode idx_mode = Db_idx_mode.Itm_end; - private Xop_redirect_mgr redirect_mgr; private Io_stream_zip_mgr zip_mgr; private byte data_storage_format; + private Io_stream_zip_mgr zip_mgr; private byte data_storage_format; private boolean redirect_id_enabled; private Xodb_mgr_sql db_mgr; private Xodb_fsys_mgr fsys_mgr; private Db_provider page_provider; private Db_stmt page_stmt; private Xob_text_stmts_mgr text_stmts_mgr; private int page_count_all, page_count_main = 0; private int txn_commit_interval = 100000; // 100 k private DateAdp modified_latest = DateAdp_.MinValue; + private Xop_redirect_mgr redirect_mgr; private Xob_redirect_tbl redirect_tbl; public Xob_page_sql(Xob_bldr bldr, Xow_wiki wiki) {this.Cmd_ctor(bldr, wiki);} public String Wkr_key() {return KEY;} public static final String KEY = "import.sql.page"; public void Wkr_bgn(Xob_bldr bldr) { @@ -42,6 +43,11 @@ public class Xob_page_sql extends Xob_itm_basic_base implements Xobd_wkr, GfoInv page_provider.Txn_mgr().Txn_bgn_if_none(); text_stmts_mgr = new Xob_text_stmts_mgr(db_mgr, fsys_mgr); if (idx_mode.Tid_is_bgn()) Idx_create(); + + if (redirect_id_enabled) { + redirect_tbl = new Xob_redirect_tbl(wiki.Fsys_mgr().Root_dir(), app.Encoder_mgr().Url_ttl()).Create_table(); + redirect_tbl.Provider().Txn_mgr().Txn_bgn_if_none(); + } } public void Wkr_run(Xodb_page page) { int page_id = page.Id(); @@ -66,6 +72,9 @@ public class Xob_page_sql extends Xob_itm_basic_base implements Xobd_wkr, GfoInv page_stmt.New(); // must new stmt variable, else java.sql.SQLException: "statement is not executing" text_stmt.New(); // must new stmt variable, else java.sql.SQLException: "statement is not executing" } + if (redirect && redirect_id_enabled) { + redirect_tbl.Insert(page_id, page.Ttl_wo_ns(), redirect_ttl); + } ++page_count_all; if (ns.Id_main() && !page.Type_redirect()) ++page_count_main; if (page_count_all % txn_commit_interval == 0) text_stmt.Provider().Txn_mgr().Txn_end_all_bgn_if_none(); @@ -82,6 +91,12 @@ public class Xob_page_sql extends Xob_itm_basic_base implements Xobd_wkr, GfoInv db_mgr.Tbl_xowa_db().Commit_all(page_provider, db_mgr.Fsys_mgr().Files_ary()); // save dbs; note that dbs can be saved again later db_mgr.Tbl_xowa_cfg().Insert_str(Xodb_mgr_sql.Grp_wiki_init, "props.modified_latest", modified_latest.XtoStr_fmt(DateAdp_.Fmt_iso8561_date_time)); if (idx_mode.Tid_is_end()) Idx_create(); + if (redirect_id_enabled) { + redirect_tbl.Provider().Txn_mgr().Txn_end_all(); + Xodb_file core_file = fsys_mgr.Get_tid_root(Xodb_file_tid.Tid_core); + redirect_tbl.Update_trg_redirect_id(core_file.Url(), 1); + redirect_tbl.Update_src_redirect_id(core_file.Url(), page_provider); + } } private void Idx_create() { fsys_mgr.Index_create(usr_dlg, Byte_.Ary(Xodb_file_tid.Tid_core, Xodb_file_tid.Tid_text), Idx_page_title, Idx_page_random); @@ -89,10 +104,11 @@ public class Xob_page_sql extends Xob_itm_basic_base implements Xobd_wkr, GfoInv @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_txn_commit_interval_)) txn_commit_interval = m.ReadInt("v"); else if (ctx.Match(k, Invk_idx_mode_)) idx_mode = Db_idx_mode.Xto_itm(m.ReadStr("v")); + else if (ctx.Match(k, Invk_redirect_id_enabled_)) redirect_id_enabled = m.ReadYn("v"); else return super.Invk(ctx, ikey, k, m); return this; } - private static final String Invk_txn_commit_interval_ = "txn_commit_interval_", Invk_idx_mode_ = "idx_mode_"; + private static final String Invk_txn_commit_interval_ = "txn_commit_interval_", Invk_idx_mode_ = "idx_mode_", Invk_redirect_id_enabled_ = "redirect_id_enabled_"; public void Wkr_ini(Xob_bldr bldr) {} public void Wkr_print() {} private static final Db_idx_itm @@ -155,5 +171,5 @@ class Xob_text_stmts_mgr { } text_stmts[stmt_idx] = stmt; text_stmts_len = new_len; - } Db_stmt[] text_stmts = new Db_stmt[0]; int text_stmts_len, text_stmts_max = 0; + } private Db_stmt[] text_stmts = new Db_stmt[0]; int text_stmts_len, text_stmts_max = 0; } diff --git a/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_category_registry_sql.java b/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_category_registry_sql.java index e69be11a7..160fd063a 100644 --- a/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_category_registry_sql.java +++ b/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_category_registry_sql.java @@ -24,6 +24,7 @@ public class Xob_category_registry_sql implements Xob_cmd { public void Cmd_bgn(Xob_bldr bldr) {} public void Cmd_run() {} public void Cmd_end() { // NOTE: placing in end, b/c must run *after* page_sql + wiki.Html_mgr().Importing_ctgs_(Bool_.Y); Io_url rslt_dir = Xob_category_registry_sql.Get_dir_output(wiki); Io_mgr._.DeleteDirDeep(rslt_dir); Xob_tmp_wtr rslt_wtr = Xob_tmp_wtr.new_wo_ns_(Io_url_gen_.dir_(rslt_dir), Io_mgr.Len_mb); @@ -47,6 +48,7 @@ public class Xob_category_registry_sql implements Xob_cmd { } } finally {rdr.Rls();} rslt_wtr.Flush(usr_dlg); + wiki.Html_mgr().Importing_ctgs_(Bool_.N); } public void Cmd_print() {} public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { diff --git a/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_categorylinks_base.java b/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_categorylinks_base.java index 4fd1c6077..389d1b96b 100644 --- a/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_categorylinks_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/imports/ctgs/Xob_categorylinks_base.java @@ -22,6 +22,7 @@ public abstract class Xob_categorylinks_base extends Xob_sql_dump_base implement @Override public String Sql_file_name() {return "categorylinks";} @Override public void Cmd_bgn_hook(Xob_bldr bldr, Sql_file_parser parser) { this.sql_parser = parser; + wiki.Html_mgr().Importing_ctgs_(Bool_.Y); parser.Fld_cmd_(this).Flds_req_(Fld_cl_from, Fld_cl_to, Fld_cl_timestamp, Fld_cl_collation, Fld_cl_sortkey, Fld_cl_type); } static final byte[] Fld_cl_from = Bry_.new_ascii_("cl_from"), Fld_cl_to = Bry_.new_ascii_("cl_to"), Fld_cl_timestamp = Bry_.new_ascii_("cl_timestamp"), Fld_cl_collation = Bry_.new_ascii_("cl_collation"), Fld_cl_sortkey = Bry_.new_ascii_("cl_sortkey"), Fld_cl_type = Bry_.new_ascii_("cl_type"); public void Exec(byte[] src, byte[] fld_key, int fld_idx, int fld_bgn, int fld_end, Bry_bfr file_bfr, Sql_file_parser_data data) { @@ -65,6 +66,7 @@ public abstract class Xob_categorylinks_base extends Xob_sql_dump_base implement } int cur_id = -1, cur_date = -1; byte[] cur_ctg = null, cur_sortkey = null; byte cur_tid = Byte_.MaxValue_127; boolean cur_collation_is_uca; int[] cur_modified_on = new int[7]; @Override public void Cmd_end() { Xobdc_merger.Basic(bldr.Usr_dlg(), dump_url_gen, temp_dir.GenSubDir("sort"), sort_mem_len, Xoctg_link_sql_sorter._, Io_line_rdr_key_gen_.noop, Make_sort_cmd(sql_parser)); + wiki.Html_mgr().Importing_ctgs_(Bool_.N); } DateAdp_parser date_parser = DateAdp_parser.new_(); Sql_file_parser sql_parser; Uca_trie trie; Bry_bfr uca_bfr = Bry_bfr.reset_(255); private static final byte[] Collation_uca = Bry_.new_utf8_("uca"), Sortkey_space = new byte[] {Byte_ascii.Space}; diff --git a/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_wiki_redirect_cmd.java b/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_redirect_cmd.java similarity index 62% rename from 400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_wiki_redirect_cmd.java rename to 400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_redirect_cmd.java index 61ebd6958..6edc94c69 100644 --- a/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_wiki_redirect_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_redirect_cmd.java @@ -17,47 +17,41 @@ along with this program. If not, see . */ package gplx.xowa.bldrs.wikis.redirects; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wikis.*; import gplx.dbs.*; import gplx.xowa.dbs.*; import gplx.xowa.dbs.tbls.*; import gplx.xowa.bldrs.oimgs.*; -public class Xob_wiki_redirect_cmd extends Xob_dump_mgr_base { - private Db_provider provider; private Db_stmt stmt; - private Xob_wiki_redirect_tbl tbl_redirect; +public class Xob_redirect_cmd extends Xob_dump_mgr_base { + private Db_provider provider; private Xob_redirect_tbl redirect_tbl; private Xodb_mgr_sql db_mgr; private Xop_redirect_mgr redirect_mgr; private Url_encoder encoder; - public Xob_wiki_redirect_cmd(Xob_bldr bldr, Xow_wiki wiki) {this.Cmd_ctor(bldr, wiki);} + public Xob_redirect_cmd(Xob_bldr bldr, Xow_wiki wiki) {this.Cmd_ctor(bldr, wiki);} @Override public String Cmd_key() {return KEY_redirect;} public static final String KEY_redirect = "wiki.redirect"; @Override public int[] Init_ns_ary() {return Int_.Ary(Xow_ns_.Id_file);} // restrict to file ns @Override public byte Init_redirect() {return Bool_.Y_byte;} // restrict to redirects @Override protected void Init_reset(Db_provider p) { p.Exec_sql("DELETE FROM " + Xodb_xowa_cfg_tbl.Tbl_name); - p.Exec_sql("DELETE FROM " + Xob_wiki_redirect_tbl.Tbl_name); + p.Exec_sql("DELETE FROM " + Xob_redirect_tbl.Tbl_name); } @Override protected Db_provider Init_db_file() { this.db_mgr = wiki.Db_mgr_as_sql(); Xoa_app app = bldr.App(); redirect_mgr = wiki.Redirect_mgr(); encoder = app.Encoder_mgr().Url_ttl(); -// app.Usr_dlg().Prog_none("", "", "dropping index: page__title"); -// db_mgr.Fsys_mgr().Core_provider().Exec_sql("DROP INDEX IF EXISTS page__title"); -// Sqlite_engine_.Idx_create(app.Usr_dlg(), db_mgr.Fsys_mgr().Core_provider(), "page", Idx_page_title); - Xodb_db_file db_file = Xodb_db_file.init__wiki_redirect(wiki.Fsys_mgr().Root_dir()); - provider = db_file.Provider(); - tbl_redirect = new Xob_wiki_redirect_tbl().Create_table(provider); - stmt = tbl_redirect.Insert_stmt(provider); + redirect_tbl = new Xob_redirect_tbl(wiki.Fsys_mgr().Root_dir(), app.Encoder_mgr().Url_ttl()).Create_table(); + provider = redirect_tbl.Provider(); provider.Txn_mgr().Txn_bgn_if_none(); return provider; } + @Override protected void Cmd_bgn_end() {} @Override public void Exec_pg_itm_hook(Xow_ns ns, Xodb_page page, byte[] page_src) { Xoa_ttl redirect_ttl = redirect_mgr.Extract_redirect(page_src, page_src.length); byte[] redirect_ttl_bry = Xoa_ttl.Replace_spaces(redirect_ttl.Page_db()); // NOTE: spaces can still exist b/c redirect is scraped from #REDIRECT which sometimes has a mix; EX: "A_b c" redirect_ttl_bry = encoder.Decode(redirect_ttl_bry); - tbl_redirect.Insert(stmt, page.Id(), Xoa_ttl.Replace_spaces(page.Ttl_wo_ns()), -1, redirect_ttl.Ns().Id(), redirect_ttl_bry, redirect_ttl.Anch_txt(), 1); + redirect_tbl.Insert(page.Id(), Xoa_ttl.Replace_spaces(page.Ttl_wo_ns()), -1, redirect_ttl.Ns().Id(), redirect_ttl_bry, redirect_ttl.Anch_txt(), 1); } @Override public void Exec_commit_hook() { provider.Txn_mgr().Txn_end_all_bgn_if_none(); } @Override public void Exec_end_hook() { provider.Txn_mgr().Txn_end_all(); - tbl_redirect.Create_indexes(usr_dlg, provider); - tbl_redirect.Update_redirects(provider, db_mgr.Fsys_mgr().Get_url(Xodb_file_tid.Tid_core), 4); + redirect_tbl.Create_indexes(usr_dlg); + redirect_tbl.Update_trg_redirect_id(db_mgr.Fsys_mgr().Get_url(Xodb_file_tid.Tid_core), 4); } -// private static final Db_idx_itm Idx_page_title = Db_idx_itm.sql_("CREATE UNIQUE INDEX IF NOT EXISTS page__title ON page (page_namespace, page_title, page_id, page_len, page_is_redirect, page_file_idx);"); // PERF:page_id for general queries; PERF: page_len for search_suggest } diff --git a/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_redirect_tbl.java b/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_redirect_tbl.java new file mode 100644 index 000000000..c93bd2824 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_redirect_tbl.java @@ -0,0 +1,164 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.bldrs.wikis.redirects; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wikis.*; +import gplx.dbs.*; import gplx.xowa.dbs.*; import gplx.xowa.bldrs.oimgs.*; +public class Xob_redirect_tbl { + private Url_encoder encoder; private Db_stmt insert_stmt; + public Xob_redirect_tbl(Io_url root_dir, Url_encoder encoder) { + this.db_file = Xodb_db_file.init__wiki_redirect(root_dir); + this.provider = db_file.Provider(); + this.encoder = encoder; + } + public Xodb_db_file Db_file() {return db_file;} private Xodb_db_file db_file; + public Db_provider Provider() {return provider;} private Db_provider provider; + public Xob_redirect_tbl Create_table() {Sqlite_engine_.Tbl_create(provider, Tbl_name, Tbl_sql); return this;} + public void Create_indexes(Gfo_usr_dlg usr_dlg) { + Sqlite_engine_.Idx_create(usr_dlg, provider, Xodb_db_file.Name__wiki_redirect, Idx_trg_id, Idx_trg_ttl); + } + public void Update_trg_redirect_id(Io_url core_url, int max_redirected_depth) { + Sqlite_engine_.Db_attach(provider, "page_db", core_url.Raw()); // link database with page table + provider.Exec_sql(Sql_get_page_data); // fill in page_id, page_ns, page_is_redirect for trg_ttl; EX: Page_A has "#REDIRECT Page_B"; Page_B is in redirect tbl; find its id, ttl, redirect status + for (int i = 0; i < max_redirected_depth; i++) { // loop to find redirected redirects; note that it is bounded by depth (to guard against circular redirects) + int affected = provider.Exec_sql(Sql_get_redirect_redirects); // find redirects that are also redirects + if (affected == 0) break; // no more redirected redirects; stop + provider.Exec_sql(Sql_get_redirect_page_data); // get page data for redirects + } + Sqlite_engine_.Db_detach(provider, "page_db"); + } + public void Update_src_redirect_id(Io_url core_url, Db_provider core_provider) { + core_provider.Exec_sql(Sql_ddl__page_redirect_id); // create page.page_redirect_id + Sqlite_engine_.Idx_create(provider, Idx_trg_src); + Sqlite_engine_.Db_attach(provider, "page_db", core_url.Raw()); // link database with page table + provider.Exec_sql(Sql_update_redirect_id); // update page_redirect_id + Sqlite_engine_.Db_detach(provider, "page_db"); + } + public void Insert(int src_id, byte[] src_bry, Xoa_ttl trg_ttl) { + byte[] redirect_ttl_bry = Xoa_ttl.Replace_spaces(trg_ttl.Page_db()); // NOTE: spaces can still exist b/c redirect is scraped from #REDIRECT which sometimes has a mix; EX: "A_b c" + redirect_ttl_bry = encoder.Decode(redirect_ttl_bry); + this.Insert(src_id, Xoa_ttl.Replace_spaces(src_bry), -1, trg_ttl.Ns().Id(), redirect_ttl_bry, trg_ttl.Anch_txt(), 1); + } + public void Insert(int src_id, byte[] src_ttl, int trg_id, int trg_ns, byte[] trg_ttl, byte[] trg_anchor, int count) { + if (insert_stmt == null) insert_stmt = Db_stmt_.new_insert_(provider, Tbl_name, Fld_src_id, Fld_src_ttl, Fld_trg_id, Fld_trg_ns, Fld_trg_ttl, Fld_trg_anchor, Fld_trg_is_redirect, Fld_redirect_count); + insert_stmt.Clear() + .Val_int_(src_id) + .Val_str_by_bry_(src_ttl) + .Val_int_(trg_id) + .Val_int_(trg_ns) + .Val_str_by_bry_(trg_ttl) + .Val_str_by_bry_(trg_anchor) + .Val_byte_((byte)1) + .Val_int_(count) + .Exec_insert(); + } + public void Rls_all() { + insert_stmt.Rls(); + provider.Conn_term(); + } + public static final String Tbl_name = "redirect"; + private static final String + Fld_src_id = "src_id", Fld_src_ttl = "src_ttl", Fld_trg_id = "trg_id", Fld_trg_ns = "trg_ns", Fld_trg_ttl = "trg_ttl", Fld_trg_anchor = "trg_anchor" + , Fld_trg_is_redirect = "trg_is_redirect", Fld_redirect_count = "redirect_count"; + private static final String Tbl_sql = String_.Concat_lines_nl + ( "CREATE TABLE IF NOT EXISTS redirect" + , "( src_id integer NOT NULL PRIMARY KEY" + , ", src_ttl varchar(255) NOT NULL" + , ", trg_id integer NOT NULL" + , ", trg_ns integer NOT NULL" + , ", trg_ttl varchar(255) NOT NULL" + , ", trg_anchor varchar(255) NOT NULL" + , ", trg_is_redirect tinyint NOT NULL" + , ", redirect_count integer NOT NULL" + , ");" + ); + private static final Db_idx_itm + Idx_trg_ttl = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS redirect__trg_ttl ON redirect (trg_ttl);") + , Idx_trg_id = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS redirect__trg_id ON redirect (trg_id);") + , Idx_trg_src = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS redirect__trg_src ON redirect (src_id, trg_id);") + ; + public static final String + Sql_ddl__page_redirect_id = "ALTER TABLE page ADD COLUMN page_redirect_id integer NOT NULL DEFAULT '-1'" + ; + private static final String + Sql_get_page_data = String_.Concat_lines_nl // get data from page table for initial redirect dump + ( "REPLACE INTO redirect " + , "SELECT t.src_id" + , ", t.src_ttl" + , ", j.page_id" + , ", t.trg_ns" + , ", t.trg_ttl" + , ", t.trg_anchor" + , ", j.page_is_redirect" + , ", t.redirect_count" + , "FROM redirect t" + , " JOIN page_db.page j " + , " ON t.trg_ns = j.page_namespace" + , " AND t.trg_ttl = j.page_title" + , " AND t.trg_is_redirect = 1 -- limit to redirects" + , ";" + ) + , Sql_get_redirect_redirects = String_.Concat_lines_nl // find redirects that are redirected + ( "REPLACE INTO redirect" + , "SELECT t.src_id" + , ", t.src_ttl" + , ", j.trg_id" + , ", -1" + , ", ''" + , ", ''" + , ", 1" + , ", t.redirect_count + 1" + , "FROM redirect t" + , " JOIN redirect j " + , " ON t.trg_id = j.src_id" + , " AND t.trg_is_redirect = 1" + , ";" + , "" + ) + , Sql_get_redirect_page_data = String_.Concat_lines_nl // get data from page table for redirected redirects + ( "REPLACE INTO redirect" + , "SELECT t.src_id" + , ", t.src_ttl" + , ", t.trg_id" + , ", j.page_namespace" + , ", j.page_title" + , ", t.trg_anchor" + , ", j.page_is_redirect" + , ", t.redirect_count" + , "FROM redirect t" + , " JOIN page_db.page j " + , " ON t.trg_id = j.page_id " + , " AND t.trg_is_redirect = 1 -- limit to redirects" + , ";" + ) + , Sql_update_redirect_id = String_.Concat_lines_nl_skip_last + ( "REPLACE INTO" + , " page_db.page" + , "SELECT p.page_id" + , ", p.page_namespace" + , ", p.page_title" + , ", p.page_is_redirect" + , ", p.page_touched" + , ", p.page_len" + , ", p.page_random_int" + , ", p.page_file_idx" +// , ", p.page_html_db_id" + , ", r.trg_id" + , "FROM redirect r" + , " JOIN page_db.page p ON r.src_id = p.page_id" + ) + ; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_wiki_redirect_tbl.java b/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_wiki_redirect_tbl.java deleted file mode 100644 index 46e7198aa..000000000 --- a/400_xowa/src/gplx/xowa/bldrs/wikis/redirects/Xob_wiki_redirect_tbl.java +++ /dev/null @@ -1,118 +0,0 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012 gnosygnu@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ -package gplx.xowa.bldrs.wikis.redirects; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wikis.*; -import gplx.dbs.*; import gplx.xowa.dbs.*; import gplx.xowa.bldrs.oimgs.*; -class Xob_wiki_redirect_tbl { - public Xob_wiki_redirect_tbl Create_table(Db_provider p) {Sqlite_engine_.Tbl_create(p, Tbl_name, Tbl_sql); return this;} - public void Create_indexes(Gfo_usr_dlg usr_dlg, Db_provider p) { - Sqlite_engine_.Idx_create(usr_dlg, p, Xodb_db_file.Name__wiki_redirect, Idx_trg_id, Idx_trg_ttl); - } - public void Update_redirects(Db_provider p, Io_url core_url, int max_redirected_depth) { - Sqlite_engine_.Db_attach(p, "join_db", core_url.Raw()); // link database with page table - p.Exec_sql(Sql_get_page_data); // fill in page_id, page_ns, page_is_redirect for trg_ttl; EX: Page_A has "#REDIRECT Page_B"; Page_B is in redirect tbl; find its id, ttl, redirect status - for (int i = 0; i < max_redirected_depth; i++) { // loop to find redirected redirects; note that it is bounded by depth (to guard against circular redirects) - int affected = p.Exec_sql(Sql_get_redirect_redirects); // find redirects that are also redirects - if (affected == 0) break; // no more redirected redirects; stop - p.Exec_sql(Sql_get_redirect_page_data); // get page data for redirects - } - Sqlite_engine_.Db_detach(p, "join_db"); - } - public Db_stmt Insert_stmt(Db_provider p) {return Db_stmt_.new_insert_(p, Tbl_name, Fld_src_id, Fld_src_ttl, Fld_trg_id, Fld_trg_ns, Fld_trg_ttl, Fld_trg_anchor, Fld_trg_is_redirect, Fld_redirect_count);} - public void Insert(Db_stmt stmt, int src_id, byte[] src_ttl, int trg_id, int trg_ns, byte[] trg_ttl, byte[] trg_anchor, int count) { - stmt.Clear() - .Val_int_(src_id) - .Val_str_by_bry_(src_ttl) - .Val_int_(trg_id) - .Val_int_(trg_ns) - .Val_str_by_bry_(trg_ttl) - .Val_str_by_bry_(trg_anchor) - .Val_byte_((byte)1) - .Val_int_(count) - .Exec_insert(); - } - public static final String Tbl_name = "redirect" - , Fld_src_id = "src_id", Fld_src_ttl = "src_ttl", Fld_trg_id = "trg_id", Fld_trg_ns = "trg_ns", Fld_trg_ttl = "trg_ttl", Fld_trg_anchor = "trg_anchor" - , Fld_trg_is_redirect = "trg_is_redirect", Fld_redirect_count = "redirect_count"; - private static final String Tbl_sql = String_.Concat_lines_nl - ( "CREATE TABLE IF NOT EXISTS redirect" - , "( src_id integer NOT NULL PRIMARY KEY" - , ", src_ttl varchar(255) NOT NULL" - , ", trg_id integer NOT NULL" - , ", trg_ns integer NOT NULL" - , ", trg_ttl varchar(255) NOT NULL" - , ", trg_anchor varchar(255) NOT NULL" - , ", trg_is_redirect tinyint NOT NULL" - , ", redirect_count integer NOT NULL" - , ");" - ); - private static final Db_idx_itm - Idx_trg_ttl = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS redirect__trg_ttl ON redirect (trg_ttl);") - , Idx_trg_id = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS redirect__trg_id ON redirect (trg_id);") - ; - private static final String - Sql_get_page_data = String_.Concat_lines_nl // get data from page table for initial redirect dump - ( "REPLACE INTO redirect " - , "SELECT t.src_id" - , ", t.src_ttl" - , ", j.page_id" - , ", t.trg_ns" - , ", t.trg_ttl" - , ", t.trg_anchor" - , ", j.page_is_redirect" - , ", t.redirect_count" - , "FROM redirect t" - , " JOIN join_db.page j " - , " ON t.trg_ns = j.page_namespace" - , " AND t.trg_ttl = j.page_title" - , " AND t.trg_is_redirect = 1 -- limit to redirects" - , ";" - ) - , Sql_get_redirect_redirects = String_.Concat_lines_nl // find redirects that are redirected - ( "REPLACE INTO redirect" - , "SELECT t.src_id" - , ", t.src_ttl" - , ", j.trg_id" - , ", -1" - , ", ''" - , ", ''" - , ", 1" - , ", t.redirect_count + 1" - , "FROM redirect t" - , " JOIN redirect j " - , " ON t.trg_id = j.src_id" - , " AND t.trg_is_redirect = 1" - , ";" - , "" - ) - , Sql_get_redirect_page_data = String_.Concat_lines_nl // get data from page table for redirected redirects - ( "REPLACE INTO redirect" - , "SELECT t.src_id" - , ", t.src_ttl" - , ", t.trg_id" - , ", j.page_namespace" - , ", j.page_title" - , ", t.trg_anchor" - , ", j.page_is_redirect" - , ", t.redirect_count" - , "FROM redirect t" - , " JOIN join_db.page j " - , " ON t.trg_id = j.page_id " - , " AND t.trg_is_redirect = 1 -- limit to redirects" - , ";" - ); -} diff --git a/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr.java b/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr.java index d6ceb4001..3fa232570 100644 --- a/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr.java +++ b/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr.java @@ -19,14 +19,14 @@ package gplx.xowa.ctgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.dbs.*; public class Xoctg_html_mgr implements GfoInvkAble { @gplx.Internal protected Xoctg_fmtr_grp Fmtr_grp() {return fmtr_grp;} private Xoctg_fmtr_grp fmtr_grp = new Xoctg_fmtr_grp(); - Xoctg_fmtr_all mgr_subcs = new Xoctg_fmtr_all(Xoa_ctg_mgr.Tid_subc); - Xoctg_fmtr_all mgr_pages = new Xoctg_fmtr_all(Xoa_ctg_mgr.Tid_page); - Xoctg_fmtr_all mgr_files = new Xoctg_fmtr_all(Xoa_ctg_mgr.Tid_file); + private final Xoctg_fmtr_all mgr_subcs = new Xoctg_fmtr_all(Xoa_ctg_mgr.Tid_subc); + private final Xoctg_fmtr_all mgr_pages = new Xoctg_fmtr_all(Xoa_ctg_mgr.Tid_page); + private final Xoctg_fmtr_all mgr_files = new Xoctg_fmtr_all(Xoa_ctg_mgr.Tid_file); public Xoctg_data_cache Data_cache() {return data_cache;} private Xoctg_data_cache data_cache = new Xoctg_data_cache(); public void Bld_html(Xoa_page page, Bry_bfr bfr) { - Bry_bfr tmp_bfr = page.Wiki().Utl_bry_bfr_mkr().Get_m001(); + Xow_wiki wiki = page.Wiki(); + Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_m001(); try { - Xow_wiki wiki = page.Wiki(); if (wiki.Db_mgr().Category_version() == Xoa_ctg_mgr.Version_2) Bld_html_v2(wiki, page, tmp_bfr); else diff --git a/400_xowa/src/gplx/xowa/dbs/Xodb_fsys_mgr.java b/400_xowa/src/gplx/xowa/dbs/Xodb_fsys_mgr.java index a20386e1d..709786503 100644 --- a/400_xowa/src/gplx/xowa/dbs/Xodb_fsys_mgr.java +++ b/400_xowa/src/gplx/xowa/dbs/Xodb_fsys_mgr.java @@ -87,6 +87,7 @@ public class Xodb_fsys_mgr { int file_idx = files_ary_len; Io_url url = Create_sqlite3(src_dir, trg_dir, wiki_name, file_idx); Xodb_file rv = Xodb_file.make_(file_idx, file_tid, url.NameAndExt()).Connect_(Db_conn_info_.sqlite_(url)); + rv.Url_(url); Xodb_xowa_cfg_tbl.Insert_str(rv.Provider(), Cfg_grp_db_meta, "type_name", Xodb_file_tid.Xto_key(file_tid)); files_ary = (Xodb_file[])Array_.Resize(files_ary, files_ary_len + 1); files_ary[files_ary_len++] = rv; diff --git a/400_xowa/src/gplx/xowa/gui/history/Xog_history_itm.java b/400_xowa/src/gplx/xowa/gui/history/Xog_history_itm.java index 2d6f3bf8d..d3754bffd 100644 --- a/400_xowa/src/gplx/xowa/gui/history/Xog_history_itm.java +++ b/400_xowa/src/gplx/xowa/gui/history/Xog_history_itm.java @@ -17,36 +17,26 @@ along with this program. If not, see . */ package gplx.xowa.gui.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*; public class Xog_history_itm { - public Xog_history_itm(Xoa_page page) { - this.wiki_key = page.Wiki().Domain_bry(); - this.page_key = page.Ttl().Full_url(); // get page_name only (no anchor; no query args) - this.anch_key = page.Url().Anchor_bry(); - this.qarg_key = page.Url().Args_all_as_bry(); - this.redirect_force = page.Url().Redirect_force() ? Bool_.Y_bry : Bool_.N_bry; - this.key = Xog_history_itm.Build_key(wiki_key, page_key, anch_key, qarg_key, redirect_force); - this.html_doc_pos = page.Html_data().Bmk_pos(); - if (this.html_doc_pos == null) - this.html_doc_pos = Html_doc_pos_toc; // never allow null doc_pos; set to top + private final boolean redirect_force; + public Xog_history_itm(byte[] wiki, byte[] page, byte[] anch, byte[] qarg, boolean redirect_force, String bmk_pos) { + this.key = Bry_.Add_w_dlm(Byte_ascii.Pipe, wiki, page, anch, qarg, redirect_force ? Bool_.Y_bry : Bool_.N_bry); + this.wiki = wiki; this.page = page; this.anch = anch; this.qarg = qarg; + this.redirect_force = redirect_force; this.bmk_pos = bmk_pos; } - public byte[] Key() {return key;} private byte[] key; - public byte[] Wiki_key() {return wiki_key;} private byte[] wiki_key; - public byte[] Page_key() {return page_key;} private byte[] page_key; - public byte[] Anch_key() {return anch_key;} private byte[] anch_key; - public byte[] Qarg_key() {return qarg_key;} private byte[] qarg_key; - public byte[] Redirect_force() {return redirect_force;} private byte[] redirect_force; - public String Html_doc_pos() {return html_doc_pos;} private String html_doc_pos; - public void Html_doc_pos_(String v) {html_doc_pos = v;} - public boolean Eq_except_bmk(Xog_history_itm comp) { - return Bry_.Eq(wiki_key, comp.Wiki_key()) - && Bry_.Eq(page_key, comp.Page_key()) - && Bry_.Eq(anch_key, comp.Anch_key()) - && Bry_.Eq(qarg_key, comp.Qarg_key()) - && Bry_.Eq(redirect_force, comp.Redirect_force()) + public byte[] Key() {return key;} private final byte[] key; + public byte[] Wiki() {return wiki;} private final byte[] wiki; + public byte[] Page() {return page;} private final byte[] page; + public byte[] Anch() {return anch;} private final byte[] anch; + public byte[] Qarg() {return qarg;} private final byte[] qarg; + public String Bmk_pos() {return bmk_pos;} public void Bmk_pos_(String v) {bmk_pos = v;} private String bmk_pos; + public boolean Eq_wo_bmk_pos(Xog_history_itm comp) { + return Bry_.Eq(wiki, comp.wiki) + && Bry_.Eq(page, comp.page) + && Bry_.Eq(anch, comp.anch) + && Bry_.Eq(qarg, comp.qarg) + && redirect_force == comp.redirect_force ; } - public static byte[] Build_key(byte[] wiki_key, byte[] page_key, byte[] anch_key, byte[] qarg_key, byte[] redirect_force) { - return Bry_.Add_w_dlm(Byte_ascii.Pipe, wiki_key, page_key, anch_key, qarg_key, redirect_force); - } public static final String Html_doc_pos_toc = "top"; - public static final Xog_history_itm Null = new Xog_history_itm(); private Xog_history_itm() {} + public static final Xog_history_itm Null = new Xog_history_itm(null, null, null, null, false, null); } diff --git a/400_xowa/src/gplx/xowa/gui/history/Xog_history_mgr.java b/400_xowa/src/gplx/xowa/gui/history/Xog_history_mgr.java index 1587c223c..6d78aa543 100644 --- a/400_xowa/src/gplx/xowa/gui/history/Xog_history_mgr.java +++ b/400_xowa/src/gplx/xowa/gui/history/Xog_history_mgr.java @@ -17,37 +17,61 @@ along with this program. If not, see . */ package gplx.xowa.gui.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*; public class Xog_history_mgr { - private OrderedHash hash = OrderedHash_.new_bry_(); - private Xog_history_stack itm_stack = new Xog_history_stack(); + private final OrderedHash hash = OrderedHash_.new_bry_(); private final Xog_history_stack stack = new Xog_history_stack(); public int Count() {return hash.Count();} + public Xoa_page Cur_page(Xow_wiki wiki) {return Get_or_fetch(wiki, stack.Cur_itm());} + public Xoa_page Go_bwd(Xow_wiki wiki) {return Go_by_dir(wiki, Bool_.N);} + public Xoa_page Go_fwd(Xow_wiki wiki) {return Go_by_dir(wiki, Bool_.Y);} + public Xoa_page Go_by_dir(Xow_wiki wiki, boolean fwd) { + Xog_history_itm itm = fwd ? stack.Go_fwd() : stack.Go_bwd(); + if (itm == Xog_history_itm.Null) return Xoa_page.Empty; + Xoa_page rv = Get_or_fetch(wiki, itm); + byte[] anch_key = itm.Anch(); + rv.Url().Anchor_bry_(anch_key); // must override anchor as it may be different for cached page + rv.Html_data().Bmk_pos_(itm.Bmk_pos()); + return rv; + } public void Add(Xoa_page page) { - itm_stack.Add(page); + Xog_history_itm new_itm = Xog_history_mgr.new_(page); + stack.Add(new_itm); byte[] page_key = Build_page_key(page); if (!hash.Has(page_key)) hash.Add(page_key, page); } public void Update_html_doc_pos(Xoa_page page, byte history_nav_type) { - itm_stack.Update_html_doc_pos(page, history_nav_type); + Xog_history_itm itm = Get_recent(page, history_nav_type); + if (itm != null) itm.Bmk_pos_(page.Html_data().Bmk_pos()); } - public Xoa_page Cur_page(Xow_wiki wiki) {return Get_or_fetch(wiki, itm_stack.Cur_itm());} - public Xoa_page Go_bwd(Xow_wiki wiki) {return Go_by_dir(wiki, Bool_.N);} - public Xoa_page Go_fwd(Xow_wiki wiki) {return Go_by_dir(wiki, Bool_.Y);} - public Xoa_page Go_by_dir(Xow_wiki wiki, boolean fwd) { - Xog_history_itm itm = fwd ? itm_stack.Go_fwd() : itm_stack.Go_bwd(); - if (itm == Xog_history_itm.Null) return Xoa_page.Empty; - Xoa_page rv = Get_or_fetch(wiki, itm); - byte[] anch_key = itm.Anch_key(); - rv.Url().Anchor_bry_(anch_key); // must override anchor as it may be different for cached page - rv.Html_data().Bmk_pos_(itm.Html_doc_pos()); - return rv; + private Xog_history_itm Get_recent(Xoa_page page, byte history_nav_type) { + int pos = -1; + int list_pos = stack.Cur_pos(); + switch (history_nav_type) { + case Xog_history_stack.Nav_fwd: pos = list_pos - 1; break; + case Xog_history_stack.Nav_bwd: pos = list_pos + 1; break; + case Xog_history_stack.Nav_by_anchor: pos = list_pos; break; + } + if (pos < 0 || pos >= stack.Len()) return null; + Xog_history_itm recent = stack.Get_at(pos); + Xog_history_itm page_itm = Xog_history_mgr.new_(page); + return page_itm.Eq_wo_bmk_pos(recent) ? recent : null; // check that recent page actually matches current; DATE:2014-05-10 } private Xoa_page Get_or_fetch(Xow_wiki wiki, Xog_history_itm itm) { - byte[] page_key = Build_page_key(itm.Wiki_key(), itm.Page_key(), itm.Qarg_key()); + byte[] page_key = Build_page_key(itm.Wiki(), itm.Page(), itm.Qarg()); Xoa_page rv = (Xoa_page)hash.Fetch(page_key); if (rv != null) return rv; - Xoa_ttl ttl = Xoa_ttl.parse_(wiki, itm.Page_key()); + Xoa_ttl ttl = Xoa_ttl.parse_(wiki, itm.Page()); return wiki.Data_mgr().Get_page(ttl, false); } private static byte[] Build_page_key(Xoa_page page) {return Build_page_key(page.Wiki().Domain_bry(), page.Ttl().Full_url(), page.Url().Args_all_as_bry());} private static byte[] Build_page_key(byte[] wiki_key, byte[] page_key, byte[] args_key) {return Bry_.Add_w_dlm(Byte_ascii.Pipe, wiki_key, page_key, args_key);} + public static Xog_history_itm new_(Xoa_page pg) { + byte[] wiki = pg.Wiki().Domain_bry(); + byte[] page = pg.Ttl().Full_url(); // get page_name only (no anchor; no query args) + byte[] anch = pg.Url().Anchor_bry(); + byte[] qarg = pg.Url().Args_all_as_bry(); + boolean redirect_force = pg.Url().Redirect_force(); + String bmk_pos = pg.Html_data().Bmk_pos(); + if (bmk_pos == null) bmk_pos = Xog_history_itm.Html_doc_pos_toc; // never allow null doc_pos; set to top + return new Xog_history_itm(wiki, page, anch, qarg, redirect_force, bmk_pos); + } } diff --git a/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack.java b/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack.java index b8778de05..7b25c987b 100644 --- a/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack.java +++ b/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack.java @@ -17,56 +17,36 @@ along with this program. If not, see . */ package gplx.xowa.gui.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*; public class Xog_history_stack { - private ListAdp list = ListAdp_.new_(); - public int Stack_pos() {return list_pos;} private int list_pos = 0; - public int Count() {return list.Count();} - public void Clear() {list.Clear(); list_pos = 0;} - public Xog_history_itm Cur_itm() {return list.Count() == 0 ? Xog_history_itm.Null : (Xog_history_itm)list.FetchAt(list_pos);} - public Xog_history_itm Add(Xoa_page page) { - Xog_history_itm new_itm = new Xog_history_itm(page); + private final ListAdp list = ListAdp_.new_(); + public int Len() {return list.Count();} + public void Clear() {list.Clear(); cur_pos = 0;} + public Xog_history_itm Get_at(int i) {return (Xog_history_itm)list.FetchAt(i);} + public int Cur_pos() {return cur_pos;} private int cur_pos = 0; + public Xog_history_itm Cur_itm() {return list.Count() == 0 ? Xog_history_itm.Null : (Xog_history_itm)list.FetchAt(cur_pos);} + public void Add(Xog_history_itm new_itm) { Xog_history_itm cur_itm = this.Cur_itm(); - if ( cur_itm != Xog_history_itm.Null - && cur_itm.Eq_except_bmk(new_itm) - ) - return Xog_history_itm.Null; // do not add if last itm is same; - Del_all_from(list_pos + 1); + if (cur_itm != Xog_history_itm.Null && cur_itm.Eq_wo_bmk_pos(new_itm)) return; // do not add if last itm is same; + this.Del_from(cur_pos + 1); list.Add(new_itm); - list_pos = list.Count() - 1; - return new_itm; - } - public void Update_html_doc_pos(Xoa_page page, byte history_nav_type) { - Xog_history_itm itm = Get_recent(page, history_nav_type); - if (itm != null) itm.Html_doc_pos_(page.Html_data().Bmk_pos()); - } - private Xog_history_itm Get_recent(Xoa_page page, byte history_nav_type) { - int pos = -1; - switch (history_nav_type) { - case Xog_history_stack.Nav_fwd: pos = list_pos - 1; break; - case Xog_history_stack.Nav_bwd: pos = list_pos + 1; break; - case Xog_history_stack.Nav_by_anchor: pos = list_pos; break; - } - if (pos < 0 || pos >= list.Count()) return null; - Xog_history_itm recent = (Xog_history_itm)list.FetchAt(pos); - Xog_history_itm page_itm = new Xog_history_itm(page); - return page_itm.Eq_except_bmk(recent) ? recent : null; // check that recent page actually matches current; DATE:2014-05-10 + cur_pos = list.Count() - 1; } public Xog_history_itm Go_bwd() { if (list.Count() == 0) return Xog_history_itm.Null; - --list_pos; - if (list_pos < 0) list_pos = 0; + --cur_pos; + if (cur_pos < 0) cur_pos = 0; return this.Cur_itm(); } public Xog_history_itm Go_fwd() { int list_count = list.Count(); if (list_count == 0) return Xog_history_itm.Null; - ++list_pos; - if (list_pos == list_count) list_pos = list_count - 1; + ++cur_pos; + if (cur_pos == list_count) cur_pos = list_count - 1; return this.Cur_itm(); } - private void Del_all_from(int from) { - int list_count = list.Count(); - if (from <= list_count - 1) - list.Del_range(from, list_count - 1); + private void Del_from(int from) { + int len = list.Count(); + if (from <= len - 1) + list.Del_range(from, len - 1); } public static final byte Nav_fwd = 1, Nav_bwd = 2, Nav_by_anchor = 3; } diff --git a/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack_tst.java b/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack_tst.java index 6382020f7..1a6c30d81 100644 --- a/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack_tst.java +++ b/400_xowa/src/gplx/xowa/gui/history/Xog_history_stack_tst.java @@ -50,13 +50,13 @@ class Xog_history_stack_fxt { } private Xoa_app app; private Xow_wiki wiki; private Xog_history_stack stack = new Xog_history_stack(); private Xoa_url_parser url_parser; public Xog_history_stack_fxt Test_cur(String expd) { Xog_history_itm page = stack.Cur_itm(); - String actl = page == null ? null : String_.new_utf8_(page.Page_key()); + String actl = page == null ? null : String_.new_utf8_(page.Page()); Tfds.Eq(expd, actl, "cur"); return this; } public Xog_history_stack_fxt Test_cur_qargs(String expd) { Xog_history_itm page = stack.Cur_itm(); - String actl = page == null ? null : String_.new_utf8_(page.Qarg_key()); + String actl = page == null ? null : String_.new_utf8_(page.Qarg()); Tfds.Eq(expd, actl, "cur_qargs"); return this; } @@ -78,9 +78,9 @@ class Xog_history_stack_fxt { if (arg_str != null) url_bry = Bry_.Add(url_bry, Bry_.new_utf8_(arg_str)); Xoa_url url = url_parser.Parse(url_bry); page.Url_(url); // set url b/c history_mgr.Add uses url - stack.Add(page); + stack.Add(Xog_history_mgr.new_(page)); return this; } - public Xog_history_stack_fxt Test_pos(int expd) {Tfds.Eq(expd, stack.Stack_pos(), "pos"); return this;} - public Xog_history_stack_fxt Test_len(int expd) {Tfds.Eq(expd, stack.Count(), "len"); return this;} + public Xog_history_stack_fxt Test_pos(int expd) {Tfds.Eq(expd, stack.Cur_pos(), "pos"); return this;} + public Xog_history_stack_fxt Test_len(int expd) {Tfds.Eq(expd, stack.Len(), "len"); return this;} } diff --git a/400_xowa/src/gplx/xowa/hdumps/Xob_hdump_bldr.java b/400_xowa/src/gplx/xowa/hdumps/Xob_hdump_bldr.java index 3cbf46394..20f5fdc18 100644 --- a/400_xowa/src/gplx/xowa/hdumps/Xob_hdump_bldr.java +++ b/400_xowa/src/gplx/xowa/hdumps/Xob_hdump_bldr.java @@ -67,16 +67,17 @@ public class Xob_hdump_bldr { } private static void Db_init(Db_provider p) {p.Exec_sql(Hdump_text_tbl.Tbl_sql);} private static void Db_term(Xodb_file core_db_file, Db_provider hdump_db_provider, int hdump_db_id) { - hdump_db_provider.Txn_mgr().Txn_end(); + hdump_db_provider.Txn_mgr().Txn_end_all(); Sqlite_engine_.Idx_create(hdump_db_provider, Hdump_text_tbl.Idx_core); Sqlite_engine_.Db_attach(hdump_db_provider, "page_db", core_db_file.Url().Raw()); + hdump_db_provider.Txn_mgr().Txn_bgn(); hdump_db_provider.Exec_sql(String_.Format(Sql_update_page, hdump_db_id)); // update all page_html_db_id entries in page_db + hdump_db_provider.Txn_mgr().Txn_end(); Sqlite_engine_.Db_detach(hdump_db_provider, "page_db"); - hdump_db_provider.Txn_mgr().Txn_end_all(); } private static final String Cfg_grp_hdump_make = "hdump.make", Cfg_itm_hdump_size = "hdump.size"; private static final String Sql_update_page = String_.Concat_lines_nl_skip_last - ( "REPLACE INTO page_db.page" + ( "REPLACE INTO page_db.page (page_id, page_namespace, page_title, page_is_redirect, page_touched, page_len, page_random_int, page_file_idx, page_redirect_id, page_html_db_id)" , "SELECT p.page_id" , ", p.page_namespace" , ", p.page_title" @@ -85,6 +86,7 @@ public class Xob_hdump_bldr { , ", p.page_len" , ", p.page_random_int" , ", p.page_file_idx" + , ", p.page_redirect_id" , ", {0}" , "FROM page_db.page p" , " JOIN html_text h ON p.page_id = h.page_id" diff --git a/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr.java b/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr.java index 93ef5446c..df93090a5 100644 --- a/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr.java +++ b/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr.java @@ -61,8 +61,8 @@ public class Xodb_hdump_mgr { public void Load(Xow_wiki wiki, Xoa_page page, int html_db_id) { if (!Enabled_chk()) return; page.Root_(new Xop_root_tkn()); - Hdump_page hpg = new Hdump_page().Init(page.Revision_data().Id(), page.Url()); - load_mgr.Load(hpg, wiki.Db_mgr_as_sql().Fsys_mgr(), html_db_id, page.Revision_data().Id()); + Hdump_page hpg = new Hdump_page().Init(page.Revision_data().Id(), page.Url(), page.Ttl()); + load_mgr.Load(hpg, wiki.Db_mgr_as_sql().Fsys_mgr(), html_db_id, page.Revision_data().Id(), page.Ttl()); Load_page(wiki, page, hpg); } private void Load_page(Xow_wiki wiki, Xoa_page page, Hdump_page hpg) { diff --git a/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr_setup.java b/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr_setup.java index 9fbbe09f4..ab90fa432 100644 --- a/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr_setup.java +++ b/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr_setup.java @@ -38,7 +38,6 @@ public class Xodb_hdump_mgr_setup { if (String_.Eq(val, "y")) return; try { core_provider.Exec_sql(Sql_ddl__page_html_db_id); - core_provider.Exec_sql(Sql_ddl__page_redirect_id); cfg_tbl.Insert_str(Xodb_fsys_mgr.Cfg_grp_db_meta, Cfg_itm_html_db_exists, "y"); } catch (Exception e) {Gfo_usr_dlg_._.Warn_many("", "", "failed to update core: db=~{0} err=~{1}", core_provider.Conn_info().Str_raw(), Err_.Message_gplx(e));} } @@ -52,8 +51,7 @@ public class Xodb_hdump_mgr_setup { Sqlite_engine_.Idx_create(html_db_file.Provider(), Hdump_text_tbl.Idx_core); } private static final String Cfg_itm_html_db_exists = "html_db.exists"; - private static final String + public static final String Sql_ddl__page_html_db_id = "ALTER TABLE page ADD COLUMN page_html_db_id integer NOT NULL DEFAULT '-1'" - , Sql_ddl__page_redirect_id = "ALTER TABLE page ADD COLUMN page_redirect_id integer NOT NULL DEFAULT '-1'" ; } diff --git a/400_xowa/src/gplx/xowa/hdumps/Xogv_tab_base.java b/400_xowa/src/gplx/xowa/hdumps/Xogv_tab_base.java new file mode 100644 index 000000000..16b8738d0 --- /dev/null +++ b/400_xowa/src/gplx/xowa/hdumps/Xogv_tab_base.java @@ -0,0 +1,52 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.hdumps; import gplx.*; import gplx.xowa.*; +import gplx.xowa.hdumps.core.*; import gplx.xowa.gui.history.*; +public abstract class Xogv_tab_base { + private Xog_history_stack history_stack = new Xog_history_stack(); + private Xoav_wiki_mgr wiki_mgr; + public void Ctor(Xoav_wiki_mgr wiki_mgr) {this.wiki_mgr = wiki_mgr;} + public Xog_history_itm Cur_itm() {return history_stack.Cur_itm();} + public Hdump_page Go_to(byte[] page) {return Go_to(history_stack.Cur_itm().Wiki(), page, Bry_.Empty, Bry_.Empty, false, "");} + public Hdump_page Go_to(byte[] wiki, byte[] page) {return Go_to(wiki, page, Bry_.Empty, Bry_.Empty, false, "");} + public Hdump_page Go_to(byte[] wiki, byte[] page, byte[] anch, byte[] qarg, boolean redirect_force, String bmk_pos) { + Xog_history_itm old_itm = this.Cur_itm(); + Xog_history_itm new_itm = new Xog_history_itm(wiki, page, anch, qarg, redirect_force, bmk_pos); + history_stack.Add(new_itm); + return Fetch_page_and_show(old_itm, new_itm); + } + public Hdump_page Go_bwd() {return Go_by_dir(Bool_.Y);} + public Hdump_page Go_fwd() {return Go_by_dir(Bool_.N);} + private Hdump_page Go_by_dir(boolean bwd) { + Xog_history_itm old_itm = this.Cur_itm(); + Xog_history_itm new_itm = bwd ? history_stack.Go_bwd() : history_stack.Go_fwd(); + return Fetch_page_and_show(old_itm, new_itm); + } + private Hdump_page Fetch_page_and_show(Xog_history_itm old_itm, Xog_history_itm new_itm) { + Hdump_page new_hpg = Fetch_page(new_itm.Wiki(), new_itm.Page()); + Show_page(old_itm, new_itm, new_hpg); + return new_hpg; + } + private Hdump_page Fetch_page(byte[] wiki_domain, byte[] page_ttl) { + Xowv_wiki wiki = wiki_mgr.Get_by_domain(wiki_domain); + Hdump_page rv = new Hdump_page(); + wiki.Hdump_mgr().Load(rv, page_ttl); + return rv; + } + protected abstract void Show_page(Xog_history_itm old_itm, Xog_history_itm new_itm, Hdump_page new_hpg); +} diff --git a/400_xowa/src/gplx/xowa/hdumps/Xowd_hdump_mgr.java b/400_xowa/src/gplx/xowa/hdumps/Xowd_hdump_mgr.java index b48ca1533..877b04114 100644 --- a/400_xowa/src/gplx/xowa/hdumps/Xowd_hdump_mgr.java +++ b/400_xowa/src/gplx/xowa/hdumps/Xowd_hdump_mgr.java @@ -20,7 +20,7 @@ import gplx.intl.*; import gplx.dbs.*; import gplx.xowa.hdumps.core.*; import gplx.xowa.hdumps.loads.*; import gplx.xowa.hdumps.htmls.*; import gplx.xowa.apps.fsys.*; public class Xowd_hdump_mgr { private final Xoav_app app; private final Xowv_wiki wiki; private final Xowv_db_mgr wiki_db_mgr; - private Xodb_page dbpg = new Xodb_page(); private Hdump_page hpg = new Hdump_page(); + private Xodb_page dbpg = new Xodb_page(); private Hdump_load_mgr load_mgr = new Hdump_load_mgr(); private Hdump_html_body html_body = new Hdump_html_body(); public Xowd_hdump_mgr(Xoav_app app, Xowv_wiki wiki) { @@ -31,9 +31,9 @@ public class Xowd_hdump_mgr { Xoa_ttl ttl = wiki.Ttl_parse(ttl_bry); wiki_db_mgr.Tbl_mgr().Tbl__page().Select_by_ttl(dbpg, app.Db_mgr().Get(wiki_db_mgr.Key__core()), ttl.Ns(), ttl.Page_db()); if (dbpg.Html_db_id() == -1) return; // should return "not found" message - load_mgr.Load2(hpg, app.Db_mgr().Get(wiki_db_mgr.Key_by_idx(dbpg.Html_db_id())), dbpg.Id()); + load_mgr.Load2(rv, app.Db_mgr().Get(wiki_db_mgr.Key_by_idx(dbpg.Html_db_id())), dbpg.Id(), ttl); Bry_bfr bfr = app.Utl_bfr_mkr().Get_m001(); - html_body.Init_by_page(wiki.Domain_bry(), hpg).Write(bfr); + html_body.Init_by_page(wiki.Domain_bry(), rv).Write(bfr); rv.Page_body_(bfr.Mkr_rls().Xto_bry_and_clear()); } } diff --git a/400_xowa/src/gplx/xowa/hdumps/core/Hdump_page.java b/400_xowa/src/gplx/xowa/hdumps/core/Hdump_page.java index 9f4df39d9..fa3caced0 100644 --- a/400_xowa/src/gplx/xowa/hdumps/core/Hdump_page.java +++ b/400_xowa/src/gplx/xowa/hdumps/core/Hdump_page.java @@ -19,6 +19,7 @@ package gplx.xowa.hdumps.core; import gplx.*; import gplx.xowa.*; import gplx.xo public class Hdump_page { public int Page_id() {return page_id;} private int page_id; public Xoa_url Page_url() {return page_url;} private Xoa_url page_url; + public Xoa_ttl Page_ttl() {return page_ttl;} private Xoa_ttl page_ttl; public int Version_id() {return version_id;} public void Version_id_(int v) {version_id = v;} private int version_id; public int Img_count() {return img_count;} public void Img_count_(int v) {img_count = v;} private int img_count; public Hdump_module_mgr Module_mgr() {return module_mgr;} private Hdump_module_mgr module_mgr = new Hdump_module_mgr(); @@ -29,9 +30,8 @@ public class Hdump_page { public int[] Redlink_uids() {return redlink_uids;} public void Redlink_uids_(int[] v) {redlink_uids = v;} private int[] redlink_uids; public Hdump_data_img__base[] Img_itms() {return img_itms;} public void Img_itms_(Hdump_data_img__base[] v) {this.img_itms = v;} private Hdump_data_img__base[] img_itms; public OrderedHash Gly_itms() {return gly_itms;} private OrderedHash gly_itms = OrderedHash_.new_(); - public Hdump_page Init(int page_id, Xoa_url page_url) { - this.page_id = page_id; - this.page_url = page_url; + public Hdump_page Init(int page_id, Xoa_url page_url, Xoa_ttl page_ttl) { + this.page_id = page_id; this.page_url = page_url; this.page_ttl = page_ttl; content_sub = sidebar_div = Bry_.Empty; display_ttl = null; img_itms = Hdump_data_img__base.Ary_empty; diff --git a/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl.java b/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl.java index aeccac626..9e711baf3 100644 --- a/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl.java +++ b/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl.java @@ -28,10 +28,13 @@ public class Hdump_text_tbl { try {stmt_delete.Clear().Val_int_(page_id).Exec_delete();} catch (Exception exc) {stmt_delete = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail } - @gplx.Virtual public void Insert(int page_id, int tid, byte[] data) { + @gplx.Virtual public int Insert(int page_id, int tid, byte[] data) { if (stmt_insert == null) stmt_insert = Db_stmt_.new_insert_(provider, Tbl_name, Flds_all); if (zip_mgr != null) data = zip_mgr.Zip(db_mgr.Data_storage_format(), data); - try {stmt_insert.Clear().Val_int_(page_id).Val_int_(tid).Val_str_by_bry_(data).Exec_insert();} + try { + stmt_insert.Clear().Val_int_(page_id).Val_int_(tid).Val_str_by_bry_(data).Exec_insert(); + return data.length; + } catch (Exception exc) {stmt_insert = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail } private static final String[] Select_by_page_flds = new String[] {Fld_page_id, Fld_text_tid, Fld_text_data}; diff --git a/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl_mem.java b/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl_mem.java index c7bb2590d..89b4a9e50 100644 --- a/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl_mem.java +++ b/400_xowa/src/gplx/xowa/hdumps/dbs/Hdump_text_tbl_mem.java @@ -18,10 +18,11 @@ along with this program. If not, see . package gplx.xowa.hdumps.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.hdumps.*; import gplx.dbs.*; public class Hdump_text_tbl_mem extends Hdump_text_tbl { private HashAdp pages = HashAdp_.new_(); - @Override public void Insert(int page_id, int tid, byte[] data) { + @Override public int Insert(int page_id, int tid, byte[] data) { Hdump_text_row row = new Hdump_text_row(page_id, tid, data); ListAdp rows = Get_or_new(pages, page_id); rows.Add(row); + return data.length; } @Override public void Select_by_page(ListAdp rv, int page_id) { ListAdp rows = Get_or_new(pages, page_id); diff --git a/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr.java b/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr.java index 4c14101fa..44318f30c 100644 --- a/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr.java +++ b/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr.java @@ -23,17 +23,17 @@ public class Hdump_load_mgr { private ListAdp tmp_rows = ListAdp_.new_(), img_itms = ListAdp_.new_(); public Hdump_load_mgr() {} public byte Zip_tid() {return zip_tid;} public void Zip_tid_(byte v) {zip_tid = v;} private byte zip_tid = gplx.ios.Io_stream_.Tid_file; - public void Load2(Hdump_page hpg, Db_provider provider, int page_id) { + public void Load2(Hdump_page hpg, Db_provider provider, int page_id, Xoa_ttl page_ttl) { text_tbl.Provider_(provider).Select_by_page(tmp_rows, page_id); - Load_rows(hpg, page_id, Xoa_url.blank_(), tmp_rows); + Load_rows(hpg, page_id, Xoa_url.blank_(), page_ttl, tmp_rows); } - public void Load(Hdump_page hpg, Xodb_fsys_mgr db_fsys_mgr, int html_db_id, int page_id) { + public void Load(Hdump_page hpg, Xodb_fsys_mgr db_fsys_mgr, int html_db_id, int page_id, Xoa_ttl page_ttl) { Db_provider provider = db_fsys_mgr.Get_by_idx(html_db_id).Provider(); text_tbl.Provider_(provider).Select_by_page(tmp_rows, page_id); - Load_rows(hpg, page_id, hpg.Page_url(), tmp_rows); + Load_rows(hpg, page_id, hpg.Page_url(), page_ttl, tmp_rows); } - public void Load_rows(Hdump_page hpg, int page_id, Xoa_url page_url, ListAdp rows) { - hpg.Init(page_id, page_url); + public void Load_rows(Hdump_page hpg, int page_id, Xoa_url page_url, Xoa_ttl page_ttl, ListAdp rows) { + hpg.Init(page_id, page_url, page_ttl); img_itms.Clear(); int len = rows.Count(); for (int i = 0; i < len; ++i) { diff --git a/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr_tst.java b/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr_tst.java index 3353b4134..5187f49eb 100644 --- a/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/hdumps/loads/Hdump_load_mgr_tst.java @@ -87,7 +87,7 @@ class Hdump_load_mgr_fxt { public Hdump_load_mgr_fxt Expd_sidebar_div(String v) {this.expd_sidebar_div = v; return this;} public Hdump_load_mgr_fxt Expd_img(Hdump_data_img__base img) {expd_imgs.Add(img); return this;} public Hdump_load_mgr_fxt Test_load(int page_id) { - load_mgr.Load_rows(hpg, page_id, page_url, init_rows); + load_mgr.Load_rows(hpg, page_id, page_url, Xoa_ttl.Null, init_rows); if (expd_body != null) Tfds.Eq(expd_body, String_.new_utf8_(hpg.Page_body())); if (expd_display_ttl != null) Tfds.Eq(expd_display_ttl, String_.new_utf8_(hpg.Display_ttl())); if (expd_content_sub != null) Tfds.Eq(expd_content_sub, String_.new_utf8_(hpg.Content_sub())); diff --git a/400_xowa/src/gplx/xowa/hdumps/saves/Hdump_save_mgr.java b/400_xowa/src/gplx/xowa/hdumps/saves/Hdump_save_mgr.java index 220e1cf63..b0777eb05 100644 --- a/400_xowa/src/gplx/xowa/hdumps/saves/Hdump_save_mgr.java +++ b/400_xowa/src/gplx/xowa/hdumps/saves/Hdump_save_mgr.java @@ -37,8 +37,7 @@ public class Hdump_save_mgr { public int Insert_body(Xoa_page page, int page_id) { Hdump_page_body_srl.Save(tmp_bfr, page); byte[] body_bry = tmp_bfr.Xto_bry_and_clear(); - text_tbl.Insert(page_id, Hdump_text_row_tid.Tid_body, body_bry); - return body_bry.length; + return text_tbl.Insert(page_id, Hdump_text_row_tid.Tid_body, body_bry); } public static byte[] Write_imgs(Bry_bfr bfr, ListAdp imgs) { int len = imgs.Count(); if (len == 0) return null; // no images; exit early, else will write blank String diff --git a/400_xowa/src/gplx/xowa/html/Xoh_page_wtr_wkr.java b/400_xowa/src/gplx/xowa/html/Xoh_page_wtr_wkr.java index b2e6954b3..7a9102377 100644 --- a/400_xowa/src/gplx/xowa/html/Xoh_page_wtr_wkr.java +++ b/400_xowa/src/gplx/xowa/html/Xoh_page_wtr_wkr.java @@ -129,7 +129,11 @@ public class Xoh_page_wtr_wkr implements Bry_fmtr_arg { if (ns_id == Xow_ns_.Id_category) // if Category, render rest of html (Subcategories; Pages; Files); note that a category may have other html which requires wikitext processing wiki.Html_mgr().Ns_ctg().Bld_html(page, bfr); int ctgs_len = page.Category_list().length; // add Categories - if (ctgs_enabled && ctgs_len > 0) { + + if ( ctgs_enabled + && ctgs_len > 0 + && !wiki.Html_mgr().Importing_ctgs() // do not show categories if importing categories, page will wait for category import to be done; DATE:2014-10-15 + ) { app.Usr_dlg().Prog_many("", "", "loading categories: count=~{0}", ctgs_len); if (app.Ctg_mgr().Pagecats_grouping_enabled()) app.Ctg_mgr().Pagectgs_wtr().Write(bfr, wiki, page); diff --git a/400_xowa/src/gplx/xowa/html/Xow_html_mgr.java b/400_xowa/src/gplx/xowa/html/Xow_html_mgr.java index e8949e737..55e168802 100644 --- a/400_xowa/src/gplx/xowa/html/Xow_html_mgr.java +++ b/400_xowa/src/gplx/xowa/html/Xow_html_mgr.java @@ -46,6 +46,7 @@ public class Xow_html_mgr implements GfoInvkAble { public Xow_portal_mgr Portal_mgr() {return portal_mgr;} private Xow_portal_mgr portal_mgr; public Xow_toc_mgr Toc_mgr() {return toc_mgr;} private Xow_toc_mgr toc_mgr = new Xow_toc_mgr(); public Xow_module_mgr Module_mgr() {return module_mgr;} private Xow_module_mgr module_mgr; + public boolean Importing_ctgs() {return importing_ctgs;} public void Importing_ctgs_(boolean v) {importing_ctgs = v;} private boolean importing_ctgs; public int Img_thumb_width() {return img_thumb_width;} private int img_thumb_width = 220; public byte[] Img_media_play_btn() {return img_media_play_btn;} private byte[] img_media_play_btn; public byte[] Img_media_info_btn() {return img_media_info_btn;} private byte[] img_media_info_btn; diff --git a/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_.java b/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_.java index 2d1f185f4..91b7d19f2 100644 --- a/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_.java +++ b/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_.java @@ -88,7 +88,7 @@ class Xop_vnt_lxr_end implements Xop_lxr { catch (Exception e) { ctx.App().Usr_dlg().Warn_many("", "", "vnt.parse failed: page=~{0} src=~{1} err=~{2}", String_.new_utf8_(ctx.Cur_page().Ttl().Raw()), String_.new_utf8_(src, bgn_pos, cur_pos), Err_.Message_gplx_brief(e)); if (vnt_tkn != null) - root.Subs_add(tkn_mkr.Bry(src, vnt_tkn.Src_bgn(), cur_pos)); + root.Subs_add(tkn_mkr.Bry_mid(src, vnt_tkn.Src_bgn(), cur_pos)); } return cur_pos; } diff --git a/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rules_parser.java b/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rules_parser.java index b7d7d0168..eee0dae4d 100644 --- a/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rules_parser.java +++ b/400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rules_parser.java @@ -155,7 +155,7 @@ class Xop_vnt_rules_parser { case Xop_vnt_rule_trie_itm.Tid_semic: switch (mode) { case Mode_text: - text_tkns_list.Add(tkn_mkr.Bry(src_bgn, pos, Bry_.Trim(Bry_.Mid(src, src_bgn, pos)))); + text_tkns_list.Add(tkn_mkr.Bry_raw(src_bgn, pos, Bry_.Trim(Bry_.Mid(src, src_bgn, pos)))); Make_rule(); cur_lang_bry = null; mode = Mode_key; diff --git a/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java b/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java index 8fae8e3ef..de8846d35 100644 --- a/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java +++ b/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java @@ -105,7 +105,7 @@ public class Xop_para_wkr implements Xop_ctx_wkr { if ( next_char_pos < src.length // bounds check && src[next_char_pos] == Byte_ascii.NewLine // is "\n\s\n"; i.e.: "\n" only ) { - ctx.Subs_add(root, ctx.Tkn_mkr().Bry(bgn_pos, bgn_pos, Byte_ascii.NewLine_bry)); // add a "\n" tkn; note that adding a NewLine tkn doesn't work, b/c Xoh_html_wtr has code to remove consecutive \n; PAGE:en.w:Preferred_numbers DATE:2014-06-24 + ctx.Subs_add(root, ctx.Tkn_mkr().Bry_raw(bgn_pos, bgn_pos, Byte_ascii.NewLine_bry)); // add a "\n" tkn; note that adding a NewLine tkn doesn't work, b/c Xoh_html_wtr has code to remove consecutive \n; PAGE:en.w:Preferred_numbers DATE:2014-06-24 prv_nl_pos = bgn_pos; } } diff --git a/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr.java b/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr.java index b22024dbc..1a368f958 100644 --- a/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr.java +++ b/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr.java @@ -31,7 +31,7 @@ public class Xop_tblw_lxr implements Xop_lxr { // standalone "!" should be ignored if no tblw present; EX: "a b! c" should not trigger ! for header switch (wlxr_type) { case Xop_tblw_wkr.Tblw_type_th: // \n! - case Xop_tblw_wkr.Tblw_type_th2: // !! + case Xop_tblw_wkr.Tblw_type_th2: // !! case Xop_tblw_wkr.Tblw_type_td: // \n| Xop_tkn_itm owner_tblw_tb = ctx.Stack_get_typ(Xop_tkn_itm_.Tid_tblw_tb); // check entire stack for tblw; DATE:2014-03-11 if ( owner_tblw_tb == null // no tblw in stack; highly probably that current sequence is not tblw tkn @@ -53,6 +53,20 @@ public class Xop_tblw_lxr implements Xop_lxr { return ctx.Lxr_make_txt_(cur_pos); } } + if (wlxr_type == Xop_tblw_wkr.Tblw_type_th2) { // !!; extra check to make sure \n! exists; DATE:2014-10-19 + int prv_th_pos = Bry_finder.Find_bwd(src, Byte_ascii.NewLine, bgn_pos); // search for previous \n + boolean invalid = prv_th_pos == Bry_finder.Not_found; // no \n; invalid + if (!invalid) { + ++prv_th_pos; // skip \n + prv_th_pos = Bry_finder.Find_fwd_while_space_or_tab(src, prv_th_pos, src_len); // skip \s; needed for "\n\s!" which is still a tblw + if (prv_th_pos == bgn_pos) // invalid: "\n" is directly in front of "!!" + invalid = true; + else + invalid = src[prv_th_pos] != Byte_ascii.Bang; // invalid if not "\n!" + } + if (invalid) + return Xop_tblw_wkr.Handle_false_tblw_match(ctx, root, src, bgn_pos, cur_pos, tkn_mkr.Txt(bgn_pos, cur_pos), false); + } break; } return Continue; diff --git a/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr__double_pipe_tst.java b/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr__double_pipe_tst.java index 07f04e290..33c0464cb 100644 --- a/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr__double_pipe_tst.java +++ b/400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr__double_pipe_tst.java @@ -27,7 +27,7 @@ public class Xop_tblw_wkr__double_pipe_tst { , "" )); } - @Test public void Tblw_lnki_nth() { // PURPOSE: if || is nth pipe, then treat as lnki; PAGE:en.w:Main_Page;de.w:Main_Page; DATE:2014-05-06 + @Test public void Lnki_nth() { // PURPOSE: if || is nth pipe, then treat as lnki; PAGE:en.w:Main_Page;de.w:Main_Page; DATE:2014-05-06 fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last ( "{|" , "|[[File:A.png|b||c]]" @@ -43,7 +43,7 @@ public class Xop_tblw_wkr__double_pipe_tst { ) ); } - @Test public void Tblw_lnki_list_1st() { // PURPOSE: if || is 1st pipe, but inside list, then treat as lnki; EX:w:Second_Boer_War; DATE:2014-05-05 + @Test public void Lnki_list_1st() { // PURPOSE: if || is 1st pipe, but inside list, then treat as lnki; EX:w:Second_Boer_War; DATE:2014-05-05 fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last ( "{|" , "|" @@ -65,7 +65,7 @@ public class Xop_tblw_wkr__double_pipe_tst { ) ); } - @Test public void Tblw_lnki_double_bang() { // PURPOSE: do not treat !! as tblw; PAGE:en.w:Pink_(singer); DATE:2014-06-25 + @Test public void Double_bang_lnki() { // PURPOSE: do not treat !! as tblw; PAGE:en.w:Pink_(singer); DATE:2014-06-25 fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last ( "{|" , "|" @@ -85,4 +85,24 @@ public class Xop_tblw_wkr__double_pipe_tst { ) ); } + @Test public void Double_bang_list() { // PURPOSE: do not treat !! as tblw; PAGE:en.w:Wikipedia:Featured_picture_candidates; DATE:2014-10-19 + fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last + ( "{|" + , "* a !! b" + , "|}" + ) , String_.Concat_lines_nl_skip_last + ( "" + , "
    " + , "
  • a !! b" + , "
  • " + , "
" + , " " + , " " + , " " + , "
" + , "
" + , "

" // NOTE:

is incorrect, but benign + ) + ); + } } diff --git a/400_xowa/src/gplx/xowa/users/history/Xou_history_mgr.java b/400_xowa/src/gplx/xowa/users/history/Xou_history_mgr.java index e760628a8..604d24b7b 100644 --- a/400_xowa/src/gplx/xowa/users/history/Xou_history_mgr.java +++ b/400_xowa/src/gplx/xowa/users/history/Xou_history_mgr.java @@ -47,7 +47,7 @@ public class Xou_history_mgr implements GfoInvkAble { byte[] page_ttl = null; ListAdp redirect_list = page.Redirected_ttls(); if (redirect_list.Count() > 0) // page was redirected; add src ttl to history, not trg; EX: UK -> United Kingdom; add "UK"; DATE:2014-02-28 - page_ttl = (byte[])page.Redirected_ttls().FetchAt(0); + page_ttl = page.Redirected_ttls__itm_0(); else { page_ttl = Bry_.Add(ttl.Ns().Name_db_w_colon(), ttl.Page_txt()); // use ttl.Page_txt() b/c it normalizes space/casing (url.Page_txt does not) if (url.Args().length > 0) diff --git a/400_xowa/src/gplx/xowa/xtns/poems/Poem_lxr_nl.java b/400_xowa/src/gplx/xowa/xtns/poems/Poem_lxr_nl.java deleted file mode 100644 index 9d2fe0bf2..000000000 --- a/400_xowa/src/gplx/xowa/xtns/poems/Poem_lxr_nl.java +++ /dev/null @@ -1,31 +0,0 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012 gnosygnu@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ -package gplx.xowa.xtns.poems; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; -import gplx.core.btries.*; import gplx.xowa.parsers.paras.*; -public class Poem_lxr_nl implements Xop_lxr { - public byte Lxr_tid() {return Xop_lxr_.Tid_nl_poem;} - public void Init_by_wiki(Xow_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.NewLine, this);} - public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} - public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) { - if (bgn_pos == Xop_parser_.Doc_bgn_bos) return ctx.Lxr_make_txt_(cur_pos); // simulated nl at beginning of every parse - ctx.Subs_add(root, tkn_mkr.Xnde(bgn_pos, cur_pos).Tag_(Xop_xnde_tag_.Tag_br)); // add
- ctx.Subs_add(root, tkn_mkr.NewLine(cur_pos, cur_pos, Xop_nl_tkn.Tid_char, 1)); // add \n; for pretty-printing - return cur_pos; - } - public static final Poem_lxr_nl _ = new Poem_lxr_nl(); Poem_lxr_nl() {} -} diff --git a/400_xowa/src/gplx/xowa/xtns/poems/Poem_lxr_pre.java b/400_xowa/src/gplx/xowa/xtns/poems/Poem_lxr_pre.java deleted file mode 100644 index 0fdbab8b8..000000000 --- a/400_xowa/src/gplx/xowa/xtns/poems/Poem_lxr_pre.java +++ /dev/null @@ -1,46 +0,0 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012 gnosygnu@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ -package gplx.xowa.xtns.poems; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; -import gplx.core.btries.*; import gplx.xowa.parsers.paras.*; -public class Poem_lxr_pre implements Xop_lxr { - public byte Lxr_tid() {return Xop_lxr_.Tid_poem;} - public void Init_by_wiki(Xow_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook_ary, this);} - public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {} - public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) { - int space_count = 1; - while (cur_pos < src_len) { - if (src[cur_pos++] == Byte_ascii.Space) { - ++space_count; - } - else { - --cur_pos; - break; - } - } - if (bgn_pos != Xop_parser_.Doc_bgn_bos) { // do not add xnde/nl if \n is BOS \n; PAGE:en.w:Teresa of Ávila; "\n\s\s" - ctx.Subs_add(root, tkn_mkr.Xnde(cur_pos, cur_pos).Tag_(Xop_xnde_tag_.Tag_br)); - ctx.Subs_add(root, tkn_mkr.NewLine(cur_pos, cur_pos, Xop_nl_tkn.Tid_char, 1)); - } - for (int i = 0; i < space_count; i++) - ctx.Subs_add(root, tkn_mkr.Amp_num(bgn_pos + 1, cur_pos, 160, Nbsp_bry)); - return cur_pos; - } - private static final byte[] Nbsp_bry = gplx.intl.Utf16_.Encode_int_to_bry(160); - private static final byte[] Hook_ary = new byte[] {Byte_ascii.NewLine, Byte_ascii.Space}; - public static final Poem_lxr_pre _ = new Poem_lxr_pre(); Poem_lxr_pre() {} -} diff --git a/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde.java b/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde.java index 28b1023c3..691c5c06b 100644 --- a/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde.java +++ b/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.xtns.poems; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; -import gplx.xowa.html.*; +import gplx.html.*; import gplx.xowa.html.*; public class Poem_nde implements Xox_xnde { private Xop_root_tkn xtn_root; public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {// REF.MW: Poem.php|wfRenderPoemTag @@ -27,15 +27,57 @@ public class Poem_nde implements Xox_xnde { if (src[itm_end - 1] == Byte_ascii.NewLine // ignore last \n; && itm_end != itm_bgn) --itm_end; // ...if not same as 1st \n; EX: \n Poem_xtn_mgr xtn_mgr = (Poem_xtn_mgr)wiki.Xtn_mgr().Get_or_fail(Poem_xtn_mgr.XTN_KEY); - xtn_root = xtn_mgr.Parser().Parse_text_to_wdom_old_ctx(ctx, Bry_.Mid(src, itm_bgn, itm_end), true); // NOTE: ignoring paragraph mode; technically MW enables para mode, but by replacing "\n" with "
\n" all the logic with para/pre mode is skipped + byte[] poem_bry = Parse_lines(wiki.Utl_bry_bfr_mkr(), src, itm_bgn, itm_end); + xtn_root = xtn_mgr.Parser().Parse_text_to_wdom_old_ctx(ctx, poem_bry, true); // NOTE: ignoring paragraph mode; technically MW enables para mode, but by replacing "\n" with "
\n" all the logic with para/pre mode is skipped } public void Xtn_write(Bry_bfr bfr, Xoa_app app, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, Xop_xnde_tkn xnde, byte[] src) { if (xtn_root == null) return; // inline poem; write nothing; EX: - bfr.Add(Bry_poem_bgn); + bfr.Add(Div_poem_bgn); html_wtr.Write_tkn(bfr, ctx, hctx, xtn_root.Root_src(), xnde, Xoh_html_wtr.Sub_idx_null, xtn_root); - bfr.Add(Bry_poem_end); + bfr.Add(Div_poem_end); + } + private static byte[] Parse_lines(Bry_bfr_mkr bfr_mkr, byte[] src, int src_bgn, int src_end) { + Bry_bfr bfr = bfr_mkr.Get_k004().Mkr_rls(); + int line_bgn = src_bgn; boolean line_is_1st = true; + while (line_bgn < src_end) { // iterate over each \n + boolean indent_enabled = false; + if (line_is_1st) line_is_1st = false; + else { + if (Bry_.Match(src, line_bgn, line_bgn + Comment_marker.length, Comment_marker)) + bfr.Add_byte_nl(); + else + bfr.Add(Html_tag_.Br_inl).Add_byte_nl().Add(Comment_marker); // add "
\n" unless 1st line; EX: "\n\s" should not add leading "
\n" + } + switch (src[line_bgn]) { + case Byte_ascii.Space: // "\n\s" -> "\n " + int space_end = Bry_finder.Find_fwd_while(src, line_bgn, src_end, Byte_ascii.Space); + int space_count = space_end - line_bgn; + line_bgn = space_end; + for (int i = 0; i < space_count; ++i) + bfr.Add(Html_entity_.Nbsp_num_bry); + break; + case Byte_ascii.Colon: { // "\n:" -> + int colon_end = Bry_finder.Find_fwd_while(src, line_bgn, src_end, Byte_ascii.Colon); + int colon_count = colon_end - line_bgn; + line_bgn = colon_end; + bfr.Add(Indent_bgn).Add_int_variable(colon_count).Add(Indent_end); // add + indent_enabled = true; + break; + } + } + int line_end = Bry_finder.Find_fwd(src, Byte_ascii.NewLine, line_bgn, src_end); // find end "\n" + if (line_end == Bry_finder.Not_found) line_end = src_end; // no "\n"; use eos; + bfr.Add_mid(src, line_bgn, line_end); // add everything from line_bgn to line_end + if (indent_enabled) bfr.Add(Html_tag_.Span_rhs); // if "\n:", add + line_bgn = line_end + 1; // +1 to skip over end "\n" + } + return bfr.Xto_bry_and_clear(); } private static byte[] - Bry_poem_bgn = Bry_.new_ascii_("
\n

\n") // NOTE: always enclose in

; MW does this implicitly in its modified parse; DATE:2014-04-27 - , Bry_poem_end = Bry_.new_ascii_("\n

\n
"); + Div_poem_bgn = Bry_.new_ascii_("
\n

\n") // NOTE: always enclose in

; MW does this implicitly in its modified parse; DATE:2014-04-27 + , Div_poem_end = Bry_.new_ascii_("\n

\n
") + , Indent_bgn = Bry_.new_ascii_("\n") + , Comment_marker = Bry_.new_ascii_("") + ; } diff --git a/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde_tst.java b/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde_tst.java index ce63739ad..6f16f829a 100644 --- a/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/poems/Poem_nde_tst.java @@ -38,7 +38,7 @@ public class Poem_nde_tst { , "" )); } - @Test public void Indent() { + @Test public void Nbsp_basic() { fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last ( "" , "a 1" @@ -57,7 +57,7 @@ public class Poem_nde_tst { , "" )); } - @Test public void Indent_2() { // PURPOSE: indent on 1st line caused page_break + @Test public void Nbsp_line_0() {// PURPOSE: indent on 1st line caused page_break fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last ( "" , " a" @@ -76,22 +76,30 @@ public class Poem_nde_tst { , "" )); } - @Test public void List() { + @Test public void Nbsp_blank_lines() {// PURPOSE: check blank lines; PAGE:none fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last ( "" - , ":a" - , ":b" + , " a" + , " " + , " " + , " b" , "" ), String_.Concat_lines_nl_skip_last ( "
" , "

" - , "" - , "

" - , "
a" - , "
" - , "
b" - , "
" - , "
" + , "  a
" + , "  
" + , "  
" + , "  b" + , "

" + , "
" + )); + } + @Test public void Comment() { + fxt.Test_parse_page_wiki_str("a c", String_.Concat_lines_nl_skip_last + ( "
" + , "

" + , "a c" , "

" , "
" )); @@ -104,7 +112,6 @@ public class Poem_nde_tst { )); fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last ( "{{test_outer}}" -// ( "{{test_print|a b}}c}}" ), String_.Concat_lines_nl_skip_last ( "a
" , "

" @@ -114,16 +121,7 @@ public class Poem_nde_tst { )); fxt.Init_defn_clear(); } - @Test public void Comment() { - fxt.Test_parse_page_wiki_str("a c", String_.Concat_lines_nl_skip_last - ( "

" - , "

" - , "a c" - , "

" - , "
" - )); - } - @Test public void Err_empty_line() { + @Test public void Err_empty_line() {// PURPOSE: one \n caused poem to fail fxt.Test_parse_page_wiki_str("\n", String_.Concat_lines_nl_skip_last ( "
" , "

" @@ -133,8 +131,7 @@ public class Poem_nde_tst { )); } @Test public void Ref() { // PURPOSE: inside poem was not showing up; DATE:2014-01-17 - fxt.Test_parse_page_all_str - ( String_.Concat_lines_nl_skip_last + fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last ( "ab" , ""), String_.Concat_lines_nl_skip_last ( "

" @@ -151,7 +148,7 @@ public class Poem_nde_tst { @Test public void Template_tkn() { // PURPOSE: make sure {{{1}}} is interpreted as invk_prm, not as text; DATE:2014-03-03 fxt.Test_parse_tmpl("{{{1}}}" , fxt.tkn_xnde_(0, 20).Subs_ - ( fxt.tkn_tmpl_prm_find_(fxt.tkn_txt_(9, 10)) + ( fxt.tkn_tmpl_prm_find_(fxt.tkn_txt_(9, 10)) ) ); } @@ -178,4 +175,99 @@ public class Poem_nde_tst { , "
de" )); } + @Test public void Indent_line_0() { // PURPOSE: handle colon on 1st line; PAGE:en.w:Mary_Wollstonecraft DATE:2014-10-19 + fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last + ( "" + , ":a" + , ":b" + , "" + ), String_.Concat_lines_nl_skip_last + ( "
" + , "

" + , "a
" + , "b" + , "

" + , "
" + )); + } + @Test public void Indent_many() { // PURPOSE: handle colon on 2nd line; PAGE:vi.s:Văn_Côi_thánh_nguyệt_tán_tụng_thi_ca DATE:2014-10-15 + fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last + ( "" + , "a" + , ":b" + , "::c" + , "" + ), String_.Concat_lines_nl_skip_last + ( "
" + , "

" + , "a
" + , "b
" + , "c" + , "

" + , "
" + )); + } + @Test public void Indent_blank() { // PURPOSE: check blank lines; PAGE:none DATE:2014-10-19 + fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last + ( "" + , ":a" + , ":" + , ":b" + , "" + ), String_.Concat_lines_nl_skip_last + ( "
" + , "

" + , "a
" + , "
" + , "b" + , "

" + , "
" + )); + } + @Test public void List_does_not_end() {// PURPOSE: list does not end with "\ntext"; PAGE:vi.s:Dương_Từ_Hà_Mậu_(dị_bản_mới); li.s:Sint_Servaes_legende/Nuuj_fergmènter DATE:2014-10-19 + fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last + ( "" + , "a" + , "*b" + , "**c" + , "d" + , "" + ), String_.Concat_lines_nl_skip_last + ( "
" + , "

" + , "a
" + , "

    " + , "
  • b
    " + , "
      " + , "
    • c
      " + , "
    • " + , "
    " + , "
  • " + , "
" + , "d" // was being embedded directly after
  • c + , "

    " + , "
  • " + )); + } + @Test public void Page() { // PURPOSE: handled dangling poems across pages; PAGE:ca.s:Llibre_de_Disputació_de_l'Ase DATE:2014-10-19 + fxt.Init_xtn_pages(); + fxt.Init_page_create("Page:A/1", "a\nb\n"); + fxt.Init_page_create("Page:A/2", "c\nd\n"); + fxt.Test_parse_page_wiki_str("", String_.Concat_lines_nl_skip_last + ( "

    " + , "

    " + , "a
    " + , "b
    " + , "

    " + , "

    " + , "c
    " // NOTE: 1
    not 2 + , "d
    " + , " " + , "

    " + , "
    " + , "

    " + , "
    " + , "

    " + )); + } } diff --git a/400_xowa/src/gplx/xowa/xtns/poems/Poem_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/poems/Poem_xtn_mgr.java index 294ddb76f..cc612911f 100644 --- a/400_xowa/src/gplx/xowa/xtns/poems/Poem_xtn_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/poems/Poem_xtn_mgr.java @@ -21,7 +21,7 @@ public class Poem_xtn_mgr extends Xox_mgr_base { @Override public Xox_mgr Clone_new() {return new Poem_xtn_mgr();} public Xop_parser Parser() {return parser;} private Xop_parser parser; @Override public void Xtn_init_by_wiki(Xow_wiki wiki) { - parser = new Xop_parser(wiki, wiki.Parser().Tmpl_lxr_mgr(), Xop_lxr_mgr.Poem_lxr_mgr); + parser = new Xop_parser(wiki, wiki.Parser().Tmpl_lxr_mgr(), wiki.Parser().Wtxt_lxr_mgr()); parser.Init_by_wiki(wiki); parser.Init_by_lang(wiki.Lang()); } diff --git a/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde_recursion_tst.java b/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde_recursion_tst.java index 1c4580a5e..702123ffa 100644 --- a/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde_recursion_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/proofreadPage/Pp_pages_nde_recursion_tst.java @@ -19,21 +19,16 @@ package gplx.xowa.xtns.proofreadPage; import gplx.*; import gplx.xowa.*; import import org.junit.*; public class Pp_pages_nde_recursion_tst { private Xop_fxt fxt = new Xop_fxt(); - @Before public void Init() { - Io_mgr._.InitEngine_mem(); - fxt.Wiki().Xtn_mgr().Xtn_proofread().Enabled_y_(); - fxt.Wiki().Db_mgr().Load_mgr().Clear(); // must clear; otherwise fails b/c files get deleted, but wiki.data_mgr caches the Xowd_regy_mgr (the .reg file) in memory; - fxt.Wiki().Ns_mgr().Add_new(Xowc_xtn_pages.Ns_page_id_default, "Page").Add_new(Xowc_xtn_pages.Ns_index_id_default, "Index").Init(); - } + @Before public void Init() {fxt.Init_xtn_pages();} @After public void term() { fxt.Wiki().Cache_mgr().Free_mem_all(); } @Test public void Page() { // PURPOSE: handle recursive calls on page; EX: fr.s:Page:NRF_19.djvu/19; DATE:2014-01-01 fxt.Init_page_create("Page:A/1", "abc"); // NOTE: recursive call to self fxt.Test_parse_page_wiki_str("", String_.Concat_lines_nl - ( "

    abc " - , "

    " - , "" + ( "

    abc " + , "

    " + , "" )); } @Test public void Index() { // PURPOSE: handle recursive calls on index; EX: en.s:Poems_of_Italy:_selections_from_the_Odes_of_Giosue_Carducci/Before_the_Old_Castle_of_Verona; DATE:2014-01-19 diff --git a/400_xowa/src_060_utl/gplx/Int_2_val.java b/400_xowa/src_060_utl/gplx/Int_2_val.java index 9752555bc..f3a3be184 100644 --- a/400_xowa/src_060_utl/gplx/Int_2_val.java +++ b/400_xowa/src_060_utl/gplx/Int_2_val.java @@ -20,6 +20,7 @@ public class Int_2_val { public Int_2_val(int v0, int v1) {val_0 = v0; val_1 = v1;} public int Val_0() {return val_0;} final int val_0; public int Val_1() {return val_1;} final int val_1; + public String Xto_str(Bry_bfr bfr) {return Xto_str(bfr, val_0, val_1);} public static final Int_2_val Null_ptr = null; public static Int_2_val parse_(String raw) { String[] itms = String_.Split(raw, ','); @@ -28,4 +29,5 @@ public class Int_2_val { int v1 = Int_.parse_or_(itms[1], Int_.MinValue); if (v1 == Int_.MinValue) return Null_ptr; return new Int_2_val(v0, v1); } + public static String Xto_str(Bry_bfr bfr, int x, int y) {return bfr.Add_int_variable(x).Add_byte_comma().Add_int_variable(y).Xto_str_and_clear();} } diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java b/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java index c5de86323..ffacb4739 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java +++ b/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor.java @@ -66,9 +66,9 @@ public class Xoa_css_extractor { this.lang_is_ltr = wiki.Lang().Dir_ltr(); this.wiki_code = wiki.Domain_abrv(); mainpage_html = Mainpage_download_html(); - Logo_setup(); Css_common_setup(); Css_wiki_setup(); + Logo_setup(); } public void Css_common_setup() { if (opt_download_css_common) @@ -95,14 +95,6 @@ public class Xoa_css_extractor { if (Io_mgr._.ExistsFil(css_commons_url)) return css_commons_url; // specific css exists for wiki; use it; EX: xowa_common_wiki_mediawikiwiki.css return failover_dir.GenSubFil(lang_is_ltr ? Css_common_name_ltr : Css_common_name_rtl); } -// private boolean Css_common_download(Io_url trg_fil) { // DELETE: replaced with Css_scrape; DATE:2014-02-11 -// String src_fil = String_.Format(css_stylesheet_common_src_fmt, String_.new_utf8_(wiki_domain)); -// String log_msg = usr_dlg.Prog_many("", "", "downloading css common: '~{0}'", src_fil); -// boolean rv = download_xrg.Prog_fmt_hdr_(log_msg).Src_(src_fil).Trg_(trg_fil).Exec(); -// if (!rv) -// usr_dlg.Warn_many("", "", "failed to download css_common: src_url=~{0};", src_fil); -// return rv; -// } public void Css_wiki_setup() { boolean css_stylesheet_wiki_missing = true; Io_url trg_fil = wiki_html_dir.GenSubFil(Css_wiki_name); @@ -141,6 +133,7 @@ public class Xoa_css_extractor { private boolean Logo_download(Io_url trg_fil) { String src_fil = Logo_find_src(); if (src_fil == null) { + if (Logo_copy_from_css(trg_fil)) return true; usr_dlg.Warn_many("", "", "failed to extract logo: trg_fil=~{0};", trg_fil.Raw()); return false; } @@ -150,6 +143,19 @@ public class Xoa_css_extractor { usr_dlg.Warn_many("", "", "failed to download logo: src_url=~{0};", src_fil); return rv; } + private boolean Logo_copy_from_css(Io_url trg_fil) { + Io_url commons_file = wiki_html_dir.GenSubFil(Css_common_name); + byte[] commons_src = Io_mgr._.LoadFilBry(commons_file); + int bgn_pos = Bry_finder.Find_fwd(commons_src, Bry_mw_wiki_logo); if (bgn_pos == Bry_finder.Not_found) return false; + bgn_pos += Bry_mw_wiki_logo.length; + int end_pos = Bry_finder.Find_fwd(commons_src, Byte_ascii.Quote, bgn_pos + 1); if (end_pos == Bry_finder.Not_found) return false; + byte[] src_bry = Bry_.Mid(commons_src, bgn_pos, end_pos); + if (Op_sys.Cur().Tid_is_wnt()) + src_bry = Bry_.Replace(src_bry, Byte_ascii.Slash, Byte_ascii.Backslash); + Io_url src_fil = wiki_html_dir.GenSubFil(String_.new_utf8_(src_bry)); + Io_mgr._.CopyFil(src_fil, trg_fil, true); + return true; + } private static final byte[] Bry_mw_wiki_logo = Bry_.new_ascii_(".mw-wiki-logo{background-image:url(\""); private String Logo_find_src() { if (mainpage_html == null) return null; int main_page_html_len = mainpage_html.length; diff --git a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java b/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java index 7f0c70ccb..d68af5cf3 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java +++ b/400_xowa/src_240_install/gplx/xowa/Xoa_css_extractor_basic_tst.java @@ -25,6 +25,13 @@ public class Xoa_css_extractor_basic_tst { fxt.Exec_logo_setup(); fxt.Test_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/logo.png", "download"); } + @Test public void Logo_download_mw_wiki_logo() { + fxt.Init_fil("mem/http/en.wikipedia.org" , ""); + fxt.Init_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/wiki.png" , "download"); + fxt.Init_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/xowa_common.css" , ".mw-wiki-logo{background-image:url(\"wiki.png\");"); + fxt.Exec_logo_setup(); + fxt.Test_fil("mem/xowa/user/anonymous/wiki/en.wikipedia.org/html/logo.png" , "download"); + } @Test public void Logo_failover() { fxt.Init_fil("mem/xowa/bin/any/html/xowa/import/logo.png" , "failover"); fxt.Exec_logo_setup(); diff --git a/400_xowa/src_240_install/gplx/xowa/Xoi_dump_mgr.java b/400_xowa/src_240_install/gplx/xowa/Xoi_dump_mgr.java index d63a654b0..52cce29ca 100644 --- a/400_xowa/src_240_install/gplx/xowa/Xoi_dump_mgr.java +++ b/400_xowa/src_240_install/gplx/xowa/Xoi_dump_mgr.java @@ -27,7 +27,7 @@ public class Xoi_dump_mgr implements GfoInvkAble { public boolean Wiki_storage_type_is_sql() {return wiki_storage_type == Wiki_storage_type_sqlite;} public String Db_ns_map() {return db_ns_map;} private String db_ns_map = "Template~Module"; public boolean Css_wiki_update() {return css_wiki_update;} private boolean css_wiki_update = true; - public boolean Css_commons_download() {return css_commons_download;} private boolean css_commons_download = false; + public boolean Css_commons_download() {return css_commons_download;} private boolean css_commons_download = true; // changed from false to true; DATE:2014-10-19 public boolean Delete_xml_file() {return delete_xml_file;} private boolean delete_xml_file = true; public byte Search_version() {return search_version;} private byte search_version = gplx.xowa.specials.search.Xosrh_core.Version_2; public boolean Import_bz2_by_stdout() {return import_bz2_by_stdout;} private boolean import_bz2_by_stdout = true; diff --git a/400_xowa/src_300_html/gplx/xowa/Xoa_page.java b/400_xowa/src_300_html/gplx/xowa/Xoa_page.java index 2fdc4b271..1980faa86 100644 --- a/400_xowa/src_300_html/gplx/xowa/Xoa_page.java +++ b/400_xowa/src_300_html/gplx/xowa/Xoa_page.java @@ -41,6 +41,7 @@ public class Xoa_page { public boolean Missing() {return missing;} public Xoa_page Missing_() {return Missing_(true);} public Xoa_page Missing_(boolean v) {missing = v; return this;} private boolean missing; public boolean Redirected() {return redirected;} public Xoa_page Redirected_(boolean v) {redirected = v; return this;} private boolean redirected; public ListAdp Redirected_ttls() {return redirected_ttls;} private ListAdp redirected_ttls = ListAdp_.new_(); + public byte[] Redirected_ttls__itm_0() {return (byte[])redirected_ttls.FetchAt(0);} public byte[] Redirected_src() {return redirected_src;} public void Redirected_src_(byte[] v) {this.redirected_src = v;} private byte[] redirected_src; public byte Edit_mode() {return edit_mode;} private byte edit_mode; public void Edit_mode_update_() {edit_mode = Xoa_page_.Edit_mode_update;} public Xop_root_tkn Root() {return root;} public Xoa_page Root_(Xop_root_tkn v) {root = v; return this;} private Xop_root_tkn root; diff --git a/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser.java b/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser.java index 1ff6666a7..3f4da7e7d 100644 --- a/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser.java +++ b/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser.java @@ -148,11 +148,12 @@ public class Xoa_url_parser { } else { // parse failed; url doesn't have protocol byte[] wiki_bry = rv.Wiki_bry(); - if (Bry_.Len_gt_0(wiki_bry)) { // NOTE: wiki_bry null when passing in Category:A from home_wiki - Xow_xwiki_itm xwiki_itm = app.User().Wiki().Xwiki_mgr().Get_by_key(wiki_bry); // see if url.Wiki_bry is actually wiki; - if ( xwiki_itm != null // null-check - && !xwiki_itm.Type_is_xwiki_lang(cur_wiki.Lang().Lang_id())) // in xwiki, but not lang; EX: "fr.wikipedia.org" vs "fr"; ca.s:So/Natura_del_so; DATE:2014-04-26 - wiki = app.Wiki_mgr().Get_by_key_or_make(xwiki_itm.Domain()); + if (Bry_.Len_gt_0(wiki_bry)) { // NOTE: wiki_bry is null when passing in Category:A from home_wiki + Xow_xwiki_itm xwiki_itm = app.User().Wiki().Xwiki_mgr().Get_by_key(wiki_bry); // check if url.Wiki_bry is actually wiki; note that checking User().Wiki().Xwiki_mgr() to find "offline" wikis + if ( xwiki_itm != null // null-check + && Bry_.Eq(xwiki_itm.Domain(), wiki_bry) // check that xwiki.domain == wiki; avoids false lang matches like "so/page" or "C/page"; EX: "fr.wikipedia.org" vs "fr"; ca.s:So/Natura_del_so; DATE:2014-04-26; PAGE:no.b:C/Variabler; DATE:2014-10-14 + ) + wiki = app.Wiki_mgr().Get_by_key_or_make(xwiki_itm.Domain()); } if (rv.Page_bry() == null) { // 1 seg; EX: "Earth"; "fr.wikipedia.org" if (wiki != null) { // wiki_bry is known wiki; EX: "fr.wikipedia.org" diff --git a/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser_basic_tst.java b/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser_basic_tst.java index e8d113e52..4bbcd8dec 100644 --- a/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser_basic_tst.java +++ b/400_xowa/src_310_url/gplx/xowa/Xoa_url_parser_basic_tst.java @@ -25,6 +25,10 @@ public class Xoa_url_parser_basic_tst { @Test public void Abrv() { // deprecate; no longer needed with shortcuts fxt.Expd_wiki("en.wikipedia.org").Expd_page("A").Test_parse_w_wiki("en.wikipedia.org/A"); } + @Test public void Commons() { // PURPOSE: "C" was being picked up as an xwiki to commons; PAGE:no.b:C/Variabler; DATE:2014-10-14 + fxt.Init_xwiki("c", "commons.wikimedia.org"); // add alias of "C" + fxt.Expd_wiki("en.wikipedia.org").Expd_page("C/D").Test_parse_w_wiki("C/D"); // should use default wiki of enwiki, not commons; also, page should be "C/D", not "D" + } @Test public void Http_basic() { fxt.Expd_wiki("en.wikipedia.org").Expd_page("A").Test_parse_w_wiki("http://en.wikipedia.org/wiki/A"); } @@ -144,6 +148,7 @@ class Xoa_url_parser_chkr implements Tst_chkr { public Xoa_url_parser_chkr Expd_anchor(String v) {this.expd_anchor = v; return this;} private String expd_anchor; public Xoa_url_parser_chkr Expd_action_is_edit_y() {this.expd_anchor_is_edit = Bool_.Y_byte; return this;} private byte expd_anchor_is_edit = Bool_.__byte; public Xoa_url_parser_chkr Expd_action_is_edit_n() {this.expd_anchor_is_edit = Bool_.N_byte; return this;} + public void Init_xwiki(String alias, String domain) {app.User().Wiki().Xwiki_mgr().Add_full(alias, domain);} public int Chk(Tst_mgr mgr, String path, Object actl_obj) { Xoa_url actl = (Xoa_url)actl_obj; int rv = 0; diff --git a/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java b/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java index 21808ecf6..e24c9ab95 100644 --- a/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java +++ b/400_xowa/src_400_parser/gplx/xowa/Xop_fxt.java @@ -400,5 +400,11 @@ public class Xop_fxt { Xol_kwd_grp kwd_grp = kwd_mgr.Get_or_new(kwd_id); kwd_grp.Srl_load(case_match, Bry_.Ary(kwds)); } + public void Init_xtn_pages() { + Io_mgr._.InitEngine_mem(); + wiki.Xtn_mgr().Xtn_proofread().Enabled_y_(); + wiki.Db_mgr().Load_mgr().Clear(); // must clear; otherwise fails b/c files get deleted, but wiki.data_mgr caches the Xowd_regy_mgr (the .reg file) in memory; + wiki.Ns_mgr().Add_new(Xowc_xtn_pages.Ns_page_id_default, "Page").Add_new(Xowc_xtn_pages.Ns_index_id_default, "Index").Init(); + } public void Clear_ref_mgr() {this.Page().Ref_mgr().Grps_clear();} // clear to reset count } diff --git a/400_xowa/src_400_parser/gplx/xowa/Xop_lxr_mgr.java b/400_xowa/src_400_parser/gplx/xowa/Xop_lxr_mgr.java index 6d83e84e9..aba531191 100644 --- a/400_xowa/src_400_parser/gplx/xowa/Xop_lxr_mgr.java +++ b/400_xowa/src_400_parser/gplx/xowa/Xop_lxr_mgr.java @@ -64,20 +64,6 @@ public class Xop_lxr_mgr { , Xop_under_lxr._ }); } - public static final Xop_lxr_mgr Poem_lxr_mgr // NOTE: can't go into gplx.xowa.xtn.poems b/c lxrs below are not public - = new Xop_lxr_mgr(new Xop_lxr[] - { Xop_pipe_lxr._, new Xop_eq_lxr(false), Xop_space_lxr._, Xop_tab_lxr._ - , Xop_amp_lxr._, Xop_apos_lxr._, Xop_colon_lxr._ - , Xop_lnki_lxr_bgn._, Xop_lnki_lxr_end._ - , Xop_list_lxr._ - , Xop_hdr_lxr._ - , Xop_hr_lxr._ - , Xop_xnde_lxr._ - , Xop_lnke_lxr._, Xop_lnke_end_lxr._ - , Xop_tblw_lxr._ - , gplx.xowa.xtns.poems.Poem_lxr_nl._ - , gplx.xowa.xtns.poems.Poem_lxr_pre._ - }); public static final Xop_lxr_mgr Popup_lxr_mgr // same as orig_page, except apos_lxr added = new Xop_lxr_mgr(new Xop_lxr[] { Xop_pipe_lxr._, new Xop_eq_lxr(true), Xop_colon_lxr._, Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._ @@ -89,5 +75,5 @@ public class Xop_lxr_mgr { , gplx.xowa.xtns.translates.Xop_tvar_lxr._ , Xop_cr_lxr._ // always ignore \r; DATE:2014-03-02 , gplx.xowa.parsers.apos.Xop_apos_lxr._ // needed else multiple apos may be split across blocks; - }); + }); } diff --git a/400_xowa/src_405_tkn/gplx/xowa/Xop_tkn_mkr.java b/400_xowa/src_405_tkn/gplx/xowa/Xop_tkn_mkr.java index 7b972f4fc..9bb4b651d 100644 --- a/400_xowa/src_405_tkn/gplx/xowa/Xop_tkn_mkr.java +++ b/400_xowa/src_405_tkn/gplx/xowa/Xop_tkn_mkr.java @@ -60,8 +60,8 @@ public class Xop_tkn_mkr { public Xop_pre_tkn Para_pre_bgn(int pos) {return new Xop_pre_tkn(pos, pos, Xop_pre_tkn.Pre_tid_bgn, null);} public Xop_pre_tkn Para_pre_end(int pos, Xop_tkn_itm bgn) {return new Xop_pre_tkn(pos, pos, Xop_pre_tkn.Pre_tid_end, bgn);} public Xop_ignore_tkn Ignore(int bgn, int end, byte ignore_type) {return new Xop_ignore_tkn(bgn, end, ignore_type);} - public Xop_bry_tkn Bry(int bgn, int end, byte[] bry) {return new Xop_bry_tkn(bgn, end, bry);} - public Xop_bry_tkn Bry(byte[] src, int bgn, int end) {return new Xop_bry_tkn(bgn, end, Bry_.Mid(src, bgn, end));} + public Xop_bry_tkn Bry_raw(int bgn, int end, byte[] bry) {return new Xop_bry_tkn(bgn, end, bry);} + public Xop_bry_tkn Bry_mid(byte[] src, int bgn, int end) {return new Xop_bry_tkn(bgn, end, Bry_.Mid(src, bgn, end));} public Xop_under_tkn Under(int bgn, int end, int v) {return new Xop_under_tkn(bgn, end, v);} public gplx.xowa.xtns.xowa_cmds.Xop_xowa_cmd Xnde_xowa_cmd() {return new gplx.xowa.xtns.xowa_cmds.Xop_xowa_cmd();} public gplx.xowa.xtns.poems.Poem_nde Xnde_poem() {return new gplx.xowa.xtns.poems.Poem_nde();} diff --git a/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr.java b/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr.java index 7fa39f2ce..4b5edd5f4 100644 --- a/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr.java +++ b/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr.java @@ -140,7 +140,7 @@ public class Xop_lnki_wkr implements Xop_ctx_wkr, Xop_arg_wkr { int subs_len = val_tkn.Subs_len(); Xop_tkn_itm caption_val_tkn = ((Arg_nde_tkn)cur_caption_tkn).Val_tkn(); int pipe_bgn = caption_val_tkn.Src_bgn(); // for bookeeping purposes, assign | pos to same pos as val_tkn; note that pos really shouldn't be used; DATE:2014-05-05 - caption_val_tkn.Subs_add(ctx.Tkn_mkr().Bry(pipe_bgn, pipe_bgn + 1, Const_pipe)); // NOTE: add pipe once for entire caption tkn; used to add for every val tkn; DATE:2014-06-08 + caption_val_tkn.Subs_add(ctx.Tkn_mkr().Bry_raw(pipe_bgn, pipe_bgn + 1, Const_pipe)); // NOTE: add pipe once for entire caption tkn; used to add for every val tkn; DATE:2014-06-08 for (int i = 0 ; i < subs_len; i++) { Xop_tkn_itm sub_itm = val_tkn.Subs_get(i); caption_val_tkn.Subs_add(sub_itm); diff --git a/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr_.java b/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr_.java index 78d1febf5..4c3e45880 100644 --- a/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr_.java +++ b/400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr_.java @@ -127,7 +127,7 @@ public class Xop_lnki_wkr_ { && lnki.Ttl() != null // only change "]]]" to "]" + "]]" if lnki is not title; otherwise [[A]]] -> "A]" which will be invalid; PAGE:en.w:Tall_poppy_syndrome DATE:2014-07-23 ) { Xop_tkn_itm caption_val_tkn = lnki.Caption_val_tkn(); - caption_val_tkn.Subs_add(tkn_mkr.Bry(cur_pos, cur_pos + 1, Byte_ascii.Brack_end_bry)); // add "]" as bry + caption_val_tkn.Subs_add(tkn_mkr.Bry_raw(cur_pos, cur_pos + 1, Byte_ascii.Brack_end_bry)); // add "]" as bry caption_val_tkn.Src_end_(caption_val_tkn.Src_end() + 1); return true; } diff --git a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java index 221bf8f3c..a48a08f84 100644 --- a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java +++ b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java @@ -222,7 +222,7 @@ public class Xop_xnde_wkr implements Xop_ctx_wkr { else if (len == 2 && src[cur_pos] == Byte_ascii.Lt && src[cur_pos + 1] == Byte_ascii.Slash) bry = Bry_escape_lt_slash; else bry = Bry_.Add(Html_entity_.Lt_bry, Bry_.Mid(src, bgn_pos + 1, cur_pos)); // +1 to skip < - return tkn_mkr.Bry(bgn_pos, cur_pos, bry); + return tkn_mkr.Bry_raw(bgn_pos, cur_pos, bry); } private int Make_noinclude(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int gtPos, Xop_xnde_tag tag, int tag_end_pos, boolean tag_is_closing) { tag_end_pos = Bry_finder.Find_fwd_while(src, tag_end_pos, src_len, Byte_ascii.Space);// NOTE: must skip spaces else "" will not work with safesubst; PAGE:en.w:Wikipedia:Featured_picture_candidates; DATE:2014-06-24 @@ -312,7 +312,7 @@ public class Xop_xnde_wkr implements Xop_ctx_wkr { if ( page.Html_data().Html_restricted() && page.Wiki().Domain_tid() != Xow_wiki_domain_.Tid_home) { int end_pos = gtPos + 1; - ctx.Subs_add(root, tkn_mkr.Bry(bgn_pos, end_pos, Bry_.Add(gplx.html.Html_entity_.Lt_bry, Bry_.Mid(src, bgn_pos + 1, end_pos)))); // +1 to skip < + ctx.Subs_add(root, tkn_mkr.Bry_raw(bgn_pos, end_pos, Bry_.Add(gplx.html.Html_entity_.Lt_bry, Bry_.Mid(src, bgn_pos + 1, end_pos)))); // +1 to skip < return end_pos; } } @@ -472,7 +472,7 @@ public class Xop_xnde_wkr implements Xop_ctx_wkr { } } if (end_tag.Restricted()) // restricted tags (like