mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
v1.10.3.1
This commit is contained in:
parent
d6561b3c1f
commit
7d8984f6a8
@ -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_(" ")
|
||||
;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public class Html_tag_ {
|
||||
, Script_lhs = Bry_.new_ascii_("<script>")
|
||||
, Script_lhs_w_type = Bry_.new_ascii_("<script type='text/javascript'>")
|
||||
, Script_rhs = Bry_.new_ascii_("</script>")
|
||||
, Span_rhs = Bry_.new_ascii_("</span>")
|
||||
;
|
||||
|
||||
public static final String
|
||||
|
@ -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 = "";
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -30,7 +30,7 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xop_lnki_log
|
||||
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,6 +90,7 @@ 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);
|
||||
if (!page.Redirected())
|
||||
wiki.Html_mgr().Page_wtr_mgr().Gen(ctx.Cur_page(), Xopg_view_mode.Tid_read);
|
||||
}
|
||||
if (gen_hdump) {
|
||||
|
@ -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
|
||||
|
@ -16,13 +16,14 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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};
|
||||
|
@ -17,47 +17,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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"
|
||||
)
|
||||
;
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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"
|
||||
, ";"
|
||||
);
|
||||
}
|
@ -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();
|
||||
try {
|
||||
Xow_wiki wiki = page.Wiki();
|
||||
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_m001();
|
||||
try {
|
||||
if (wiki.Db_mgr().Category_version() == Xoa_ctg_mgr.Version_2)
|
||||
Bld_html_v2(wiki, page, tmp_bfr);
|
||||
else
|
||||
|
@ -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;
|
||||
|
@ -17,36 +17,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
@ -17,37 +17,61 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -17,56 +17,36 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
@ -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;}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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'"
|
||||
;
|
||||
}
|
||||
|
52
400_xowa/src/gplx/xowa/hdumps/Xogv_tab_base.java
Normal file
52
400_xowa/src/gplx/xowa/hdumps/Xogv_tab_base.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -18,10 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
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);
|
||||
|
@ -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) {
|
||||
|
@ -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()));
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
( "<table>"
|
||||
, " <ul>"
|
||||
, " <li> a !! b"
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "</p>" // NOTE: </p> is incorrect, but benign
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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 <br/>
|
||||
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() {}
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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; "<poem>\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() {}
|
||||
}
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.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: <poem>\n</poem>
|
||||
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 "<br/>\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 "<br/>\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: <poem/>
|
||||
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 "<br/>\n" unless 1st line; EX: "<poem>\n\s" should not add leading "<br/>\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:" -> <span class='mw-poem-indented' style='display: inline-block; margin-left: #em;'>
|
||||
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 <span class='mw-poem-indented' style='display: inline-block; margin-left: #em;'>
|
||||
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 </span>
|
||||
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_("<div class=\"poem\">\n<p>\n") // NOTE: always enclose in <p>; MW does this implicitly in its modified parse; DATE:2014-04-27
|
||||
, Bry_poem_end = Bry_.new_ascii_("\n</p>\n</div>");
|
||||
Div_poem_bgn = Bry_.new_ascii_("<div class=\"poem\">\n<p>\n") // NOTE: always enclose in <p>; MW does this implicitly in its modified parse; DATE:2014-04-27
|
||||
, Div_poem_end = Bry_.new_ascii_("\n</p>\n</div>")
|
||||
, Indent_bgn = Bry_.new_ascii_("\n<span class='mw-poem-indented' style='display: inline-block; margin-left: ")
|
||||
, Indent_end = Bry_.new_ascii_("em;'>")
|
||||
, Comment_marker = Bry_.new_ascii_("<!--xowa-->")
|
||||
;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class Poem_nde_tst {
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Indent() {
|
||||
@Test public void Nbsp_basic() {
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, "a 1"
|
||||
@ -57,7 +57,7 @@ public class Poem_nde_tst {
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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
|
||||
( "<poem>"
|
||||
, " a"
|
||||
@ -76,22 +76,30 @@ public class Poem_nde_tst {
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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
|
||||
( "<poem>"
|
||||
, ":a"
|
||||
, ":b"
|
||||
, " a"
|
||||
, " "
|
||||
, " "
|
||||
, " b"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, ""
|
||||
, "<dl>"
|
||||
, " <dd>a"
|
||||
, " </dd>"
|
||||
, " <dd>b"
|
||||
, " </dd>"
|
||||
, "</dl>"
|
||||
, "  a<br/>"
|
||||
, "  <br/>"
|
||||
, "  <br/>"
|
||||
, "  b"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Comment() {
|
||||
fxt.Test_parse_page_wiki_str("<poem>a<!-- b --> c</poem>", String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a c"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
@ -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 <poem>b}}c</poem>}}"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "a <div class=\"poem\">"
|
||||
, "<p>"
|
||||
@ -114,16 +121,7 @@ public class Poem_nde_tst {
|
||||
));
|
||||
fxt.Init_defn_clear();
|
||||
}
|
||||
@Test public void Comment() {
|
||||
fxt.Test_parse_page_wiki_str("<poem>a<!-- b --> c</poem>", String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a c"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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("<poem>\n</poem>", String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
@ -133,8 +131,7 @@ public class Poem_nde_tst {
|
||||
));
|
||||
}
|
||||
@Test public void Ref() { // PURPOSE: <ref> 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
|
||||
( "<poem>a<ref>b</ref></poem>"
|
||||
, "<references/>"), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
@ -178,4 +175,99 @@ public class Poem_nde_tst {
|
||||
, "</div>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
|
||||
( "<poem>"
|
||||
, ":a"
|
||||
, ":b"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>a</span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>b</span>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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
|
||||
( "<poem>"
|
||||
, "a"
|
||||
, ":b"
|
||||
, "::c"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>b</span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 2em;'>c</span>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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
|
||||
( "<poem>"
|
||||
, ":a"
|
||||
, ":"
|
||||
, ":b"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>a</span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'></span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>b</span>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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
|
||||
( "<poem>"
|
||||
, "a"
|
||||
, "*b"
|
||||
, "**c"
|
||||
, "d"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "<ul>"
|
||||
, " <li>b<br/>"
|
||||
, " <ul>"
|
||||
, " <li>c<br/>"
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " </li>"
|
||||
, "</ul>"
|
||||
, "d" // was being embedded directly after <li>c
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@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", "<poem>a\nb\n");
|
||||
fxt.Init_page_create("Page:A/2", "<poem>c\nd\n");
|
||||
fxt.Test_parse_page_wiki_str("<pages index=\"A\" from=1 to=2 />", String_.Concat_lines_nl_skip_last
|
||||
( "<p><div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "b<br/>"
|
||||
, " <div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "c<br/>" // NOTE: 1 <br/> not 2
|
||||
, "d<br/>"
|
||||
, " "
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -19,12 +19,7 @@ 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();
|
||||
}
|
||||
|
@ -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();}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -148,10 +148,11 @@ 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 (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
|
||||
&& !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
|
||||
&& 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"
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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._
|
||||
|
@ -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();}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 "<noinclude />" 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 <script>) are not placed on stack; for now, just write it out
|
||||
ctx.Subs_add(root, tkn_mkr.Bry(bgn_pos, cur_pos, Bry_.Add(gplx.html.Html_entity_.Lt_bry, Bry_.Mid(src, bgn_pos + 1, cur_pos)))); // +1 to skip <
|
||||
ctx.Subs_add(root, tkn_mkr.Bry_raw(bgn_pos, cur_pos, Bry_.Add(gplx.html.Html_entity_.Lt_bry, Bry_.Mid(src, bgn_pos + 1, cur_pos)))); // +1 to skip <
|
||||
else {
|
||||
if (pre2_pending) {
|
||||
pre2_pending = false;
|
||||
@ -482,7 +482,7 @@ public class Xop_xnde_wkr implements Xop_ctx_wkr {
|
||||
if (end_tag.Xtn()) // if xtn end tag, ignore it; tidy / browser doesn't know about xtn_tags like "</poem>" so these need to be hidden, else they will show; DATE:2014-07-22
|
||||
ctx.Subs_add(root, tkn_mkr.Ignore(bgn_pos, cur_pos, Xop_ignore_tkn.Ignore_tid_xnde_dangling));
|
||||
else // regular tag; show it; depend on tidy to clean up; DATE:2014-07-22
|
||||
ctx.Subs_add(root, tkn_mkr.Bry(src, bgn_pos, cur_pos));
|
||||
ctx.Subs_add(root, tkn_mkr.Bry_mid(src, bgn_pos, cur_pos));
|
||||
}
|
||||
}
|
||||
ctx.Para().Process_block__xnde(end_tag, end_tag.Block_close());
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user