From f4b95f5ce6764a241d4dd0b7e208336cfa9332bc Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Mon, 27 Apr 2015 00:27:52 -0400 Subject: [PATCH] v2.4.4.1 --- 100_core/.classpath | 1 - .../src_200_io/gplx/ios/IoEngine_system.java | 47 ++-- 100_core/src_200_io/gplx/ios/IoStream_.java | 2 +- .../src_200_io/gplx/ios/Io_stream_wtr_.java | 1 - 140_dbs/src/gplx/dbs/Db_conn_.java | 2 +- 140_dbs/src/gplx/dbs/Db_conn_bldr.java | 4 + 140_dbs/src/gplx/dbs/Db_sql_select.java | 78 ++++++ 150_gfui/src_700_env/gplx/gfui/Swt_kit.java | 10 +- 400_xowa/src/gplx/core/brys/Bry_rdr.java | 1 + 400_xowa/src/gplx/dbs/Db_attach_rdr.java | 8 +- 400_xowa/src/gplx/dbs/cfgs/Db_cfg_tbl.java | 1 + .../updates/Schema_update_mgr_tst.java | 2 +- 400_xowa/src/gplx/fsdb/Fsdb_db_mgr_.java | 2 +- 400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v1.java | 47 +++- 400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2.java | 2 +- .../src/gplx/fsdb/Fsdb_db_mgr__v2_bldr.java | 29 +- 400_xowa/src/gplx/fsdb/meta/Fsm_mnt_mgr.java | 5 + 400_xowa/src/gplx/xowa/Xoa_app.java | 1 + 400_xowa/src/gplx/xowa/Xoa_app_.java | 2 +- 400_xowa/src/gplx/xowa/Xoae_app.java | 3 +- .../apis/xowa/html/modules/Xoapi_popups.java | 2 +- .../xowa/apis/xowa/specials/Xoapi_search.java | 41 ++- .../startups/tabs/Xoapi_startup_tabs.java | 3 +- 400_xowa/src/gplx/xowa/apps/Xoa_thread_.java | 30 ++ .../xowa/bldrs/cmds/Xob_dump_mgr_base.java | 1 + .../bldrs/cmds/files/Xob_fsdb_make_cmd.java | 14 +- .../bldrs/cmds/files/Xob_lnki_temp_wkr.java | 5 +- .../bldrs/cmds/wikis/Xob_redirect_cmd.java | 2 +- .../xowa/bldrs/infos/Xob_info_session.java | 2 +- .../src/gplx/xowa/ctgs/Xoctg_fmtr_all.java | 9 +- .../gplx/xowa/ctgs/Xoctg_html_mgr_tst.java | 8 +- .../src/gplx/xowa/dbs/Xodb_save_mgr_sql.java | 5 +- 400_xowa/src/gplx/xowa/files/Xof_ext_.java | 10 + .../src/gplx/xowa/files/bins/Xof_bin_mgr.java | 3 +- .../xowa/files/bins/Xof_bin_skip_mgr.java | 71 +++++ .../files/bins/Xof_bin_wkr__fsdb_sql.java | 12 +- .../xowa/files/fsdb/tsts/Xof_file_fxt.java | 2 +- .../src/gplx/xowa/gui/views/Xog_html_itm.java | 60 ++-- .../src/gplx/xowa/gui/views/Xog_tab_itm.java | 3 +- .../src/gplx/xowa/gui/views/Xog_tab_mgr.java | 4 +- .../src/gplx/xowa/gui/views/Xog_win_itm.java | 6 +- .../src/gplx/xowa/html/Xohp_ctg_grp_mgr.java | 6 +- .../gplx/xowa/html/lnkis/Xoh_lnki_wtr.java | 2 +- .../html/modules/popups/Xow_popup_itm.java | 2 +- .../html/modules/popups/Xow_popup_mgr.java | 8 +- .../xowa/html/wtrs/Xoh_anchor_kv_bldr.java | 49 ++++ .../src/gplx/xowa/html/wtrs/Xoh_img_path.java | 27 ++ .../gplx/xowa/html/wtrs/Xoh_lnki_bldr.java | 82 ++++++ .../gplx/xowa/html/wtrs/Xoh_lnki_wtr_utl.java | 10 +- .../src/gplx/xowa/langs/Xol_lang_itm_.java | 202 +++++++------- .../src/gplx/xowa/pages/Xopg_html_data.java | 4 +- .../xowa/servers/http/Http_server_mgr.java | 2 +- .../gplx/xowa/servers/tcp/Xosrv_server.java | 2 +- 400_xowa/src/gplx/xowa/specials/Xows_mgr.java | 36 +-- .../src/gplx/xowa/specials/Xows_page.java | 3 +- .../gplx/xowa/specials/Xows_special_meta.java | 35 +++ .../xowa/specials/Xows_special_meta_.java | 69 +++++ .../specials/allPages/Xows_page_allpages.java | 3 +- .../allPages/Xows_page_allpages_tst.java | 4 +- .../xowa/specials/movePage/Move_page.java | 1 + .../gplx/xowa/specials/nearby/Nearby_mgr.java | 2 +- .../randoms/Xop_randomRootPage_page.java | 1 + .../specials/randoms/Xows_page_random.java | 1 + .../search/Xog_search_suggest_mgr.java | 2 +- .../search/Xow_domain_sorter__manual_tid.java | 121 +++++++++ .../xowa/specials/search/Xows_arg_mgr.java | 14 +- .../gplx/xowa/specials/search/Xows_core.java | 27 +- .../xowa/specials/search/Xows_db_cache.java | 24 +- .../specials/search/Xows_db_matcher_bldr.java | 1 - .../xowa/specials/search/Xows_db_row.java | 12 +- .../xowa/specials/search/Xows_db_wkr.java | 119 ++++---- .../xowa/specials/search/Xows_html_wkr.java | 93 +++---- .../specials/search/Xows_html_wkr_tst.java | 29 +- .../specials/search/Xows_page__search.java | 43 +-- .../specials/search/Xows_paging_parser.java | 40 +++ .../specials/search/Xows_ui_async_tst.java | 5 +- .../xowa/specials/search/Xows_ui_cmd.java | 110 +++++--- .../xowa/specials/search/Xows_ui_qry.java | 7 +- .../search/parsers/Xow_search_parser.java | 3 +- .../search/parsers/Xow_search_scanner.java | 1 - .../statistics/Xop_statistics_page.java | 1 + .../xowa/default_tab/Default_tab_page.java | 5 +- .../file_browsers/Xosp_fbrow_special.java | 2 +- .../popup_history/Popup_history_page.java | 4 +- .../xowa/system_data/System_data_page.java | 1 + .../xowa/users/data/Xoud_history_mgr.java | 7 +- .../xowa/users/data/Xoud_history_special.java | 2 +- .../xowa/users/data/Xoud_opt_scope_tst.java | 2 +- .../xowa/users/history/Xou_history_html.java | 29 +- .../src/gplx/xowa/wikis/Xoa_wiki_mgr.java | 9 - 400_xowa/src/gplx/xowa/wikis/Xow_domain.java | 1 + .../gplx/xowa/wikis/data/Xowd_db_file.java | 10 +- .../wikis/data/Xowd_db_file_schema_props.java | 13 +- .../wikis/data/tbls/Xowd_search_word_tbl.java | 4 +- .../wikis/data/tbls/Xowd_wbase_qid_tbl.java | 8 +- .../data/tbls/Xowd_wbase_qid_tbl_tst.java | 47 ++++ .../domains/crts/Xow_domain_crt_itm_.java | 13 +- .../crts/Xow_domain_crt_itm_parser.java | 46 +++- .../crts/Xow_domain_crt_kv_itm_mgr.java | 67 +++++ .../domains/crts/Xow_domain_crt_kv_mgr.java | 45 --- .../gplx/xowa/wikis/xwikis/Xow_xwiki_itm.java | 2 + .../gplx/xowa/wikis/xwikis/Xow_xwiki_mgr.java | 11 + .../xowa/xtns/dynamicPageList/Dpl_itm.java | 2 +- .../xtns/dynamicPageList/Dpl_xnde_tst.java | 4 +- .../xtns/pfuncs/exprs/Pfunc_expr_ops.java | 3 +- .../xtns/pfuncs/exprs/Pfunc_expr_tst.java | 3 +- .../xowa/xtns/scribunto/Scrib_proc_rslt.java | 7 +- .../libs/Scrib_lib_language_tst.java | 9 +- .../scribunto/libs/Scrib_lib_title_tst.java | 2 +- .../xtns/translates/Xop_mylanguage_page.java | 1 + .../gplx/xowa/xtns/wdatas/Wdata_wiki_mgr.java | 43 +-- .../wdatas/imports/Xob_wdata_qid_base.java | 3 +- .../imports/Xob_wdata_qid_base_tst.java | 34 ++- .../wdatas/imports/Xow_wmf_api_wkr__ns.java | 15 +- .../xtns/wdatas/imports/Xowmf_site_tbl.java | 256 +++++++++++++++++- .../specials/Wdata_itemByTitle_page.java | 1 + 400_xowa/src/gplx/xowa2/apps/Xoav_app.java | 3 + .../gplx/xowa/Xof_xfer_queue.java | 3 +- .../gplx/threads/Gfo_thread_cmd_download.java | 2 +- .../gplx/xowa/Xoi_cmd_base.java | 2 +- .../gplx/xowa/Xoi_cmd_mgr.java | 2 +- .../gplx/xowa/Xoi_cmd_wiki.java | 2 +- .../gplx/xowa/Xoi_cmd_wiki_import.java | 2 +- .../gplx/xowa/Xoh_href_parser.java | 30 +- .../gplx/xowa/Xoh_href_parser_tst.java | 10 +- .../en.wikipedia.org-text.xowa | Bin 36864 -> 36864 bytes 126 files changed, 1840 insertions(+), 671 deletions(-) create mode 100644 140_dbs/src/gplx/dbs/Db_sql_select.java create mode 100644 400_xowa/src/gplx/xowa/apps/Xoa_thread_.java create mode 100644 400_xowa/src/gplx/xowa/files/bins/Xof_bin_skip_mgr.java create mode 100644 400_xowa/src/gplx/xowa/html/wtrs/Xoh_anchor_kv_bldr.java create mode 100644 400_xowa/src/gplx/xowa/html/wtrs/Xoh_img_path.java create mode 100644 400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_bldr.java create mode 100644 400_xowa/src/gplx/xowa/specials/Xows_special_meta.java create mode 100644 400_xowa/src/gplx/xowa/specials/Xows_special_meta_.java create mode 100644 400_xowa/src/gplx/xowa/specials/search/Xow_domain_sorter__manual_tid.java create mode 100644 400_xowa/src/gplx/xowa/specials/search/Xows_paging_parser.java create mode 100644 400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl_tst.java create mode 100644 400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_itm_mgr.java delete mode 100644 400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_mgr.java diff --git a/100_core/.classpath b/100_core/.classpath index 0240594b5..57d372839 100644 --- a/100_core/.classpath +++ b/100_core/.classpath @@ -5,7 +5,6 @@ - diff --git a/100_core/src_200_io/gplx/ios/IoEngine_system.java b/100_core/src_200_io/gplx/ios/IoEngine_system.java index 2f10e2125..674509b45 100644 --- a/100_core/src_200_io/gplx/ios/IoEngine_system.java +++ b/100_core/src_200_io/gplx/ios/IoEngine_system.java @@ -39,10 +39,7 @@ public class IoEngine_system extends IoEngine_base { @Override public void DeleteFil_api(IoEngine_xrg_deleteFil args) { Io_url url = args.Url(); File fil = Fil_(url); - if (!Fil_Exists(fil)) { - if (args.MissingFails()) throw IoErr.FileNotFound("delete", url); - else return; - } + if (!Fil_Exists(fil)) return; MarkFileWritable(fil, url, args.ReadOnlyFails(), "DeleteFile"); DeleteFil_lang(fil, url); } @@ -68,8 +65,8 @@ public class IoEngine_system extends IoEngine_base { // write text try {fc.write(ByteBuffer.wrap(textBytes));} catch (IOException e) { - Closeable_Close(fc, url, false); - Closeable_Close(fos, url, false); + Closeable_close(fc, url, false); + Closeable_close(fos, url, false); throw Err_.err_key_(e, IoEngineArgs._.Err_IoException, "write data to file failed").Add("url", url.Xto_api()); } if (!Op_sys.Cur().Tid_is_drd()) { @@ -79,11 +76,10 @@ public class IoEngine_system extends IoEngine_base { } finally { // cleanup - Closeable_Close(fc, url, false); - Closeable_Close(fos, url, false); + Closeable_close(fc, url, false); + Closeable_close(fos, url, false); } } - @SuppressWarnings("resource") @Override public String LoadFilStr(IoEngine_xrg_loadFilStr args) { Io_url url = args.Url(); String url_str = url.Xto_api(); boolean file_exists = ExistsFil_api(url); // check if file exists first to avoid throwing exception; note that most callers pass Missing_ignored; DATE:2015-02-24 @@ -104,7 +100,7 @@ public class IoEngine_system extends IoEngine_base { InputStreamReader reader = null; try {reader = new InputStreamReader(stream, IoEngineArgs._.LoadFilStr_Encoding);} catch (UnsupportedEncodingException e) { - Closeable_Close(stream, url_str, false); + Closeable_close(stream, url_str, false); throw Err_text_unsupported_encoding(IoEngineArgs._.LoadFilStr_Encoding, "", url_str, e); } @@ -117,8 +113,11 @@ public class IoEngine_system extends IoEngine_base { while (true) { try {pos = reader.read(readerBuffer);} catch (IOException e) { - Closeable_Close(stream, url_str, false); - Closeable_Close(reader, url_str, false); + try { + stream.close(); + reader.close(); + } + catch (IOException e2) {} throw Err_.err_key_(e, IoEngineArgs._.Err_IoException, "read data from file failed").Add("url", url_str).Add("pos", pos); } if (pos == -1) break; @@ -126,8 +125,8 @@ public class IoEngine_system extends IoEngine_base { } // cleanup - Closeable_Close(stream, url_str, false); - Closeable_Close(reader, url_str, false); + Closeable_close(stream, url_str, false); + Closeable_close(reader, url_str, false); return sw.toString(); } @Override public boolean ExistsDir(Io_url url) {return new File(url.Xto_api()).exists();} @@ -272,10 +271,10 @@ public class IoEngine_system extends IoEngine_base { while (pos < count) { try {read = trgChannel.transferFrom(srcChannel, pos, transferSize);} catch (IOException e) { - Closeable_Close(srcChannel, srcUrl, false); - Closeable_Close(trgChannel, trgUrl, false); - Closeable_Close(srcStream, srcUrl, false); - Closeable_Close(trgStream, srcUrl, false); + Closeable_close(srcChannel, srcUrl, false); + Closeable_close(trgChannel, trgUrl, false); + Closeable_close(srcStream, srcUrl, false); + Closeable_close(trgStream, srcUrl, false); throw Err_.err_key_(e, IoEngineArgs._.Err_IoException, "transfer data failed").Add("src", srcUrl.Xto_api()).Add("trg", trgUrl.Xto_api()); } if (read == -1) break; @@ -286,10 +285,10 @@ public class IoEngine_system extends IoEngine_base { } finally { // cleanup - Closeable_Close(srcChannel, srcUrl, false); - Closeable_Close(trgChannel, trgUrl, false); - Closeable_Close(srcStream, srcUrl, false); - Closeable_Close(trgStream, srcUrl, false); + Closeable_close(srcChannel, srcUrl, false); + Closeable_close(trgChannel, trgUrl, false); + Closeable_close(srcStream, srcUrl, false); + Closeable_close(trgStream, srcUrl, false); } UpdateFilModifiedTime(trgUrl, QueryFil(srcUrl).ModifiedTime()); // must happen after file is closed } @@ -356,8 +355,8 @@ public class IoEngine_system extends IoEngine_base { XferDir(IoEngine_xrg_xferDir.copy_(src, trg)); } } - protected static void Closeable_Close(Closeable closeable, Io_url url, boolean throwErr) {Closeable_Close(closeable, url.Xto_api(), throwErr);} - protected static void Closeable_Close(Closeable closeable, String url_str, boolean throwErr) { + protected static void Closeable_close(Closeable closeable, Io_url url, boolean throwErr) {Closeable_close(closeable, url.Xto_api(), throwErr);} + protected static void Closeable_close(Closeable closeable, String url_str, boolean throwErr) { if (closeable == null) return; try {closeable.close();} catch (IOException e) { diff --git a/100_core/src_200_io/gplx/ios/IoStream_.java b/100_core/src_200_io/gplx/ios/IoStream_.java index 570fd6491..c4edc8f6e 100644 --- a/100_core/src_200_io/gplx/ios/IoStream_.java +++ b/100_core/src_200_io/gplx/ios/IoStream_.java @@ -132,7 +132,7 @@ class IoStream_base implements IoStream { bfr.Clear(); } @gplx.Virtual public void Rls() { - IoEngine_system.Closeable_Close(under, url, true); + IoEngine_system.Closeable_close(under, url, true); } RandomAccessFile under; boolean mode_is_append; byte mode; public static IoStream_base rdr_wrapper_() {return new IoStream_base();} diff --git a/100_core/src_200_io/gplx/ios/Io_stream_wtr_.java b/100_core/src_200_io/gplx/ios/Io_stream_wtr_.java index 0f097907a..143b234b6 100644 --- a/100_core/src_200_io/gplx/ios/Io_stream_wtr_.java +++ b/100_core/src_200_io/gplx/ios/Io_stream_wtr_.java @@ -71,7 +71,6 @@ abstract class Io_stream_wtr_base implements Io_stream_wtr { public Io_url Url() {return url;} public Io_stream_wtr Url_(Io_url v) {url = v; trg_bfr = null; return this;} Io_url url; public void Trg_bfr_(Bry_bfr v) {trg_bfr = v;} Bry_bfr trg_bfr; java.io.ByteArrayOutputStream mem_stream; public byte[] Xto_ary_and_clear() {return trg_bfr.Xto_bry_and_clear();} - @SuppressWarnings("resource") // rely on OutputStream to close bry_stream public Io_stream_wtr Open() { java.io.OutputStream bry_stream = null; if (trg_bfr == null) { diff --git a/140_dbs/src/gplx/dbs/Db_conn_.java b/140_dbs/src/gplx/dbs/Db_conn_.java index 958beebb8..9bc6b00d7 100644 --- a/140_dbs/src/gplx/dbs/Db_conn_.java +++ b/140_dbs/src/gplx/dbs/Db_conn_.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.dbs; import gplx.*; import gplx.dbs.qrys.*; public class Db_conn_ { - public static final Db_conn Empty = Db_conn_pool.I.Get_or_new(Db_conn_info_.Null); + public static final Db_conn Noop = Db_conn_pool.I.Get_or_new(Db_conn_info_.Null); public static int Select_fld0_as_int_or(Db_conn p, String sql, int or) { DataRdr rdr = DataRdr_.Null; try { diff --git a/140_dbs/src/gplx/dbs/Db_conn_bldr.java b/140_dbs/src/gplx/dbs/Db_conn_bldr.java index 00b838685..d1a9b6fc9 100644 --- a/140_dbs/src/gplx/dbs/Db_conn_bldr.java +++ b/140_dbs/src/gplx/dbs/Db_conn_bldr.java @@ -28,5 +28,9 @@ public class Db_conn_bldr { Db_conn conn = exists ? Get(url) : New(url); return new Db_conn_bldr_data(conn, exists); } + public Db_conn Get_or_noop(Io_url url) { + Db_conn rv = wkr.Get(url); + return rv == null ? Db_conn_.Noop : rv; + } public static final Db_conn_bldr I = new Db_conn_bldr(); Db_conn_bldr() {} } diff --git a/140_dbs/src/gplx/dbs/Db_sql_select.java b/140_dbs/src/gplx/dbs/Db_sql_select.java new file mode 100644 index 000000000..b148e18da --- /dev/null +++ b/140_dbs/src/gplx/dbs/Db_sql_select.java @@ -0,0 +1,78 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.dbs; import gplx.*; +import gplx.core.criterias.*; +interface Db_sql_qry { + String Tbl_main(); +} +class Db_sql_qry__select { + public Db_sql_qry__select(String from) {this.from = from;} + public String From() {return from;} private final String from; + public Db_sql_col[] Select() {return select;} private Db_sql_col[] select; +// public Criteria Where() {return where;} private Criteria where; +// public Db_sql_col[] Group_bys() {return group_bys;} private Db_sql_col[] group_bys; +// public Db_sql_col[] Order_bys() {return order_bys;} private Db_sql_col[] order_bys; +// public int Limit() {return limit;} private int limit; +// public int Offset() {return offset;} private int offset; + public Db_sql_qry__select Select_all_() {this.select = Db_sql_col_.Ary(new Db_sql_col__all(0, from)); return this;} + public Db_sql_qry__select Select_flds_(String... ary) {this.select = Db_sql_col_bldr.I.new_fld_many(ary); return this;} + public static Db_sql_qry__select new_(String from) {return new Db_sql_qry__select(from);} +} +class Db_sql_bldr { + public void Test() { +// Db_sql_qry__select qry = null; +// qry = Db_sql_qry__select.new_("tbl").Select_all_(); +// qry = Db_sql_qry__select.new_("tbl").Select_flds_("fld1", "fld2"); +// qry = Db_sql_qry__select.new_("tbl").Select_flds_("fld1", "fld2").Where_("fld3"); +// , String_.Ary("col1", "col2"), String_.Ary("col3")).Limit_(10).; +// Db_sql_qry__select qry = Db_sql_qry__select_.new_("tbl").Cols_("col1", "col2").Where_eq_one("col3").Limit_(10); + } +} +interface Db_sql_col { + int Ord(); + String Alias(); +} +class Db_sql_col_ { + public static Db_sql_col[] Ary(Db_sql_col... v) {return v;} +} +class Db_sql_col_bldr { + private final ListAdp tmp_list = ListAdp_.new_(); + public Db_sql_col[] new_fld_many(String[] ary) { + tmp_list.Clear(); + int ord = -1; + for (int i = 0; i < ary.length; ++i) { + String fld_key = ary[i]; + if (fld_key == Db_meta_fld.Key_null) continue; + Db_sql_col__name fld = new Db_sql_col__name(++ord, fld_key); + tmp_list.Add(fld); + } + return (Db_sql_col[])tmp_list.Xto_ary_and_clear(Db_sql_col.class); + } + public static final Db_sql_col_bldr I = new Db_sql_col_bldr(); Db_sql_col_bldr() {} +} +class Db_sql_col__name { + public Db_sql_col__name(int ord, String key) {this.ord = ord; this.key = key;} + public int Ord() {return ord;} private final int ord; + public String Key() {return key;} private final String key; +} +class Db_sql_col__all implements Db_sql_col { + public Db_sql_col__all(int ord, String tbl) {this.ord = ord; this.tbl = tbl;} + public int Ord() {return ord;} private final int ord; + public String Tbl() {return tbl;} private final String tbl; + public String Alias() {return "*";} +} diff --git a/150_gfui/src_700_env/gplx/gfui/Swt_kit.java b/150_gfui/src_700_env/gplx/gfui/Swt_kit.java index 184f1a4e1..834b66460 100644 --- a/150_gfui/src_700_env/gplx/gfui/Swt_kit.java +++ b/150_gfui/src_700_env/gplx/gfui/Swt_kit.java @@ -311,10 +311,12 @@ class Swt_gui_cmd implements GfuiInvkCmd, Runnable { return this; } @Override public void run() { - try {target.Invk(invk_ctx, invk_ikey, invk_key, invk_msg);} - catch (Exception e) { - if (kit.Kit_mode__term()) return; // NOTE: if shutting down, don't warn; warn will try to write to status.bar, which will fail b/c SWT is shutting down; failures will try to write to status.bar again, causing StackOverflow exception; DATE:2014-05-04 - usr_dlg.Warn_many("", "", "fatal error while running; key=~{0} err=~{1}", invk_key, Err_.Message_gplx_brief(e)); + synchronized (this) {// needed for Special:Search and async; DATE:2015-04-23 + try {target.Invk(invk_ctx, invk_ikey, invk_key, invk_msg);} + catch (Exception e) { + if (kit.Kit_mode__term()) return; // NOTE: if shutting down, don't warn; warn will try to write to status.bar, which will fail b/c SWT is shutting down; failures will try to write to status.bar again, causing StackOverflow exception; DATE:2014-05-04 + usr_dlg.Warn_many("", "", "fatal error while running; key=~{0} err=~{1}", invk_key, Err_.Message_gplx_brief(e)); + } } } public void Rls() { diff --git a/400_xowa/src/gplx/core/brys/Bry_rdr.java b/400_xowa/src/gplx/core/brys/Bry_rdr.java index 1706e9200..1e54f48b4 100644 --- a/400_xowa/src/gplx/core/brys/Bry_rdr.java +++ b/400_xowa/src/gplx/core/brys/Bry_rdr.java @@ -61,6 +61,7 @@ public class Bry_rdr { return bgn == pos ? or_int : rv * negative; } public byte[] Read_bry_to_nl() {return Read_bry_to(Byte_ascii.NewLine);} + public byte[] Read_bry_to_semic() {return Read_bry_to(Byte_ascii.Semic);} public byte[] Read_bry_to_pipe() {return Read_bry_to(Byte_ascii.Pipe);} public byte[] Read_bry_to_quote() {return Read_bry_to(Byte_ascii.Quote);} public byte[] Read_bry_to_apos() {return Read_bry_to(Byte_ascii.Apos);} diff --git a/400_xowa/src/gplx/dbs/Db_attach_rdr.java b/400_xowa/src/gplx/dbs/Db_attach_rdr.java index 69c977237..d6c037ffe 100644 --- a/400_xowa/src/gplx/dbs/Db_attach_rdr.java +++ b/400_xowa/src/gplx/dbs/Db_attach_rdr.java @@ -25,14 +25,16 @@ public class Db_attach_rdr { Sqlite_conn_info conn_info = (Sqlite_conn_info)conn.Conn_info(); this.diff_db = !String_.Eq(conn_info.Url().Raw(), attach_url.Raw()); } - public Db_rdr Exec_as_rdr(String sql) { + public void Attach() { try { if (diff_db) conn.Env_db_attach(attach_name, attach_url); - } catch (Exception e) {Err_.Noop(e); Gfo_usr_dlg_.I.Warn_many("", "", "db:failed to attach db; name=~{0} url=~{1}", attach_name, attach_url.Raw());} + } catch (Exception e) {Err_.Noop(e); Gfo_usr_dlg_.I.Warn_many("", "", "db:failed to attach db; name=~{0} url=~{1}", attach_name, attach_url.Raw());} + } + public Db_rdr Exec_as_rdr(String sql) { sql = String_.Replace(sql, "", diff_db ? attach_name + "." : ""); // replace with either "attach_db." or ""; return conn.Exec_sql_as_rdr2(sql); } - public void Rls() { + public void Detach() { if (diff_db) conn.Env_db_detach(attach_name); } } diff --git a/400_xowa/src/gplx/dbs/cfgs/Db_cfg_tbl.java b/400_xowa/src/gplx/dbs/cfgs/Db_cfg_tbl.java index 08dfa5090..981a5545b 100644 --- a/400_xowa/src/gplx/dbs/cfgs/Db_cfg_tbl.java +++ b/400_xowa/src/gplx/dbs/cfgs/Db_cfg_tbl.java @@ -60,6 +60,7 @@ public class Db_cfg_tbl implements RlsAble { if (stmt_update == null) stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_grp, fld_key); stmt_update.Clear().Val_str(fld_val, val).Crt_str(fld_grp, grp).Crt_str(fld_key, key).Exec_update(); } + public void Upsert_yn (String grp, String key, boolean val) {Upsert_str(grp, key, val ? "y" : "n");} public void Upsert_int (String grp, String key, int val) {Upsert_str(grp, key, Int_.Xto_str(val));} public void Upsert_str (String grp, String key, String val) { String cur_val = this.Select_str_or(grp, key, null); diff --git a/400_xowa/src/gplx/dbs/schemas/updates/Schema_update_mgr_tst.java b/400_xowa/src/gplx/dbs/schemas/updates/Schema_update_mgr_tst.java index 11d924185..c5574a051 100644 --- a/400_xowa/src/gplx/dbs/schemas/updates/Schema_update_mgr_tst.java +++ b/400_xowa/src/gplx/dbs/schemas/updates/Schema_update_mgr_tst.java @@ -40,7 +40,7 @@ class Schema_update_mgr_fxt { public void Test_exec_n(Schema_update_cmd cmd) {Test_exec(cmd, Bool_.N);} private void Test_exec(Schema_update_cmd cmd, boolean expd) { update_mgr.Add(cmd); - update_mgr.Update(db_mgr, Db_conn_.Empty); + update_mgr.Update(db_mgr, Db_conn_.Noop); Tfds.Eq(expd, cmd.Exec_is_done()); } } diff --git a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr_.java b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr_.java index 412252453..437ff48fa 100644 --- a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr_.java +++ b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr_.java @@ -40,7 +40,7 @@ public class Fsdb_db_mgr_ { Db_conn main_core_conn = Db_conn_bldr.I.Get(main_core_url); Io_url user_core_url = wiki_dir.GenSubFil(Fsdb_db_mgr__v2_bldr.Make_user_name(domain_str)); if (!Db_conn_bldr.I.Exists(user_core_url)) // if user file does not exist, create it; needed b/c offline packages don't include file; DATE:2015-04-19 - Fsdb_db_mgr__v2_bldr.I.Make_core_file_user(wiki, wiki_dir, user_core_url.NameAndExt(), main_core_url.NameAndExt()); + Fsdb_db_mgr__v2_bldr.I.Make_core_file_user(wiki, user_core_url, user_core_url.NameAndExt(), main_core_url.NameAndExt()); Db_conn user_core_conn = Db_conn_bldr.I.Get(user_core_url); return new Fsdb_db_mgr__v2(Fsdb_db_mgr__v2.Cfg__layout_file__get(main_core_conn), wiki_dir, new Fsdb_db_file(main_core_url, main_core_conn), new Fsdb_db_file(user_core_url, user_core_conn)); } diff --git a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v1.java b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v1.java index 165b210ac..b7fed59ed 100644 --- a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v1.java +++ b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v1.java @@ -16,19 +16,21 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.fsdb; import gplx.*; -import gplx.dbs.*; import gplx.fsdb.meta.*; import gplx.xowa.files.origs.*; +import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.fsdb.meta.*; import gplx.fsdb.data.*; import gplx.xowa.files.origs.*; public class Fsdb_db_mgr__v1 implements Fsdb_db_mgr { private final Io_url file_dir; private final Fsdb_db_file orig_file, mnt_file, abc_file__main, abc_file__user, atr_file__main, atr_file__user; private final Xof_orig_tbl[] orig_tbl_ary; public Fsdb_db_mgr__v1(Io_url file_dir) { this.file_dir = file_dir; - this.orig_file = new_db(file_dir.GenSubFil(Orig_name)); // EX: /xowa/enwiki/wiki.orig#00.sqlite3 - this.mnt_file = new_db(file_dir.GenSubFil(Mnt_name)); // EX: /xowa/enwiki/wiki.mnt.sqlite3 - this.abc_file__main = new_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_main, Abc_name)); // EX: /xowa/enwiki/fsdb.main/fsdb.abc.sqlite3 - this.atr_file__main = new_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_main, Atr_name)); // EX: /xowa/enwiki/fsdb.main/fsdb.atr.00.sqlite3 - this.abc_file__user = new_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_user, Abc_name)); // EX: /xowa/enwiki/fsdb.user/fsdb.abc.sqlite3 - this.atr_file__user = new_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_user, Atr_name)); // EX: /xowa/enwiki/fsdb.user/fsdb.atr.00.sqlite3 + this.orig_file = get_db(file_dir.GenSubFil(Orig_name)); // EX: /xowa/enwiki/wiki.orig#00.sqlite3 + this.mnt_file = get_db(file_dir.GenSubFil(Mnt_name)); // EX: /xowa/enwiki/wiki.mnt.sqlite3 + this.abc_file__main = get_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_main, Abc_name)); // EX: /xowa/enwiki/fsdb.main/fsdb.abc.sqlite3 + this.atr_file__main = get_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_main, Atr_name)); // EX: /xowa/enwiki/fsdb.main/fsdb.atr.00.sqlite3 + if (Db_conn_bldr.I.Get(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_user, Abc_name)) == null) // user doesn't exist; create; DATE:2015-04-20 + Fsdb_db_mgr__v1_bldr.I.Make_core_dir(file_dir, Fsm_mnt_mgr.Mnt_idx_user, Fsm_mnt_tbl.Mnt_name_user); + this.abc_file__user = get_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_user, Abc_name)); // EX: /xowa/enwiki/fsdb.user/fsdb.abc.sqlite3 + this.atr_file__user = get_db(file_dir.GenSubFil_nest(Fsm_mnt_tbl.Mnt_name_user, Atr_name)); // EX: /xowa/enwiki/fsdb.user/fsdb.atr.00.sqlite3 this.orig_tbl_ary = new Xof_orig_tbl[] {new Xof_orig_tbl(orig_file.Conn(), this.File__schema_is_1())}; } public boolean File__schema_is_1() {return Bool_.Y;} @@ -46,5 +48,34 @@ public class Fsdb_db_mgr__v1 implements Fsdb_db_mgr { } public Fsdb_db_file File__bin_file__new(int mnt_id, String file_name) {throw Err_.not_implemented_();} public static final String Orig_name = "wiki.orig#00.sqlite3", Mnt_name = "wiki.mnt.sqlite3", Abc_name = "fsdb.abc.sqlite3", Atr_name= "fsdb.atr.00.sqlite3"; - private static Fsdb_db_file new_db(Io_url file) {return new Fsdb_db_file(file, Db_conn_bldr.I.Get(file));} + private static Fsdb_db_file get_db(Io_url file) { + Db_conn conn = Db_conn_bldr.I.Get(file); + if (conn == null) conn = Db_conn_.Noop; + return new Fsdb_db_file(file, conn); + } +} +class Fsdb_db_mgr__v1_bldr { + public void Make_core_dir(Io_url file_dir, int mnt_id, String mnt_name) { + boolean schema_is_1 = true; + Io_url mnt_dir = file_dir.GenSubDir(mnt_name); + // make abc_fil + Fsdb_db_file db_abc = new_db(mnt_dir.GenSubFil(Fsdb_db_mgr__v1.Abc_name)); + Db_cfg_tbl cfg_tbl = new Db_cfg_tbl(db_abc.Conn(), "fsdb_cfg"); cfg_tbl.Create_tbl(); + Fsm_mnt_mgr.Patch(cfg_tbl); + Fsm_mnt_mgr.Patch_core(cfg_tbl); + Fsm_atr_tbl dba_tbl = new Fsm_atr_tbl(db_abc.Conn(), schema_is_1); dba_tbl.Create_tbl(); + dba_tbl.Insert(mnt_id, mnt_name); + Fsm_bin_tbl dbb_tbl = new Fsm_bin_tbl(db_abc.Conn(), schema_is_1, mnt_id); dbb_tbl.Create_tbl(); + dbb_tbl.Insert(0, "fsdb.bin.0000.sqlite3"); + // make atr_fil + Fsdb_db_file db_atr = new_db(mnt_dir.GenSubFil(Fsdb_db_mgr__v1.Atr_name)); + Fsd_dir_tbl dir_tbl = new Fsd_dir_tbl(db_atr.Conn(), schema_is_1); dir_tbl.Create_tbl(); + Fsd_fil_tbl fil_tbl = new Fsd_fil_tbl(db_atr.Conn(), schema_is_1, mnt_id); fil_tbl.Create_tbl(); + Fsd_thm_tbl thm_tbl = new Fsd_thm_tbl(db_atr.Conn(), schema_is_1, mnt_id, Bool_.Y); thm_tbl.Create_tbl(); + // make bin_fil + Fsdb_db_file db_bin = new_db(mnt_dir.GenSubFil("fsdb.bin.0000.sqlite3")); + Fsd_bin_tbl bin_tbl = new Fsd_bin_tbl(db_bin.Conn(), schema_is_1); bin_tbl.Create_tbl(); + } + private Fsdb_db_file new_db(Io_url url) {return new Fsdb_db_file(url, Db_conn_bldr.I.New(url));} + public static final Fsdb_db_mgr__v1_bldr I = new Fsdb_db_mgr__v1_bldr(); Fsdb_db_mgr__v1_bldr() {} } diff --git a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2.java b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2.java index 802f446a3..09134af7f 100644 --- a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2.java +++ b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2.java @@ -43,7 +43,7 @@ public class Fsdb_db_mgr__v2 implements Fsdb_db_mgr { Db_conn conn = Db_conn_bldr.I.Get(url); if (conn == null) { // bin file deleted or not downloaded; use Noop Db_conn and continue; do not fail; DATE:2015-04-16 Gfo_usr_dlg_.I.Warn_many("", "", "fsdb.bin:file does not exist; url=~{0}", url); - conn = Db_conn_.Empty; + conn = Db_conn_.Noop; } return new Fsdb_db_file(url, conn); } diff --git a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2_bldr.java b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2_bldr.java index f6e2f8789..55665af29 100644 --- a/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2_bldr.java +++ b/400_xowa/src/gplx/fsdb/Fsdb_db_mgr__v2_bldr.java @@ -19,31 +19,38 @@ package gplx.fsdb; import gplx.*; import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.fsdb.meta.*; import gplx.fsdb.data.*; import gplx.xowa.files.origs.*; import gplx.xowa.*; import gplx.xowa.wikis.data.*; import gplx.xowa.bldrs.infos.*; public class Fsdb_db_mgr__v2_bldr { - public Fsdb_db_mgr__v2 Make(Xowe_wiki wiki) { + public Fsdb_db_mgr__v2 Make(Xowe_wiki wiki, boolean delete_if_exists) { Xowd_db_layout layout = wiki.Data_mgr__core_mgr().Props().Layout_file(); String domain_str = wiki.Domain_str(); Io_url wiki_dir = wiki.Fsys_mgr().Root_dir(); String main_core_name = Main_core_name(layout, domain_str); - Fsdb_db_file main_core_file = Make_core_file_main(wiki, wiki_dir, main_core_name, layout); - Fsdb_db_file user_core_file = Make_core_file_user(wiki, wiki_dir, Make_user_name(domain_str), main_core_name); + String user_core_name = Make_user_name(domain_str); + Io_url main_core_url = wiki_dir.GenSubFil(main_core_name); + Io_url user_core_url = wiki_dir.GenSubFil(user_core_name); + if (delete_if_exists) { + Db_conn_bldr.I.Get_or_noop(main_core_url).Rls_conn(); + Db_conn_bldr.I.Get_or_noop(user_core_url).Rls_conn(); + Io_mgr._.DeleteFil(main_core_url); + Io_mgr._.DeleteFil(user_core_url); + } + Fsdb_db_file main_core_file = Make_core_file_main(wiki, main_core_url, main_core_name, layout); + Fsdb_db_file user_core_file = Make_core_file_user(wiki, user_core_url, user_core_name, main_core_name); return new Fsdb_db_mgr__v2(layout, wiki_dir, main_core_file, user_core_file); } - private Fsdb_db_file Make_core_file_main(Xowe_wiki wiki, Io_url wiki_dir, String main_core_name, Xowd_db_layout layout) { - Io_url url = wiki_dir.GenSubFil(main_core_name); - Db_conn conn = layout.Tid_is_all() ? Db_conn_bldr.I.Get(url) : Db_conn_bldr.I.New(url); // if all, use existing (assumes same file name); else, create new + private Fsdb_db_file Make_core_file_main(Xowe_wiki wiki, Io_url main_core_url, String main_core_name, Xowd_db_layout layout) { + Db_conn conn = layout.Tid_is_all() ? Db_conn_bldr.I.Get(main_core_url) : Db_conn_bldr.I.New(main_core_url); // if all, use existing (assumes same file name); else, create new conn.Txn_bgn(); - Fsdb_db_file rv = Make_core_file(url, conn, schema_is_1, Fsm_mnt_mgr.Mnt_idx_main); + Fsdb_db_file rv = Make_core_file(main_core_url, conn, schema_is_1, Fsm_mnt_mgr.Mnt_idx_main); if (!layout.Tid_is_all()) // do not make cfg data if all Make_cfg_data(wiki, main_core_name, rv, Main_core_tid(layout), -1); Fsdb_db_mgr__v2.Cfg__layout_file__set(rv.Tbl__cfg(), layout); conn.Txn_end(); return rv; } - public Fsdb_db_file Make_core_file_user(Xow_wiki wiki, Io_url wiki_dir, String user_file_name, String main_core_name) { // always create file; do not create mnt_tbl; - Io_url url = wiki_dir.GenSubFil(user_file_name); - Db_conn conn = Db_conn_bldr.I.New(url); + public Fsdb_db_file Make_core_file_user(Xow_wiki wiki, Io_url user_core_url, String user_file_name, String main_core_name) { // always create file; do not create mnt_tbl; + Db_conn conn = Db_conn_bldr.I.New(user_core_url); conn.Txn_bgn(); - Fsdb_db_file rv = Make_core_file(url, conn, schema_is_1, Fsm_mnt_mgr.Mnt_idx_user); + Fsdb_db_file rv = Make_core_file(user_core_url, conn, schema_is_1, Fsm_mnt_mgr.Mnt_idx_user); Fsm_bin_tbl dbb_tbl = new Fsm_bin_tbl(conn, schema_is_1, Fsm_mnt_mgr.Mnt_idx_user); dbb_tbl.Insert(0, user_file_name); Make_bin_tbl(rv); Make_cfg_data(wiki, main_core_name, rv, Xowd_db_file_.Tid_file_user, -1); diff --git a/400_xowa/src/gplx/fsdb/meta/Fsm_mnt_mgr.java b/400_xowa/src/gplx/fsdb/meta/Fsm_mnt_mgr.java index 05d42096d..54d0d3387 100644 --- a/400_xowa/src/gplx/fsdb/meta/Fsm_mnt_mgr.java +++ b/400_xowa/src/gplx/fsdb/meta/Fsm_mnt_mgr.java @@ -48,5 +48,10 @@ public class Fsm_mnt_mgr implements GfoInvkAble { cfg_tbl.Upsert_str(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_upright_use_thumb_w , "y"); cfg_tbl.Upsert_str(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_upright_fix_default , "y"); } + public static void Patch_core(Db_cfg_tbl cfg_tbl) { + cfg_tbl.Insert_int (Fsm_cfg_mgr.Grp_core, Fsm_cfg_mgr.Key_next_id , 1); // start next_id at 1 + cfg_tbl.Insert_yn (Fsm_cfg_mgr.Grp_core, Fsm_cfg_mgr.Key_schema_thm_page , Bool_.Y); // new dbs automatically have page and time in fsdb_xtn_tm + cfg_tbl.Insert_yn (Fsm_cfg_mgr.Grp_core, Fsm_cfg_mgr.Key_patch_next_id , Bool_.Y); // new dbs automatically have correct next_id + } public static final String Cfg_grp_core = "core", Cfg_key_mnt_insert_idx = "mnt.insert_idx"; // SERIALIZED } diff --git a/400_xowa/src/gplx/xowa/Xoa_app.java b/400_xowa/src/gplx/xowa/Xoa_app.java index 8780b2d61..349c5f50c 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app.java +++ b/400_xowa/src/gplx/xowa/Xoa_app.java @@ -28,5 +28,6 @@ public interface Xoa_app { Gfo_usr_dlg Usr_dlg(); Bry_bfr_mkr Utl__bfr_mkr(); Url_encoder_mgr Utl__encoder_mgr(); + Xoh_href_parser Html__href_parser(); boolean Xwiki_mgr__missing(byte[] domain); } diff --git a/400_xowa/src/gplx/xowa/Xoa_app_.java b/400_xowa/src/gplx/xowa/Xoa_app_.java index 48959a9b8..cf6e4822b 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app_.java +++ b/400_xowa/src/gplx/xowa/Xoa_app_.java @@ -26,7 +26,7 @@ public class Xoa_app_ { boot_mgr.Run(args); } public static final String Name = "xowa"; - public static final String Version = "2.4.3.1"; + public static final String Version = "2.4.4.1"; public static String Build_date = "2012-12-30 00:00:00"; public static String Op_sys; public static String User_agent = ""; diff --git a/400_xowa/src/gplx/xowa/Xoae_app.java b/400_xowa/src/gplx/xowa/Xoae_app.java index e19e0f063..6de4b587f 100644 --- a/400_xowa/src/gplx/xowa/Xoae_app.java +++ b/400_xowa/src/gplx/xowa/Xoae_app.java @@ -64,6 +64,7 @@ public class Xoae_app implements Xoa_app, GfoInvkAble { public Xoa_fsys_mgr Fsys_mgr() {return fsys_mgr;} private final Xoa_fsys_mgr fsys_mgr; public Xof_cache_mgr File_mgr__cache_mgr() {return file_mgr.Cache_mgr();} public Xof_img_mgr File_mgr__img_mgr() {return file_mgr.Img_mgr();} + public Xoh_href_parser Html__href_parser() {return href_parser;} private Xoh_href_parser href_parser; public Xowmf_mgr Wmf_mgr() {return wmf_mgr;} private final Xowmf_mgr wmf_mgr = new Xowmf_mgr(); public Bry_bfr_mkr Utl__bfr_mkr() {return Xoa_app_.Utl__bfr_mkr();} public Url_encoder_mgr Utl__encoder_mgr() {return Xoa_app_.Utl__encoder_mgr();} @@ -90,7 +91,7 @@ public class Xoae_app implements Xoa_app, GfoInvkAble { public Xoa_thread_mgr Thread_mgr() {return thread_mgr;} private Xoa_thread_mgr thread_mgr = new Xoa_thread_mgr(); public Xoa_hive_mgr Hive_mgr() {return hive_mgr;} private Xoa_hive_mgr hive_mgr; public Xoa_url_parser Url_parser() {return url_parser;} private Xoa_url_parser url_parser = new Xoa_url_parser(); - public Xoh_href_parser Href_parser() {return href_parser;} private Xoh_href_parser href_parser; + public Xoh_href_parser Href_parser() {return href_parser;} public Xop_sanitizer Sanitizer() {return sanitizer;} private Xop_sanitizer sanitizer; public Xop_xatr_parser Xatr_parser() {return xatr_parser;} private Xop_xatr_parser xatr_parser = new Xop_xatr_parser(); public Xop_xnde_tag_regy Xnde_tag_regy() {return xnde_tag_regy;} private Xop_xnde_tag_regy xnde_tag_regy = new Xop_xnde_tag_regy(); diff --git a/400_xowa/src/gplx/xowa/apis/xowa/html/modules/Xoapi_popups.java b/400_xowa/src/gplx/xowa/apis/xowa/html/modules/Xoapi_popups.java index f137bebef..8ff10c54d 100644 --- a/400_xowa/src/gplx/xowa/apis/xowa/html/modules/Xoapi_popups.java +++ b/400_xowa/src/gplx/xowa/apis/xowa/html/modules/Xoapi_popups.java @@ -184,7 +184,7 @@ public class Xoapi_popups implements GfoInvkAble, GfoEvMgrOwner { ; public static final byte[] Dflt_xnde_ignore_ids = Bry_.new_ascii_("coordinates") - , Dflt_tmpl_keeplist = Bry_.new_ascii_("en.wikipedia.org|formatnum;age;age_in_days;age_in_years_and_days*;nts;number_table_sorting*;as_of;oldstyledatedy;gregorian_serial_date;currentminute;currentsecond;dmca;spaced_ndash;trim;month*;convert*;worldpop*;ipa*;lang*;nowrap*;h:*;mvar;math;vgy;audio;iso_639_name;transl;translate;linktext;zh;nihongo*;japanese_name;ko-hhrm|\n") + , Dflt_tmpl_keeplist = Bry_.new_ascii_("en.wikipedia.org|formatnum;age;age_in_days;age_in_years_and_days*;nts;number_table_sorting*;as_of;oldstyledatedy;gregorian_serial_date;currentminute;currentsecond;dmca;spaced_ndash;trim;month*;convert*;worldpop*;ipa*;lang*;nowrap*;h:*;mvar;math;vgy;audio;iso_639_name;transl;translate;linktext;zh;nihongo*;japanese_name;ko-hhrm;mp|\n") , Dflt_html_fmtr_popup = Bry_.new_ascii_(String_.Concat_lines_nl_skip_last ( "
" , "
~{content}" diff --git a/400_xowa/src/gplx/xowa/apis/xowa/specials/Xoapi_search.java b/400_xowa/src/gplx/xowa/apis/xowa/specials/Xoapi_search.java index 4e09ff94f..422764180 100644 --- a/400_xowa/src/gplx/xowa/apis/xowa/specials/Xoapi_search.java +++ b/400_xowa/src/gplx/xowa/apis/xowa/specials/Xoapi_search.java @@ -18,37 +18,56 @@ along with this program. If not, see . package gplx.xowa.apis.xowa.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.apis.*; import gplx.xowa.apis.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.domains.crts.*; public class Xoapi_search implements GfoInvkAble, GfoEvMgrOwner { - private final Xow_domain_crt_kv_mgr multi_wiki_rules_mgr = new Xow_domain_crt_kv_mgr(); private String multi_wiki_rules_str = "*.*|"; + private final Xow_domain_crt_kv_itm_mgr multi_wikis_mgr = new Xow_domain_crt_kv_itm_mgr(); private byte[] multi_wikis_bry = Dflt_multi_wikis_bry; + private final Xow_domain_crt_kv_itm_mgr multi_sorts_mgr = new Xow_domain_crt_kv_itm_mgr(); private byte[] multi_sorts_bry = Dflt_multi_sorts_bry; public Xoapi_search() { this.evMgr = GfoEvMgr.new_(this); + multi_wikis_mgr.Parse_as_itms(multi_wikis_bry); + multi_sorts_mgr.Parse_as_arys(multi_sorts_bry); } public GfoEvMgr EvMgr() {return evMgr;} private GfoEvMgr evMgr; public int Results_per_page() {return results_per_page;} private int results_per_page = 20; public boolean Async_db() {return async_db;} private boolean async_db = true; - public void Multi_wiki_rule_str_(String v) { - if (!multi_wiki_rules_mgr.Parse(Bry_.new_utf8_(v))) return; - this.multi_wiki_rules_str = v; - GfoEvMgr_.PubVal(this, Evt_multi_wiki_rules_changed, v); + public void Multi_wikis_bry_(byte[] v) { + if (!multi_wikis_mgr.Parse_as_itms(v)) return; + this.multi_wikis_bry = v; + GfoEvMgr_.PubVal(this, Evt_multi_wikis_changed, v); } - public Xow_domain_crt_itm Multi_wiki_crt(Xow_domain cur_domain) { - return multi_wiki_rules_mgr.Find(cur_domain, cur_domain); + public Xow_domain_crt_itm Multi_wikis_crt(Xow_domain cur_domain) { + return multi_wikis_mgr.Find_itm(cur_domain, cur_domain); + } + public void Multi_sorts_bry_(byte[] v) { + if (!multi_sorts_mgr.Parse_as_arys(v)) return; + this.multi_sorts_bry = v; + GfoEvMgr_.PubVal(this, Evt_multi_sorts_changed, v); + } + public Xow_domain_crt_itm[] Multi_sorts_crt(Xow_domain cur_domain) { + return multi_sorts_mgr.Find_ary(cur_domain, cur_domain); } public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_results_per_page)) return results_per_page; else if (ctx.Match(k, Invk_results_per_page_)) results_per_page = m.ReadInt("v"); else if (ctx.Match(k, Invk_async_db)) return Yn.Xto_str(async_db); else if (ctx.Match(k, Invk_async_db_)) async_db = m.ReadYn("v"); - else if (ctx.Match(k, Invk_multi_wiki_rules)) return multi_wiki_rules_str; - else if (ctx.Match(k, Invk_multi_wiki_rules_)) multi_wiki_rules_str = m.ReadStr("v"); + else if (ctx.Match(k, Invk_multi_wikis)) return String_.new_utf8_(multi_wikis_bry); + else if (ctx.Match(k, Invk_multi_wikis_)) Multi_wikis_bry_(m.ReadBry("v")); + else if (ctx.Match(k, Invk_multi_sorts)) return String_.new_utf8_(multi_sorts_bry); + else if (ctx.Match(k, Invk_multi_sorts_)) Multi_sorts_bry_(m.ReadBry("v")); else return GfoInvkAble_.Rv_unhandled; return this; } private static final String Invk_results_per_page = "results_per_page" , Invk_results_per_page_ = "results_per_page_" , Invk_async_db = "async_db" , Invk_async_db_ = "async_db_" - , Invk_multi_wiki_rules = "multi_wiki_rules" , Invk_multi_wiki_rules_ = "multi_wiki_rules_" + , Invk_multi_wikis = "multi_wikis" , Invk_multi_wikis_ = "multi_wikis_" + , Invk_multi_sorts = "multi_sorts" , Invk_multi_sorts_ = "multi_sorts_" ; public static final String - Evt_multi_wiki_rules_changed = "multi_wiki_rules_changed" + Evt_multi_wikis_changed = "multi_wikis_changed" + , Evt_multi_sorts_changed = "multi_sorts_changed" + ; + public static final byte[] + Dflt_multi_wikis_bry = Bry_.new_ascii_("|") + , Dflt_multi_sorts_bry = Bry_.new_ascii_("|,*.wikipedia,*.wikivoyage,*.wiktionary,*.wikisource,*.wikiquote,*.wikibooks,*.wikiversity,*.wikinews") ; } diff --git a/400_xowa/src/gplx/xowa/apis/xowa/startups/tabs/Xoapi_startup_tabs.java b/400_xowa/src/gplx/xowa/apis/xowa/startups/tabs/Xoapi_startup_tabs.java index 46d3a6dd7..076443bb5 100644 --- a/400_xowa/src/gplx/xowa/apis/xowa/startups/tabs/Xoapi_startup_tabs.java +++ b/400_xowa/src/gplx/xowa/apis/xowa/startups/tabs/Xoapi_startup_tabs.java @@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.apis.xowa.startups.tabs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apis.*; import gplx.xowa.apis.xowa.*; import gplx.xowa.apis.xowa.startups.*; +import gplx.xowa.specials.*; public class Xoapi_startup_tabs implements GfoInvkAble { public String Custom() {return custom;} private String custom; public boolean Custom_is_expr() {return custom_is_expr;} private boolean custom_is_expr; @@ -46,7 +47,7 @@ public class Xoapi_startup_tabs implements GfoInvkAble { String xowa_home = gplx.xowa.users.Xouc_pages_mgr.Page_xowa; if (manual == null) { switch (type) { - case Xoapi_startup_tabs_tid_.Tid_blank: rv.Add(gplx.xowa.specials.xowa.default_tab.Default_tab_page.Ttl_full_str); break; + case Xoapi_startup_tabs_tid_.Tid_blank: rv.Add(Xows_special_meta_.Itm__default_tab.Ttl_str()); break; case Xoapi_startup_tabs_tid_.Tid_xowa: rv.Add(xowa_home); break; case Xoapi_startup_tabs_tid_.Tid_custom: Add_ary(rv, custom); break; case Xoapi_startup_tabs_tid_.Tid_previous: Add_ary(rv, previous); break; diff --git a/400_xowa/src/gplx/xowa/apps/Xoa_thread_.java b/400_xowa/src/gplx/xowa/apps/Xoa_thread_.java new file mode 100644 index 000000000..682dbed70 --- /dev/null +++ b/400_xowa/src/gplx/xowa/apps/Xoa_thread_.java @@ -0,0 +1,30 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.apps; import gplx.*; import gplx.xowa.*; +public class Xoa_thread_ { + public static final String + Key_page_async = "xowa.page.async" + , Key_page_redlink = "xowa.page.redlink" + , Key_page_popup = "xowa.page.popup" + , Key_http_server_main = "xowa.http_server.main" + , Key_bldr_download = "xowa.bldr.download" + , Key_special_search_db = "xowa.special.search.db" + , Key_special_search_cancel = "xowa.special.search.cancel" + , Key_special_suggest = "xowa.special.suggest" + ; +} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java b/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java index 8b390e3ea..489eb56b9 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_dump_mgr_base.java @@ -180,6 +180,7 @@ public abstract class Xob_dump_mgr_base extends Xob_itm_basic_base implements Xo gplx.xowa.xtns.scribunto.Scrib_core.Core_invalidate(); wiki.Cache_mgr().Free_mem_all(); } + protected void Reset_db_y_() {this.reset_db = true;} @Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_commit_interval_)) commit_interval = m.ReadInt("v"); else if (ctx.Match(k, Invk_progress_interval_)) progress_interval = m.ReadInt("v"); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_fsdb_make_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_fsdb_make_cmd.java index 1822f09d5..fc9e3f524 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_fsdb_make_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_fsdb_make_cmd.java @@ -22,7 +22,7 @@ import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.files import gplx.fsdb.data.*; import gplx.fsdb.meta.*; public class Xob_fsdb_make_cmd extends Xob_itm_basic_base implements Xob_cmd { private Db_conn bldr_conn; private Db_cfg_tbl bldr_cfg_tbl; - private Xof_bin_mgr src_bin_mgr; private Xof_bin_wkr__fsdb_sql src_fsdb_wkr; private boolean src_bin_mgr__cache_enabled = Bool_.N; private String src_bin_mgr__fsdb_version; private boolean src_bin_mgr__wmf_enabled; + private Xof_bin_mgr src_bin_mgr; private Xof_bin_wkr__fsdb_sql src_fsdb_wkr; private boolean src_bin_mgr__cache_enabled = Bool_.N; private String src_bin_mgr__fsdb_version; private String[] src_bin_mgr__fsdb_skip_wkrs; private boolean src_bin_mgr__wmf_enabled; private Fsm_mnt_itm trg_mnt_itm; private Fsm_cfg_mgr trg_cfg_mgr; private Fsm_atr_fil trg_atr_fil; private Fsm_bin_fil trg_bin_fil; private long trg_bin_db_max; private final Xof_bin_updater trg_bin_updater = new Xof_bin_updater(); private Xob_tier_namer tier_namer; private int[] ns_ids; private int prv_lnki_tier_id = -1; private long download_size_max = Io_mgr.Len_mb_long; private int[] download_keep_tier_ids = Int_.Ary(0); @@ -48,6 +48,9 @@ public class Xob_fsdb_make_cmd extends Xob_itm_basic_base implements Xob_cmd { src_bin_mgr.Wkrs__add(src_fsdb_wkr); src_fsdb_wkr.Mnt_mgr().Ctor_by_load(new_src_bin_db_mgr(wiki, src_bin_mgr__fsdb_version)); src_fsdb_wkr.Mnt_mgr().Mnts__get_main().Txn_bgn(); // NOTE: txn on atr speeds up from 50 -> 300; DATE:2015-03-21 + if (src_bin_mgr__fsdb_skip_wkrs != null) { + src_fsdb_wkr.Skip_mgr_init(src_bin_mgr__fsdb_skip_wkrs); + } if (src_bin_mgr__cache_enabled) { usr_dlg.Prog_many("", "", "src_bin_mgr.cache.bgn"); src_fsdb_wkr.Mnt_mgr().Mnts__get_main().Atr_mgr().Db__core().Fil_cache_enabled_y_(); @@ -62,7 +65,7 @@ public class Xob_fsdb_make_cmd extends Xob_itm_basic_base implements Xob_cmd { // trg_mnt_itm this.trg_bin_db_max = app.Api_root().Bldr().Wiki().Import().File_db_max(); Fsdb_db_mgr trg_db_mgr = Fsdb_db_mgr_.new_detect(wiki, wiki.Fsys_mgr().Root_dir(), wiki.Fsys_mgr().File_dir()); - if (trg_db_mgr == null) trg_db_mgr = Fsdb_db_mgr__v2_bldr.I.Make(wiki); + if (trg_db_mgr == null) trg_db_mgr = Fsdb_db_mgr__v2_bldr.I.Make(wiki, Bool_.Y); Fsm_mnt_mgr trg_mnt_mgr = new Fsm_mnt_mgr(); trg_mnt_mgr.Ctor_by_load(trg_db_mgr); trg_mnt_mgr.Mnts__get_insert_idx_(Fsm_mnt_mgr.Mnt_idx_main); // NOTE: do not delete; mnt_mgr default to Mnt_idx_user; DATE:2014-04-25 this.trg_mnt_itm = trg_mnt_mgr.Mnts__get_insert(); @@ -119,7 +122,9 @@ public class Xob_fsdb_make_cmd extends Xob_itm_basic_base implements Xob_cmd { } public void Cmd_end() { usr_dlg.Note_many("", "", "fsdb_make.done: count=~{0} rate=~{1}", exec_count, DecimalAdp_.divide_safe_(exec_count, Env_.TickCount_elapsed_in_sec(time_bgn)).Xto_str("#,###.000")); - if (src_fsdb_wkr != null) src_fsdb_wkr.Mnt_mgr().Mnts__get_main().Txn_end(); // NOTE: src_fsdb_wkr will be null if no src db defined + if (src_fsdb_wkr != null) { + src_fsdb_wkr.Mnt_mgr().Mnts__get_main().Txn_end(); // NOTE: src_fsdb_wkr will be null if no src db defined + } trg_atr_fil.Conn().Txn_end(); trg_atr_fil.Conn().Rls_conn(); if (!trg_mnt_itm.Db_mgr().File__solo_file()) { trg_bin_fil.Conn().Txn_end(); trg_bin_fil.Conn().Rls_conn(); @@ -276,6 +281,7 @@ public class Xob_fsdb_make_cmd extends Xob_itm_basic_base implements Xob_cmd { else if (ctx.Match(k, Invk_resume_enabled_)) resume_enabled = m.ReadYn("v"); else if (ctx.Match(k, Invk_ns_ids_)) ns_ids = Int_.Ary_parse(m.ReadStr("v"), "|"); else if (ctx.Match(k, Invk_src_bin_mgr__fsdb_version_)) src_bin_mgr__fsdb_version = m.ReadStr("v"); + else if (ctx.Match(k, Invk_src_bin_mgr__fsdb_skip_wkrs_)) src_bin_mgr__fsdb_skip_wkrs = m.ReadStrAry("v", "|"); else if (ctx.Match(k, Invk_src_bin_mgr__wmf_enabled_)) src_bin_mgr__wmf_enabled = m.ReadYn("v"); else if (ctx.Match(k, Invk_src_bin_mgr__cache_enabled_)) src_bin_mgr__cache_enabled = m.ReadYn("v"); else if (ctx.Match(k, Invk_poll_mgr)) return poll_mgr; @@ -289,7 +295,7 @@ public class Xob_fsdb_make_cmd extends Xob_itm_basic_base implements Xob_cmd { , Invk_select_interval_ = "select_interval_", Invk_commit_interval_ = "commit_interval_", Invk_progress_interval_ = "progress_interval_", Invk_delete_interval_ = "delete_interval_" , Invk_exec_count_max_ = "exec_count_max_", Invk_exec_fail_max_ = "exec_fail_max_", Invk_exit_now_ = "exit_now_", Invk_exit_after_commit_ = "exit_after_commit_" , Invk_resume_enabled_ = "resume_enabled_", Invk_poll_mgr = "poll_mgr" - , Invk_src_bin_mgr__fsdb_version_ = "src_bin_mgr__fsdb_version_" + , Invk_src_bin_mgr__fsdb_version_ = "src_bin_mgr__fsdb_version_", Invk_src_bin_mgr__fsdb_skip_wkrs_ = "src_bin_mgr__fsdb_skip_wkrs_" , Invk_src_bin_mgr__wmf_enabled_ = "src_bin_mgr__wmf_enabled_" , Invk_src_bin_mgr__cache_enabled_ = "src_bin_mgr__cache_enabled_", Invk_ns_ids_ = "ns_ids_" , Invk_download_size_max = "download_size_max", Invk_download_keep_tier_ids = "download_keep_tier_ids" diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_lnki_temp_wkr.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_lnki_temp_wkr.java index b16ed54c7..74a2599db 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_lnki_temp_wkr.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_lnki_temp_wkr.java @@ -65,9 +65,9 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xopg_redlink gplx.xowa.xtns.hieros.Hiero_xnde.Log_wkr = log_mgr.Make_wkr(); Xof_fsdb_mgr__sql trg_fsdb_mgr = new Xof_fsdb_mgr__sql(); wiki.File_mgr__fsdb_mode().Tid_make_y_(); + Fsdb_db_mgr__v2 fsdb_core = Fsdb_db_mgr__v2_bldr.I.Make(wiki, Bool_.Y); trg_fsdb_mgr.Init_by_wiki(wiki); Fsm_mnt_mgr trg_mnt_mgr = trg_fsdb_mgr.Mnt_mgr(); - Fsdb_db_mgr__v2 fsdb_core = Fsdb_db_mgr__v2_bldr.I.Make(wiki); wiki.File_mgr().Init_file_mgr_by_load(wiki); // must happen after fsdb.make wiki.File_mgr__bin_mgr().Wkrs__del(gplx.xowa.files.bins.Xof_bin_wkr_.Key_http_wmf); // must happen after init_file_mgr_by_load; remove wmf wkr, else will try to download images during parsing wiki.File_mgr__orig_mgr().Wkrs_del(gplx.xowa.files.origs.Xof_orig_wkr_.Tid_wmf_api); @@ -129,7 +129,8 @@ public class Xob_lnki_temp_wkr extends Xob_dump_mgr_base implements Xopg_redlink hdump_bldr.Bld_term(); link_dump_cmd.Wkr_end(); } - Gfo_usr_dlg_.I.Warn_many("", "", invoke_wkr.Err_filter_mgr().Print()); + String err_filter_mgr = invoke_wkr.Err_filter_mgr().Print(); + if (String_.Len_gt_0(err_filter_mgr)) usr_dlg.Warn_many("", "", err_filter_mgr); wiki.Appe().Log_mgr().Txn_end(); tbl.Insert_end(); } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_redirect_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_redirect_cmd.java index 53d191147..55378008e 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_redirect_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/wikis/Xob_redirect_cmd.java @@ -20,7 +20,7 @@ import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.xowa.dbs.*; import gplx.x public class Xob_redirect_cmd extends Xob_dump_mgr_base { private Db_conn conn; private Xob_redirect_tbl redirect_tbl; private Xodb_mgr_sql db_mgr; private Xop_redirect_mgr redirect_mgr; private Url_encoder encoder; - public Xob_redirect_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);} + public Xob_redirect_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki); this.Reset_db_y_();} @Override public String Cmd_key() {return Xob_cmd_keys.Key_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 diff --git a/400_xowa/src/gplx/xowa/bldrs/infos/Xob_info_session.java b/400_xowa/src/gplx/xowa/bldrs/infos/Xob_info_session.java index 40892c0b8..3d25cb5e1 100644 --- a/400_xowa/src/gplx/xowa/bldrs/infos/Xob_info_session.java +++ b/400_xowa/src/gplx/xowa/bldrs/infos/Xob_info_session.java @@ -48,7 +48,7 @@ public class Xob_info_session { , hash.Get(Cfg_key__guid).To_guid_or(Guid_adp_.Empty) ); } - private static final String Cfg_grp = gplx.xowa.wikis.Xow_cfg_consts.Grp__bldr_session + public static final String Cfg_grp = gplx.xowa.wikis.Xow_cfg_consts.Grp__bldr_session , Cfg_key__user = "user" // EX: anonymous , Cfg_key__version = "version" // EX: 2.3.1.4 , Cfg_key__wiki_domain = "wiki_domain" // EX: en.wikipedia.org diff --git a/400_xowa/src/gplx/xowa/ctgs/Xoctg_fmtr_all.java b/400_xowa/src/gplx/xowa/ctgs/Xoctg_fmtr_all.java index e26f5104e..8538d8085 100644 --- a/400_xowa/src/gplx/xowa/ctgs/Xoctg_fmtr_all.java +++ b/400_xowa/src/gplx/xowa/ctgs/Xoctg_fmtr_all.java @@ -56,12 +56,12 @@ class Xoctg_fmtr_all { ("div_id", "all_label", "all_stats", "all_navs", "lang_key", "lang_ltr", "grps"); html_nav.Fmt_(String_.Concat_lines_nl_skip_last ( "" - , " (~{nav_text})" + , " (~{nav_text})" )) .Keys_("nav_href", "nav_title", "nav_text"); html_itm.Fmt_(String_.Concat_lines_nl_skip_last ( "" - , "
  • ~{itm_text}
  • " + , "
  • ~{itm_text}
  • " )) .Keys_("itm_href", "itm_title", "itm_text", "itm_id", "itm_atr_cls"); html_itm_missing.Fmt_(String_.Concat_lines_nl_skip_last @@ -80,7 +80,7 @@ class Xoctg_fmtr_all { , " " , " " , " " - , " ~{itm_text}" + , " ~{itm_text}" , " " , " ~{itm_contains_text}" , " " @@ -115,7 +115,8 @@ class Xoctg_fmtr_all { } private void Html_nav_bry(Bry_bfr bfr, Xowe_wiki wiki, Xoa_ttl ttl, Xoctg_view_grp view_grp, boolean fill_at_bgn) { Bry_bfr href_bfr = wiki.Utl__bfr_mkr().Get_b512(); - wiki.Appe().Href_parser().Build_to_bfr(href_bfr, wiki, ttl); + Xoae_app app = wiki.Appe(); + app.Href_parser().Build_to_bfr(href_bfr, app, wiki.Domain_bry(), ttl); byte[] arg_idx_lbl = null; byte[] arg_sortkey = null; if (fill_at_bgn) { arg_idx_lbl = url_arg_bgn; diff --git a/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr_tst.java b/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr_tst.java index 7f1aab028..085e47a71 100644 --- a/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/ctgs/Xoctg_html_mgr_tst.java @@ -46,7 +46,7 @@ public class Xoctg_html_mgr_tst { , " " , "

    A

    " , " " , " " , " " @@ -135,7 +135,7 @@ public class Xoctg_html_mgr_tst { , " " , " " , " " - , " Subc 1" + , " Subc 1" , " " , " " , " " @@ -194,8 +194,8 @@ public class Xoctg_html_mgr_tst { fxt.Init_itm_page("A1").Init_ctg_name_("Ctg_1").Init_ctg_pages_(1, 1) .Test_bld_rslts_lnk(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl ( "" - , " (previous 0)" - , " (next 0)" + , " (previous 0)" + , " (next 0)" )); } @Test public void Calc_col_max() { diff --git a/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java b/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java index 4e402d58f..2eced0928 100644 --- a/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java +++ b/400_xowa/src/gplx/xowa/dbs/Xodb_save_mgr_sql.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.dbs; import gplx.*; import gplx.xowa.*; -import gplx.ios.*; import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; +import gplx.ios.*; import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.dbs.qrys.*; import gplx.xowa.wikis.*; public class Xodb_save_mgr_sql implements Xodb_save_mgr { private final Xow_page_mgr page_mgr; @@ -30,7 +30,8 @@ public class Xodb_save_mgr_sql implements Xodb_save_mgr { Xowd_db_file db_file = db_mgr.Core_data_mgr().Db__core(); int ns_count = db_file.Tbl__ns().Select_ns_count(ns_id) + 1; int page_id = db_file.Tbl__cfg().Select_int_or("db", "page.id_nxt", -1); - if (page_id == -1) { // HACK: was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;") + if (page_id == -1) { // HACK: changed for tests; was dbs.qrys.Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;") +// Db_rdr rdr = db_mgr.Core_data_mgr().Tbl__page().Conn().Stmt_new(Db_qry_sql.rdr_("SELECT (Max(page_id) + 1) AS max_page_id FROM page;")).Exec_select__rls_manual(); Db_rdr rdr = db_mgr.Core_data_mgr().Tbl__page().Conn().Stmt_select(db_file.Tbl__page().Tbl_name(), String_.Ary(db_file.Tbl__page().Fld_page_id()), Db_meta_fld.Ary_empy).Exec_select__rls_auto(); try { int max_page_id = -1; diff --git a/400_xowa/src/gplx/xowa/files/Xof_ext_.java b/400_xowa/src/gplx/xowa/files/Xof_ext_.java index d32e3e864..a7715347e 100644 --- a/400_xowa/src/gplx/xowa/files/Xof_ext_.java +++ b/400_xowa/src/gplx/xowa/files/Xof_ext_.java @@ -139,6 +139,16 @@ public class Xof_ext_ { return false; } } + public static boolean Id_is_image_wo_svg(int id) { // same as Id_is_image, but ignore svg + switch (id) { + case Xof_ext_.Id_png: case Xof_ext_.Id_jpg: case Xof_ext_.Id_jpeg: + case Xof_ext_.Id_gif: case Xof_ext_.Id_tif: case Xof_ext_.Id_tiff: + case Xof_ext_.Id_bmp: case Xof_ext_.Id_xcf: + return true; + default: + return false; + } + } public static boolean Id_is_thumbable_img(int id) { switch (id) { case Xof_ext_.Id_png: case Xof_ext_.Id_jpg: case Xof_ext_.Id_jpeg: diff --git a/400_xowa/src/gplx/xowa/files/bins/Xof_bin_mgr.java b/400_xowa/src/gplx/xowa/files/bins/Xof_bin_mgr.java index aae320aff..3e282df7a 100644 --- a/400_xowa/src/gplx/xowa/files/bins/Xof_bin_mgr.java +++ b/400_xowa/src/gplx/xowa/files/bins/Xof_bin_mgr.java @@ -87,10 +87,9 @@ public class Xof_bin_mgr { fsdb.File_exists_y_(); return rv; } - usr_dlg.Log_direct(String_.Format("thumb not found; ttl={0} w={1} ", String_.new_utf8_(fsdb.Lnki_ttl()), fsdb.Lnki_w())); rv = wkr.Get_as_rdr(fsdb, Bool_.N, fsdb.Orig_w()); // thumb missing; get orig; if (rv == Io_stream_rdr_.Null) { - usr_dlg.Log_direct(String_.Format("orig not found;")); + usr_dlg.Log_direct(String_.Format("bin_mgr:thumb not found; wkr={0} ttl={1} w={2}", wkr.Key(), fsdb.Lnki_ttl(), fsdb.Lnki_w())); continue; // nothing found; continue; } if (!wkr.Resize_allowed()) continue; diff --git a/400_xowa/src/gplx/xowa/files/bins/Xof_bin_skip_mgr.java b/400_xowa/src/gplx/xowa/files/bins/Xof_bin_skip_mgr.java new file mode 100644 index 000000000..6c60fb1f6 --- /dev/null +++ b/400_xowa/src/gplx/xowa/files/bins/Xof_bin_skip_mgr.java @@ -0,0 +1,71 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.files.bins; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*; +import gplx.ios.*; +import gplx.xowa.files.fsdb.*; +public class Xof_bin_skip_mgr { + private Xof_bin_skip_wkr[] wkrs = new Xof_bin_skip_wkr[0]; private int wkrs_len; + public Xof_bin_skip_mgr(String[] wkr_keys) { + this.wkrs_len = wkr_keys.length; + this.wkrs = new Xof_bin_skip_wkr[wkrs_len]; + for (int i = 0; i < wkrs_len; ++i) + wkrs[i] = New_wkr(wkr_keys[i]); + } + public boolean Skip(Xof_fsdb_itm fsdb, Io_stream_rdr src_rdr) { + for (int i = 0; i < wkrs_len; ++i) { + if (wkrs[i].Skip(fsdb, src_rdr)) return true; + } + return false; + } + private Xof_bin_skip_wkr New_wkr(String key) { + if (String_.Eq(key, Xof_bin_skip_wkr_.Key__page_gt_1)) return Xof_bin_skip_wkr__page_gt_1.I; + else if (String_.Eq(key, Xof_bin_skip_wkr_.Key__small_size)) return Xof_bin_skip_wkr__small_size.I; + else throw Err_.unhandled(key); + } +} +interface Xof_bin_skip_wkr { + String Key(); + boolean Skip(Xof_fsdb_itm fsdb, Io_stream_rdr src_rdr); +} +class Xof_bin_skip_wkr_ { + public static final String Key__page_gt_1 = "page_gt_1", Key__small_size = "small_size"; +} +class Xof_bin_skip_wkr__page_gt_1 implements Xof_bin_skip_wkr { // prior to v2.4.3; lnkis with page > 1 was mistakenly bringing down page 1; EX: [[A.pdf|page=5]] -> page1; DATE:2015-04-21 + public String Key() {return Xof_bin_skip_wkr_.Key__page_gt_1;} + public boolean Skip(Xof_fsdb_itm fsdb, Io_stream_rdr src_rdr) { + boolean rv = fsdb.Lnki_page() > 1; + if (rv) + Xoa_app_.Usr_dlg().Note_many("", "", "src_bin_mgr:skip page gt 1: file=~{0} width=~{1} page=~{2}", fsdb.Lnki_ttl(), fsdb.File_w(), fsdb.Lnki_page()); + return rv; + } + public static final Xof_bin_skip_wkr__page_gt_1 I = new Xof_bin_skip_wkr__page_gt_1(); Xof_bin_skip_wkr__page_gt_1() {} +} +class Xof_bin_skip_wkr__small_size implements Xof_bin_skip_wkr {// downloads can randomly be broken; assume that anything with a small size is broken and redownload again; DATE:2015-04-21 + public String Key() {return Xof_bin_skip_wkr_.Key__small_size;} + public boolean Skip(Xof_fsdb_itm fsdb, Io_stream_rdr src_rdr) { + boolean rv = + src_rdr.Len() < 500 // file is small (< 500 bytes) + && fsdb.Html_w() > 50 // only apply to images larger than 50 px (arbitrarily chosen); needed to ignore 1x1 images as well as icon-sized images + && Xof_ext_.Id_is_image_wo_svg(fsdb.Lnki_ext().Id()) // only consider images; needed b/c of file_w check; note:ignore svg which can be small + ; + if (rv) + Xoa_app_.Usr_dlg().Note_many("", "", "src_bin_mgr:skip small file: file=~{0} width=~{1} ext=~{2} len=~{3}", fsdb.Lnki_ttl(), fsdb.Lnki_w(), fsdb.Orig_ext(), src_rdr.Len()); + return rv; + } + public static final Xof_bin_skip_wkr__small_size I = new Xof_bin_skip_wkr__small_size(); Xof_bin_skip_wkr__small_size() {} +} diff --git a/400_xowa/src/gplx/xowa/files/bins/Xof_bin_wkr__fsdb_sql.java b/400_xowa/src/gplx/xowa/files/bins/Xof_bin_wkr__fsdb_sql.java index 5be3fe3c9..051f87335 100644 --- a/400_xowa/src/gplx/xowa/files/bins/Xof_bin_wkr__fsdb_sql.java +++ b/400_xowa/src/gplx/xowa/files/bins/Xof_bin_wkr__fsdb_sql.java @@ -20,16 +20,20 @@ import gplx.dbs.*; import gplx.ios.*; import gplx.cache.*; import gplx.xowa.file import gplx.fsdb.*; import gplx.fsdb.data.*; import gplx.fsdb.meta.*; public class Xof_bin_wkr__fsdb_sql implements Xof_bin_wkr { private final Xof_bin_wkr_ids tmp_ids = new Xof_bin_wkr_ids(); + private Xof_bin_skip_mgr skip_mgr; Xof_bin_wkr__fsdb_sql(Fsm_mnt_mgr mnt_mgr) {this.mnt_mgr = mnt_mgr;} public byte Tid() {return Xof_bin_wkr_.Tid_fsdb_xowa;} public String Key() {return Xof_bin_wkr_.Key_fsdb_wiki;} public Fsm_mnt_mgr Mnt_mgr() {return mnt_mgr;} private final Fsm_mnt_mgr mnt_mgr; public boolean Resize_allowed() {return bin_wkr_resize;} public void Resize_allowed_(boolean v) {bin_wkr_resize = v;} private boolean bin_wkr_resize = false; - public Io_stream_rdr Get_as_rdr(Xof_fsdb_itm itm, boolean is_thumb, int w) { - Find_ids(itm, is_thumb, w); - int bin_db_id = tmp_ids.Bin_db_id(); if (bin_db_id == Fsd_bin_tbl.Bin_db_id_null) return gplx.ios.Io_stream_rdr_.Null; + public void Skip_mgr_init(String[] wkrs) {this.skip_mgr = new Xof_bin_skip_mgr(wkrs);} + public Io_stream_rdr Get_as_rdr(Xof_fsdb_itm fsdb, boolean is_thumb, int w) { + Find_ids(fsdb, is_thumb, w); + int bin_db_id = tmp_ids.Bin_db_id(); if (bin_db_id == Fsd_bin_tbl.Bin_db_id_null) return Io_stream_rdr_.Null; Fsm_bin_fil bin_db = mnt_mgr.Bins__at(tmp_ids.Mnt_id(), bin_db_id); - return bin_db.Select_as_rdr(tmp_ids.Itm_id()); + Io_stream_rdr rdr = bin_db.Select_as_rdr(tmp_ids.Itm_id()); + if (skip_mgr != null && skip_mgr.Skip(fsdb, rdr)) return Io_stream_rdr_.Null; + return rdr; } public boolean Get_to_fsys(Xof_fsdb_itm itm, boolean is_thumb, int w, Io_url bin_url) {return Get_to_fsys(itm.Orig_repo_name(), itm.Lnki_ttl(), itm.Lnki_md5(), itm.Lnki_ext(), is_thumb, w, itm.Lnki_time(), itm.Lnki_page(), bin_url);} private boolean Get_to_fsys(byte[] orig_repo, byte[] orig_ttl, byte[] orig_md5, Xof_ext orig_ext, boolean lnki_is_thumb, int file_w, double lnki_time, int lnki_page, Io_url file_url) { diff --git a/400_xowa/src/gplx/xowa/files/fsdb/tsts/Xof_file_fxt.java b/400_xowa/src/gplx/xowa/files/fsdb/tsts/Xof_file_fxt.java index ad8f24b29..18518e2f9 100644 --- a/400_xowa/src/gplx/xowa/files/fsdb/tsts/Xof_file_fxt.java +++ b/400_xowa/src/gplx/xowa/files/fsdb/tsts/Xof_file_fxt.java @@ -35,7 +35,7 @@ class Xof_file_fxt { Xof_repo_fxt.Repos_init(app.File_mgr(), true, wiki); Xowe_wiki_bldr.Create(wiki, 1, "dump.xml"); Xowd_db_file text_db = wiki.Data_mgr__core_mgr().Dbs__make_by_tid(Xowd_db_file_.Tid_text); text_db.Tbl__text().Create_tbl(); - Fsdb_db_mgr__v2 fsdb_core = Fsdb_db_mgr__v2_bldr.I.Make(wiki); + Fsdb_db_mgr__v2 fsdb_core = Fsdb_db_mgr__v2_bldr.I.Make(wiki, Bool_.Y); fsdb_mgr.Mnt_mgr().Ctor_by_load(fsdb_core); fsdb_mgr.Mnt_mgr().Mnts__get_main().Bin_mgr().Dbs__make("temp.xowa"); wiki.File_mgr().Init_file_mgr_by_load(wiki); diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java b/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java index e1122c4f9..393307152 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_html_itm.java @@ -20,7 +20,7 @@ import gplx.core.primitives.*; import gplx.core.btries.*; import gplx.gfui.*; import gplx.xowa.gui.menus.*; import gplx.xowa.gui.menus.dom.*; import gplx.xowa.files.gui.*; import gplx.html.*; import gplx.xowa.html.modules.*; import gplx.xowa.pages.*; public class Xog_html_itm implements Xog_js_wkr, GfoInvkAble, GfoEvObj { - private Xoae_app app; + private Xoae_app app; private final Object thread_lock = new Object(); public Xog_html_itm(Xog_tab_itm owner_tab) { this.owner_tab = owner_tab; app = owner_tab.Tab_mgr().Win().App(); @@ -92,41 +92,57 @@ public class Xog_html_itm implements Xog_js_wkr, GfoInvkAble, GfoEvObj { public String Get_elem_value_for_edit_box() {return html_box.Html_elem_atr_get_str(Elem_id__xowa_edit_data_box, Gfui_html.Atr_value);} public String Get_elem_value(String elem_id) {return html_box.Html_elem_atr_get_str(elem_id, Gfui_html.Atr_value);} public void Html_img_update(String elem_id, String elem_src, int elem_width, int elem_height) { - GfoMsg m = GfoMsg_.new_cast_(Invk_html_img_update).Add("elem_id", elem_id).Add("elem_src", elem_src).Add("elem_width", elem_width).Add("elem_height", elem_height); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_img_update, m); - } Object guard = new Object(); + synchronized (thread_lock) { + GfoMsg m = GfoMsg_.new_cast_(Invk_html_img_update).Add("elem_id", elem_id).Add("elem_src", elem_src).Add("elem_width", elem_width).Add("elem_height", elem_height); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_img_update, m); + } + } public void Html_elem_delete(String elem_id) { - GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_delete).Add("elem_id", elem_id); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_delete, m); + synchronized (thread_lock) { + GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_delete).Add("elem_id", elem_id); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_delete, m); + } } public void Html_atr_set(String elem_id, String atr_key, String atr_val) { - GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set, m); + synchronized (thread_lock) { + GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set, m); + } } public void Html_redlink(String html_uid) {Html_elem_atr_set_append(html_uid, "class", "new");} public void Html_elem_atr_set_append(String elem_id, String atr_key, String atr_val) { - GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set_append).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set_append, m); + synchronized (thread_lock) { + GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set_append).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set_append, m); + } } public void Html_elem_replace_html(String id, String html) { - GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_replace_html).Add("id", id).Add("html", html); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_replace_html, m); + synchronized (thread_lock) { + GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_replace_html).Add("id", id).Add("html", html); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_replace_html, m); + } } public void Html_elem_append_above(String id, String html) { - GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_append_above).Add("id", id).Add("html", html); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_append_above, m); + synchronized (thread_lock) { // needed for Special:Search and async; DATE:2015-04-23 + GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_append_above).Add("id", id).Add("html", html); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_append_above, m); + } } public void Html_gallery_packed_exec() { - if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // do not exec unless active; - GfoMsg m = GfoMsg_.new_cast_(Invk_html_gallery_packed_exec); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_gallery_packed_exec, m); - module_packed_done = true; + synchronized (thread_lock) { + if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // do not exec unless active; + GfoMsg m = GfoMsg_.new_cast_(Invk_html_gallery_packed_exec); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_gallery_packed_exec, m); + module_packed_done = true; + } } public void Html_popups_bind_hover_to_doc() { - if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // do not exec unless active; - GfoMsg m = GfoMsg_.new_cast_(Invk_html_popups_bind_hover_to_doc); - GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_popups_bind_hover_to_doc, m); - module_popups_done = true; + synchronized (thread_lock) { + if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // do not exec unless active; + GfoMsg m = GfoMsg_.new_cast_(Invk_html_popups_bind_hover_to_doc); + GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_popups_bind_hover_to_doc, m); + module_popups_done = true; + } } private boolean module_packed_done = false, module_popups_done = false; public void Tab_selected(Xoae_page page) { diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java b/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java index 880d0b81f..74c4c9e85 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_tab_itm.java @@ -171,6 +171,7 @@ public class Xog_tab_itm implements GfoInvkAble { } else async_wkr = new Load_files_wkr(this); + page.Html_data().Mode_wtxt_shown_y_(); app.Thread_mgr().File_load_mgr().Add_at_end(async_wkr).Run(); } finally { @@ -244,7 +245,7 @@ public class Xog_tab_itm implements GfoInvkAble { try { if (page.Tab_data().Tab() != null) { // needed b/c Preview has page.Tab of null which causes null_ref error in redlinks Xog_redlink_mgr redlinks_wkr = new Xog_redlink_mgr(win_itm, page, app.User().Cfg_mgr().Log_mgr().Log_redlinks()); - ThreadAdp_.invk_(redlinks_wkr, gplx.xowa.parsers.lnkis.redlinks.Xog_redlink_mgr.Invk_run).Start(); + ThreadAdp_.invk_(gplx.xowa.apps.Xoa_thread_.Key_page_redlink, redlinks_wkr, gplx.xowa.parsers.lnkis.redlinks.Xog_redlink_mgr.Invk_run).Start(); usr_dlg.Prog_none("", "imgs.done", ""); } } catch (Exception e) {usr_dlg.Warn_many("", "", "page.thread.redlinks: page=~{0} err=~{1}", page_ttl_str, Err_.Message_gplx_brief(e));} diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_tab_mgr.java b/400_xowa/src/gplx/xowa/gui/views/Xog_tab_mgr.java index 0bd523dd0..e23ecee99 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_tab_mgr.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_tab_mgr.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*; -import gplx.gfui.*; import gplx.xowa.cfgs2.*; import gplx.xowa.apis.xowa.gui.browsers.*; +import gplx.gfui.*; import gplx.xowa.cfgs2.*; import gplx.xowa.apis.xowa.gui.browsers.*; import gplx.xowa.specials.*; public class Xog_tab_mgr implements GfoEvObj { private OrderedHash tab_regy = OrderedHash_.new_(); private int tab_uid = 0; public Xog_tab_mgr(Xog_win_itm win) { @@ -76,7 +76,7 @@ public class Xog_tab_mgr implements GfoEvObj { public Xog_tab_itm Tabs_new_dflt(boolean focus) { boolean active_tab_is_null = this.Active_tab_is_null(); Xowe_wiki cur_wiki = active_tab_is_null ? win.App().User().Wiki() : active_tab.Wiki(); - Xoa_ttl ttl = Xoa_ttl.parse_(cur_wiki, gplx.xowa.specials.xowa.default_tab.Default_tab_page.Ttl_full_bry); + Xoa_ttl ttl = Xoa_ttl.parse_(cur_wiki, Xows_special_meta_.Itm__default_tab.Ttl_bry()); Xoa_url url = Xoa_url_parser.Parse_from_url_bar(win.App(), cur_wiki, ttl.Full_db_as_str()); Xog_tab_itm rv = Tabs_new(focus, active_tab_is_null, cur_wiki, Xoae_page.new_(cur_wiki, ttl)); rv.Page_update_ui(); diff --git a/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java b/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java index b61bbe1e9..5b50a3f70 100644 --- a/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java +++ b/400_xowa/src/gplx/xowa/gui/views/Xog_win_itm.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*; import gplx.threads.*; import gplx.gfui.*; import gplx.xowa.gui.*; import gplx.xowa.gui.history.*; import gplx.xowa.xtns.math.*; import gplx.xowa.files.*; import gplx.xowa.gui.urls.*; import gplx.xowa.gui.views.*; import gplx.xowa.pages.*; -import gplx.xowa.parsers.lnkis.redlinks.*; +import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.specials.*; public class Xog_win_itm implements GfoInvkAble, GfoEvObj { private GfoInvkAble sync_cmd; public Xog_win_itm(Xoae_app app, Xoa_gui_mgr gui_mgr) { @@ -180,7 +180,7 @@ public class Xog_win_itm implements GfoInvkAble, GfoEvObj { Xoae_page cur_page = tab.Page(); Xowe_wiki cur_wiki = tab.Wiki(); Xoae_page new_page = tab.History_mgr().Go_by_dir(cur_wiki, fwd); if (new_page.Missing()) return; - if (new_page.Wikie().Special_mgr().Page_search().Match_ttl(new_page.Ttl())) // if Special:Search, reload page; needed for async loading; DATE:2015-04-19 + if (Xows_special_meta_.Itm__search.Match_ttl(new_page.Ttl())) // if Special:Search, reload page; needed for async loading; DATE:2015-04-19 new_page = new_page.Wikie().GetPageByTtl(new_page.Url(), new_page.Ttl()); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save byte history_nav_type = fwd ? Xog_history_stack.Nav_fwd : Xog_history_stack.Nav_bwd; boolean new_page_is_same = Bry_.Eq(cur_page.Ttl().Full_txt(), new_page.Ttl().Full_txt()); @@ -205,7 +205,7 @@ public class Xog_win_itm implements GfoInvkAble, GfoEvObj { Page__async__bgn(tab); } public void Page__async__bgn(Xog_tab_itm tab) { - page__async__thread = ThreadAdp_.invk_msg_(this, GfoMsg_.new_cast_(Invk_page_async_exec).Add("v", tab)).Start(); + page__async__thread = ThreadAdp_.invk_msg_(gplx.xowa.apps.Xoa_thread_.Key_page_async, this, GfoMsg_.new_cast_(Invk_page_async_exec).Add("v", tab)).Start(); } private ThreadAdp page__async__thread = ThreadAdp.Null; public boolean Page__async__working(Xoa_url url) { if (page__async__thread.IsAlive()) { // cancel pending image downloads diff --git a/400_xowa/src/gplx/xowa/html/Xohp_ctg_grp_mgr.java b/400_xowa/src/gplx/xowa/html/Xohp_ctg_grp_mgr.java index f72ab58f7..71a145e46 100644 --- a/400_xowa/src/gplx/xowa/html/Xohp_ctg_grp_mgr.java +++ b/400_xowa/src/gplx/xowa/html/Xohp_ctg_grp_mgr.java @@ -47,11 +47,13 @@ class Xoh_ctg_itm_fmtr implements Bry_fmtr_arg { int ctgs_len = page.Category_list().length; Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128(); Bry_bfr tmp_href = Xoa_app_.Utl__bfr_mkr().Get_b128(); - byte[] ctg_prefix = page.Wiki().Ns_mgr().Ns_category().Name_db_w_colon(); + Xowe_wiki wiki = page.Wikie(); + Xoae_app app = wiki.Appe(); + byte[] ctg_prefix = wiki.Ns_mgr().Ns_category().Name_db_w_colon(); for (int i = 0; i < ctgs_len; i++) { byte[] page_name = page.Category_list()[i]; tmp_bfr.Add(ctg_prefix).Add(page_name); - page.Wikie().Appe().Href_parser().Build_to_bfr(tmp_href, page.Wikie(), tmp_bfr.Xto_bry_and_clear()); + page.Wikie().Appe().Href_parser().Build_to_bfr(tmp_href, app, wiki.Domain_bry(), wiki.Ttl_parse(tmp_bfr.Xto_bry_and_clear())); itm_fmtr.Bld_bfr(bfr, tmp_href.Xto_bry_and_clear(), page_name, page_name); } tmp_bfr.Mkr_rls(); diff --git a/400_xowa/src/gplx/xowa/html/lnkis/Xoh_lnki_wtr.java b/400_xowa/src/gplx/xowa/html/lnkis/Xoh_lnki_wtr.java index 16396f558..485763532 100644 --- a/400_xowa/src/gplx/xowa/html/lnkis/Xoh_lnki_wtr.java +++ b/400_xowa/src/gplx/xowa/html/lnkis/Xoh_lnki_wtr.java @@ -100,7 +100,7 @@ public class Xoh_lnki_wtr { wiki.Html_mgr().Hzip_mgr().Itm__anchor().Html_plain(bfr, lnki); else bfr.Add(Xoh_consts.A_bgn); // ' 0 && !ns_allowed_regy.Has(ns_allowed_regy_key.Val_(popup_ttl.Ns().Id()))) return Bry_.Empty; itm.Init(popup_wiki.Domain_bry(), popup_ttl); diff --git a/400_xowa/src/gplx/xowa/html/wtrs/Xoh_anchor_kv_bldr.java b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_anchor_kv_bldr.java new file mode 100644 index 000000000..1a78e3516 --- /dev/null +++ b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_anchor_kv_bldr.java @@ -0,0 +1,49 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.html.wtrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; +import gplx.html.*; +public class Xoh_anchor_kv_bldr { + private byte[] base_url; private boolean has_qarg; + private final Bry_bfr tmp_bfr = Bry_bfr.new_(16), apos_bfr = Bry_bfr.new_(16); + public Xoh_anchor_kv_bldr Init_w_qarg(byte[] base_url) {return Init(Bool_.Y, base_url);} + public Xoh_anchor_kv_bldr Init(boolean has_qarg, byte[] base_url) { + this.has_qarg = has_qarg; this.base_url = base_url; + tmp_bfr.Clear(); + tmp_bfr.Add(base_url); + return this; + } + public Xoh_anchor_kv_bldr Add_int(byte[] key, int val) { + tmp_bfr.Add_byte(has_qarg ? Byte_ascii.Amp : Byte_ascii.Question); + tmp_bfr.Add(key); + tmp_bfr.Add_byte(Byte_ascii.Eq); + tmp_bfr.Add_int_variable(val); + return this; + } + public Xoh_anchor_kv_bldr Add_bry(byte[] key, byte[] bry) { + tmp_bfr.Add_byte(has_qarg ? Byte_ascii.Amp : Byte_ascii.Question); + tmp_bfr.Add(key); + tmp_bfr.Add_byte(Byte_ascii.Eq); + tmp_bfr.Add(Html_utl.Escape_for_atr_val_as_bry(apos_bfr, Byte_ascii.Apos, bry)); + return this; + } + public byte[] Bld_to_bry() { + byte[] rv = tmp_bfr.Xto_bry_and_clear(); + tmp_bfr.Add(base_url); + return rv; + } +} diff --git a/400_xowa/src/gplx/xowa/html/wtrs/Xoh_img_path.java b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_img_path.java new file mode 100644 index 000000000..ba6980315 --- /dev/null +++ b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_img_path.java @@ -0,0 +1,27 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.html.wtrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; +public class Xoh_img_path { + public static final byte[] + Img_cancel = Bry_.new_ascii_("window/menu/file/cancel.png") // 32,32 + , Img_search = Bry_.new_ascii_("window/chrome/search_exec.png") + , Img_option = Bry_.new_ascii_("window/menu/tools/options.png") + , Img_go_bwd = Bry_.new_ascii_("window/paging/go_bwd.png") + , Img_go_fwd = Bry_.new_ascii_("window/paging/go_fwd.png") + ; +} diff --git a/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_bldr.java b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_bldr.java new file mode 100644 index 000000000..5d34cd9cd --- /dev/null +++ b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_bldr.java @@ -0,0 +1,82 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.html.wtrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; +import gplx.html.*; +public class Xoh_lnki_bldr { + private final Xoa_app app; private final Xoh_href_parser href_parser; private final byte[] img_root_dir; + private final Bry_bfr tmp_bfr = Bry_bfr.reset_(255); + private byte[] href, title, id, caption; + private byte[] img_rel_path; private int img_w, img_h; private boolean img_pos_is_left; + public Xoh_lnki_bldr(Xoa_app app, Xoh_href_parser href_parser) { + this.app = app; this.href_parser = href_parser; + this.img_root_dir = app.Fsys_mgr().Root_dir().GenSubDir_nest("user", "anonymous", "app", "img").To_http_file_bry(); + } + public Xoh_lnki_bldr Clear() { + href = title = id = caption = null; + img_rel_path = null; img_w = 0; img_h = 0; + img_pos_is_left = true; + return this; + } + public Xoh_lnki_bldr Id_(byte[] v) {this.id = Html_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, v); return this;} + public Xoh_lnki_bldr Href_(Xow_wiki wiki, byte[] bry) {return Href_(wiki.Domain_bry(), wiki.Ttl_parse(bry));} + public Xoh_lnki_bldr Href_(byte[] domain_bry, Xoa_ttl ttl) { + href_parser.Build_to_bfr(tmp_bfr, app, domain_bry, ttl, Bool_.Y); + this.href = tmp_bfr.Xto_bry_and_clear(); + return this; + } + public Xoh_lnki_bldr Title_(byte[] title) { + this.title = Html_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, title); + return this; + } + public Xoh_lnki_bldr Img_pos_is_left_(boolean v) {this.img_pos_is_left = v; return this;} + public Xoh_lnki_bldr Img_16x16(byte[] rel_path) {return Img_(rel_path, 16, 16);} + private Xoh_lnki_bldr Img_(byte[] rel_path, int w, int h) { + this.img_rel_path = rel_path; + this.img_w = w; + this.img_h = h; + return this; + } + public Xoh_lnki_bldr Caption_(byte[] text) { + this.caption = Html_utl.Escape_html_as_bry(tmp_bfr, text, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y); + return this; + } + public byte[] Bld_to_bry() { + Bld(tmp_bfr); + byte[] rv = tmp_bfr.Xto_bry_and_clear(); + this.Clear(); + return rv; + } + public void Bld(Bry_bfr bfr) { + bfr.Add_str_ascii(""); + if ( img_pos_is_left && img_rel_path != null) + Bld_img(bfr); + if (caption != null) + bfr.Add(caption); + if (!img_pos_is_left && img_rel_path != null) + Bld_img(bfr); + bfr.Add_str_ascii(""); + } + private void Bld_img(Bry_bfr bfr) { + bfr.Add_str_ascii(""); + } +} diff --git a/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_wtr_utl.java b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_wtr_utl.java index 03c35497f..d6c087172 100644 --- a/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_wtr_utl.java +++ b/400_xowa/src/gplx/xowa/html/wtrs/Xoh_lnki_wtr_utl.java @@ -16,13 +16,17 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.html.wtrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.html.*; +import gplx.html.*; public class Xoh_lnki_wtr_utl { - private final Xow_wiki wiki; private final Xoh_href_parser href_parser; private final Bry_bfr tmp_bfr = Bry_bfr.new_(255); + private final Xoa_app app; private final Xow_wiki wiki; private final Xoh_href_parser href_parser; private final Bry_bfr tmp_bfr = Bry_bfr.new_(255); public Xoh_lnki_wtr_utl(Xow_wiki wiki, Xoh_href_parser href_parser) { + this.app = wiki.App(); this.wiki = wiki; this.href_parser = href_parser; } - public byte[] Bld_href(byte[] page) { - return href_parser.Build_to_bry(wiki, wiki.Ttl_parse(page)); + public byte[] Bld_href(byte[] page) {return Bld_href(wiki.Domain_bry(), wiki.Ttl_parse(page));} + public byte[] Bld_href(byte[] domain_bry, Xoa_ttl ttl) { + href_parser.Build_to_bfr(tmp_bfr, app, domain_bry, ttl, Bool_.Y); + return tmp_bfr.Xto_bry_and_clear(); } public byte[] Bld_title(byte[] text) { return gplx.html.Html_utl.Escape_html_as_bry(tmp_bfr, text, Bool_.N, Bool_.N, Bool_.N, Bool_.Y, Bool_.Y); diff --git a/400_xowa/src/gplx/xowa/langs/Xol_lang_itm_.java b/400_xowa/src/gplx/xowa/langs/Xol_lang_itm_.java index 887b22d05..ac73a7415 100644 --- a/400_xowa/src/gplx/xowa/langs/Xol_lang_itm_.java +++ b/400_xowa/src/gplx/xowa/langs/Xol_lang_itm_.java @@ -360,107 +360,108 @@ public class Xol_lang_itm_ { , Id_sdh = 334 , Id_se = 335 , Id_sei = 336 -, Id_sg = 337 -, Id_sgs = 338 -, Id_sh = 339 -, Id_shi = 340 -, Id_shn = 341 -, Id_si = 342 -, Id_simple = 343 -, Id_sk = 344 -, Id_sl = 345 -, Id_sli = 346 -, Id_sly = 347 -, Id_sm = 348 -, Id_sma = 349 -, Id_sn = 350 -, Id_so = 351 -, Id_sq = 352 -, Id_sr = 353 -, Id_sr_ec = 354 -, Id_sr_el = 355 -, Id_srn = 356 -, Id_ss = 357 -, Id_st = 358 -, Id_stq = 359 -, Id_su = 360 -, Id_sv = 361 -, Id_sw = 362 -, Id_sxu = 363 -, Id_szl = 364 -, Id_ta = 365 -, Id_tcy = 366 -, Id_te = 367 -, Id_test = 368 -, Id_tet = 369 -, Id_tg = 370 -, Id_tg_cyrl = 371 -, Id_tg_latn = 372 -, Id_th = 373 -, Id_ti = 374 -, Id_tk = 375 -, Id_tl = 376 -, Id_tly = 377 -, Id_tn = 378 -, Id_to = 379 -, Id_tokipona = 380 -, Id_tp = 381 -, Id_tpi = 382 -, Id_tr = 383 -, Id_tru = 384 -, Id_ts = 385 -, Id_tt = 386 -, Id_tt_cyrl = 387 -, Id_tt_latn = 388 -, Id_ttt = 389 -, Id_tum = 390 -, Id_tw = 391 -, Id_ty = 392 -, Id_tyv = 393 -, Id_tzm = 394 -, Id_udm = 395 -, Id_ug = 396 -, Id_ug_arab = 397 -, Id_ug_latn = 398 -, Id_uk = 399 -, Id_ur = 400 -, Id_uz = 401 -, Id_ve = 402 -, Id_vec = 403 -, Id_vep = 404 -, Id_vi = 405 -, Id_vls = 406 -, Id_vmf = 407 -, Id_vo = 408 -, Id_vot = 409 -, Id_vro = 410 -, Id_wa = 411 -, Id_war = 412 -, Id_wo = 413 -, Id_wuu = 414 -, Id_xal = 415 -, Id_xh = 416 -, Id_xmf = 417 -, Id_yi = 418 -, Id_yo = 419 -, Id_yue = 420 -, Id_za = 421 -, Id_zea = 422 -, Id_zh = 423 -, Id_zh_classical = 424 -, Id_zh_cn = 425 -, Id_zh_hans = 426 -, Id_zh_hant = 427 -, Id_zh_hk = 428 -, Id_zh_min_nan = 429 -, Id_zh_mo = 430 -, Id_zh_my = 431 -, Id_zh_sg = 432 -, Id_zh_tw = 433 -, Id_zh_yue = 434 -, Id_zu = 435 +, Id_ses = 337 +, Id_sg = 338 +, Id_sgs = 339 +, Id_sh = 340 +, Id_shi = 341 +, Id_shn = 342 +, Id_si = 343 +, Id_simple = 344 +, Id_sk = 345 +, Id_sl = 346 +, Id_sli = 347 +, Id_sly = 348 +, Id_sm = 349 +, Id_sma = 350 +, Id_sn = 351 +, Id_so = 352 +, Id_sq = 353 +, Id_sr = 354 +, Id_sr_ec = 355 +, Id_sr_el = 356 +, Id_srn = 357 +, Id_ss = 358 +, Id_st = 359 +, Id_stq = 360 +, Id_su = 361 +, Id_sv = 362 +, Id_sw = 363 +, Id_sxu = 364 +, Id_szl = 365 +, Id_ta = 366 +, Id_tcy = 367 +, Id_te = 368 +, Id_test = 369 +, Id_tet = 370 +, Id_tg = 371 +, Id_tg_cyrl = 372 +, Id_tg_latn = 373 +, Id_th = 374 +, Id_ti = 375 +, Id_tk = 376 +, Id_tl = 377 +, Id_tly = 378 +, Id_tn = 379 +, Id_to = 380 +, Id_tokipona = 381 +, Id_tp = 382 +, Id_tpi = 383 +, Id_tr = 384 +, Id_tru = 385 +, Id_ts = 386 +, Id_tt = 387 +, Id_tt_cyrl = 388 +, Id_tt_latn = 389 +, Id_ttt = 390 +, Id_tum = 391 +, Id_tw = 392 +, Id_ty = 393 +, Id_tyv = 394 +, Id_tzm = 395 +, Id_udm = 396 +, Id_ug = 397 +, Id_ug_arab = 398 +, Id_ug_latn = 399 +, Id_uk = 400 +, Id_ur = 401 +, Id_uz = 402 +, Id_ve = 403 +, Id_vec = 404 +, Id_vep = 405 +, Id_vi = 406 +, Id_vls = 407 +, Id_vmf = 408 +, Id_vo = 409 +, Id_vot = 410 +, Id_vro = 411 +, Id_wa = 412 +, Id_war = 413 +, Id_wo = 414 +, Id_wuu = 415 +, Id_xal = 416 +, Id_xh = 417 +, Id_xmf = 418 +, Id_yi = 419 +, Id_yo = 420 +, Id_yue = 421 +, Id_za = 422 +, Id_zea = 423 +, Id_zh = 424 +, Id_zh_classical = 425 +, Id_zh_cn = 426 +, Id_zh_hans = 427 +, Id_zh_hant = 428 +, Id_zh_hk = 429 +, Id_zh_min_nan = 430 +, Id_zh_mo = 431 +, Id_zh_my = 432 +, Id_zh_sg = 433 +, Id_zh_tw = 434 +, Id_zh_yue = 435 +, Id_zu = 436 ; - public static final int Id__max = 436; + public static final int Id__max = 437; public static Hash_adp_bry Regy() { if (regy == null) { // NOTE: any parenthetical String below will have an "unseen" character of "\xE2\x80\xAA" at the begining and "\xE2\x80\xAC" at the end. They are responsible for parentheses-orientation in RTL langs. @@ -802,6 +803,7 @@ Regy_add(regy, Id_sdc, "sdc", "Sassaresu"); Regy_add(regy, Id_sdh, "sdh", "Southern Kurdish"); Regy_add(regy, Id_se, "se", "Sámegiella"); Regy_add(regy, Id_sei, "sei", "Cmique Itom"); +Regy_add(regy, Id_ses, "ses", "Songhay"); Regy_add(regy, Id_sg, "sg", "Sängö"); Regy_add(regy, Id_sgs, "sgs", "Žemaitėška"); Regy_add(regy, Id_sh, "sh", "Srpskohrvatski / Српскохрватски"); diff --git a/400_xowa/src/gplx/xowa/pages/Xopg_html_data.java b/400_xowa/src/gplx/xowa/pages/Xopg_html_data.java index d443ac177..b7780e272 100644 --- a/400_xowa/src/gplx/xowa/pages/Xopg_html_data.java +++ b/400_xowa/src/gplx/xowa/pages/Xopg_html_data.java @@ -31,7 +31,8 @@ public class Xopg_html_data { : display_ttl // return normal title ; } - public Xopg_html_data Display_ttl_(byte[] v) {display_ttl = v; return this;} private byte[] display_ttl; + public Xopg_html_data Display_ttl_(byte[] v) {display_ttl = v; return this;} private byte[] display_ttl; + public boolean Mode_wtxt_shown() {synchronized (this) {return mode_wtxt_shown;}} public void Mode_wtxt_shown_y_() {synchronized (this) {this.mode_wtxt_shown = true;}} private boolean mode_wtxt_shown; public byte[] Display_ttl_vnt() {return display_ttl_vnt;} public void Display_ttl_vnt_(byte[] v) {display_ttl_vnt = v;} private byte[] display_ttl_vnt; public byte[] Content_sub() {return content_sub;} public void Content_sub_(byte[] v) {content_sub = v;} private byte[] content_sub; public String Bmk_pos() {return html_bmk_pos;} public void Bmk_pos_(String v) {html_bmk_pos = v;} private String html_bmk_pos; @@ -85,6 +86,7 @@ public class Xopg_html_data { custom_html = custom_html_end = custom_head_end = custom_name = null; if (ctg_hash != null) ctg_hash.Clear(); indicators = null; + this.mode_wtxt_shown = false; } public byte[][] Ctgs_to_ary() {return ctg_hash == null ? Bry_.Ary_empty : (byte[][])ctg_hash.Xto_ary(byte[].class);} public void Ctgs_add(Xoa_ttl ttl) { diff --git a/400_xowa/src/gplx/xowa/servers/http/Http_server_mgr.java b/400_xowa/src/gplx/xowa/servers/http/Http_server_mgr.java index c494b9e20..f70c3f8b0 100644 --- a/400_xowa/src/gplx/xowa/servers/http/Http_server_mgr.java +++ b/400_xowa/src/gplx/xowa/servers/http/Http_server_mgr.java @@ -170,7 +170,6 @@ class Http_server_wkr implements Runnable { } } } private boolean canceled; - @SuppressWarnings("resource") public void run() { try { if (server_socket == null) @@ -303,6 +302,7 @@ class HttpRequest implements Runnable{ page_html = page_html.replaceAll(app_file_dir , "%file%/"); page_html = page_html.replaceAll("xowa-cmd" , "%xowa-cmd%/xowa-cmd"); page_html = page_html.replaceAll(". */ package gplx.xowa.specials; import gplx.*; import gplx.xowa.*; public interface Xows_page { - void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl); + Xows_special_meta Special_meta(); + void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl); } diff --git a/400_xowa/src/gplx/xowa/specials/Xows_special_meta.java b/400_xowa/src/gplx/xowa/specials/Xows_special_meta.java new file mode 100644 index 000000000..cc3d84b8d --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/Xows_special_meta.java @@ -0,0 +1,35 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials; import gplx.*; import gplx.xowa.*; +public class Xows_special_meta { + public Xows_special_meta(int src, int uid, String key_str) { + this.src = src; this.uid = uid; this.key_str = key_str; + this.key_bry = Bry_.new_utf8_(key_str); + this.ttl_str = "Special:" + key_str; // canonical name + this.ttl_bry = Bry_.new_utf8_(ttl_str); + } + public int Src() {return src;} private final int src; + public int Uid() {return uid;} private final int uid; + public String Key_str() {return key_str;} private final String key_str; + public byte[] Key_bry() {return key_bry;} private final byte[] key_bry; + public String Ttl_str() {return ttl_str;} private final String ttl_str; + public byte[] Ttl_bry() {return ttl_bry;} private final byte[] ttl_bry; + public boolean Match_ttl(Xoa_ttl ttl) { + return ttl.Ns().Id_special() && Bry_.Eq(ttl.Root_txt(), key_bry); + } +} diff --git a/400_xowa/src/gplx/xowa/specials/Xows_special_meta_.java b/400_xowa/src/gplx/xowa/specials/Xows_special_meta_.java new file mode 100644 index 000000000..81ea46c16 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/Xows_special_meta_.java @@ -0,0 +1,69 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials; import gplx.*; import gplx.xowa.*; +public class Xows_special_meta_ { + public static final int Src__mw = 1, Src__xowa = 2; + public static final int + Uid__all_pages = 1 + , Uid__random = 2 + , Uid__random_root_page = 3 + , Uid__search = 4 + , Uid__statistics = 5 + , Uid__move_page = 6 + , Uid__my_language = 7 + , Uid__item_by_title = 8 + , Uid__default_tab = 9 + , Uid__file_browser = 10 + , Uid__popup_history = 11 + , Uid__system_data = 12 + , Uid__nearby = 13 + , Uid__page_history = 14 + ; + public static final String + Key__all_pages = "AllPages" + , Key__random = "RandomPage" + , Key__random_root_page = "RandomRootPage" + , Key__search = "Search" + , Key__statistics = "Statistics" + , Key__move_page = "MovePage" + , Key__my_language = "MyLanguage" + , Key__item_by_title = "ItemByTitle" + , Key__default_tab = "XowaDefaultTab" + , Key__file_browser = "XowaFileBrowser" + , Key__popup_history = "XowaPopupHistory" + , Key__system_data = "XowaSystemData" + , Key__nearby = "Nearby" + , Key__page_history = "XowaHistory" + ; + public static final Xows_special_meta + Itm__all_pages = new Xows_special_meta(Src__mw , Uid__all_pages , Key__all_pages) + , Itm__random = new Xows_special_meta(Src__mw , Uid__random , Key__random) + , Itm__random_root_page = new Xows_special_meta(Src__mw , Uid__random_root_page , Key__random_root_page) + , Itm__search = new Xows_special_meta(Src__mw , Uid__search , Key__search) + , Itm__statistics = new Xows_special_meta(Src__mw , Uid__statistics , Key__statistics) + , Itm__move_page = new Xows_special_meta(Src__xowa , Uid__move_page , Key__move_page) + , Itm__my_language = new Xows_special_meta(Src__xowa , Uid__my_language , Key__my_language) + , Itm__item_by_title = new Xows_special_meta(Src__xowa , Uid__item_by_title , Key__item_by_title) + , Itm__default_tab = new Xows_special_meta(Src__xowa , Uid__default_tab , Key__default_tab) + , Itm__file_browser = new Xows_special_meta(Src__xowa , Uid__file_browser , Key__file_browser) + , Itm__popup_history = new Xows_special_meta(Src__xowa , Uid__popup_history , Key__popup_history) + , Itm__system_data = new Xows_special_meta(Src__xowa , Uid__system_data , Key__system_data) + , Itm__nearby = new Xows_special_meta(Src__xowa , Uid__nearby , Key__nearby) + , Itm__page_history = new Xows_special_meta(Src__xowa , Uid__page_history , Key__page_history) + ; +} diff --git a/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages.java b/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages.java index 0f97e36e3..4a122d8bd 100644 --- a/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages.java +++ b/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages.java @@ -23,6 +23,7 @@ public class Xows_page_allpages implements GfoInvkAble, Bry_fmtr_arg, Xows_page this.wiki = wiki; html_itm_fmtr = new Xos_pagelist_html_itm_fmtr(this, wiki); } private Xos_pagelist_html_itm_fmtr html_itm_fmtr; + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__all_pages;} public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki; public Bry_fmtr Html_all() {return html_all;} Bry_fmtr html_all = Bry_fmtr.new_(String_.Concat_lines_nl ( "" @@ -161,8 +162,6 @@ public class Xows_page_allpages implements GfoInvkAble, Bry_fmtr_arg, Xows_page public static final String Invk_html_all_ = "html_all_", Invk_html_list_grp_ = "html_list_grp_", Invk_html_list_itm_normal_ = "html_list_itm_normal_", Invk_html_list_itm_redirect_ = "html_list_itm_redirect_" , Invk_itms_per_page_ = "itms_per_page_", Invk_itms_per_grp_ = "itms_per_grp_", Invk_show_redirects_ = "show_redirects_"; public static final String GRP_KEY = "xowa.special.allpages"; - public static final String Ttl_full_str = "Special:AllPages"; - public static final byte[] Ttl_full_bry = Bry_.new_ascii_(Ttl_full_str); } class Xos_pagelist_html_itm_fmtr implements Bry_fmtr_arg { public Xos_pagelist_html_itm_fmtr(Xows_page_allpages mgr, Xowe_wiki wiki) { diff --git a/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages_tst.java b/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages_tst.java index c67d194ff..815f32fb9 100644 --- a/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages_tst.java +++ b/400_xowa/src/gplx/xowa/specials/allPages/Xows_page_allpages_tst.java @@ -170,7 +170,7 @@ class Xows_page_allpages_fxt { } public Xows_page_allpages_fxt Test_special_gen() { Xoa_url_parser parserx = new Xoa_url_parser(); - parserx.Parse(init_url, Xows_page_allpages.Ttl_full_bry); + parserx.Parse(init_url, Xows_special_meta_.Itm__all_pages.Ttl_bry()); Xoa_ttl init_ttl = Make_init_ttl(); allpages.Special_gen(wiki, wiki.Ctx().Cur_page(), init_url, init_ttl); if (expd_display_ttl != null) Tfds.Eq(expd_display_ttl, String_.new_utf8_(wiki.Ctx().Cur_page().Html_data().Display_ttl())); @@ -201,5 +201,5 @@ class Xows_page_allpages_fxt { Xoa_ttl init_ttl = Make_init_ttl(); allpages.Build_data(init_url, init_ttl); } - private Xoa_ttl Make_init_ttl() {return Xoa_ttl.parse_(wiki, Bry_.new_utf8_(Xows_page_allpages.Ttl_full_str + init_ttl_leaf));} + private Xoa_ttl Make_init_ttl() {return Xoa_ttl.parse_(wiki, Bry_.new_utf8_(Xows_special_meta_.Itm__all_pages.Ttl_str() + init_ttl_leaf));} } diff --git a/400_xowa/src/gplx/xowa/specials/movePage/Move_page.java b/400_xowa/src/gplx/xowa/specials/movePage/Move_page.java index b34c793ce..11a43437d 100644 --- a/400_xowa/src/gplx/xowa/specials/movePage/Move_page.java +++ b/400_xowa/src/gplx/xowa/specials/movePage/Move_page.java @@ -21,6 +21,7 @@ public class Move_page implements Xows_page { private Move_trg_ns_list_fmtr ns_list_fmtr = new Move_trg_ns_list_fmtr(); private Move_url_args args = new Move_url_args(); private Xoa_ttl src_ttl; + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__move_page;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { args.Parse(url); byte[] src_ttl_bry = args.Src_ttl(); diff --git a/400_xowa/src/gplx/xowa/specials/nearby/Nearby_mgr.java b/400_xowa/src/gplx/xowa/specials/nearby/Nearby_mgr.java index 11a739be1..199d57b73 100644 --- a/400_xowa/src/gplx/xowa/specials/nearby/Nearby_mgr.java +++ b/400_xowa/src/gplx/xowa/specials/nearby/Nearby_mgr.java @@ -27,6 +27,7 @@ public class Nearby_mgr implements Xows_page { // int pages_count = 0; Bry_bfr tmp_bfr = Bry_bfr.new_(); public int Results_max() {return results_max;} public Nearby_mgr Results_max_(int v) {results_max = v; return this;} private int results_max = 1; + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__nearby;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { page.Data_raw_(Bld_html(wiki)); page.Html_data().Html_restricted_n_(); // [[Special:]] pages allow all HTML @@ -166,7 +167,6 @@ public class Nearby_mgr implements Xows_page { } } } - public static final byte[] Ttl_name = Bry_.new_ascii_("XowaNearby"); } class Nearby_rslt { public Nearby_rslt(ListAdp trail, Xoa_ttl trg_ttl) { diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Xop_randomRootPage_page.java b/400_xowa/src/gplx/xowa/specials/randoms/Xop_randomRootPage_page.java index 50394a80a..6c11979f1 100644 --- a/400_xowa/src/gplx/xowa/specials/randoms/Xop_randomRootPage_page.java +++ b/400_xowa/src/gplx/xowa/specials/randoms/Xop_randomRootPage_page.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; public class Xop_randomRootPage_page implements Xows_page { + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__random_root_page;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { Xow_ns ns = wiki.Ns_mgr().Names_get_or_main(ttl.Rest_txt()); byte[] random_ttl_bry = wiki.Db_mgr().Load_mgr().Find_random_ttl(ns); diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java b/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java index 1b95ef5af..d712cb33b 100644 --- a/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java +++ b/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java @@ -18,6 +18,7 @@ along with this program. If not, see . package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; public class Xows_page_random implements Xows_page { public Xows_page_random(Xowe_wiki wiki) {} + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__random;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { Xow_ns ns = wiki.Ns_mgr().Names_get_or_main(ttl.Rest_txt()); byte[] random_ttl_bry = wiki.Db_mgr().Load_mgr().Find_random_ttl(ns); diff --git a/400_xowa/src/gplx/xowa/specials/search/Xog_search_suggest_mgr.java b/400_xowa/src/gplx/xowa/specials/search/Xog_search_suggest_mgr.java index 892d305aa..0cb7ca139 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xog_search_suggest_mgr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xog_search_suggest_mgr.java @@ -53,7 +53,7 @@ public class Xog_search_suggest_mgr implements GfoInvkAble { } public void Search(Xowe_wiki wiki, byte[] search_bry, byte[] cbk_func) { this.wiki = wiki; this.search_bry = search_bry; this.cbk_func = cbk_func; - ThreadAdp_.invk_(this, Invk_search_async).Start(); + ThreadAdp_.invk_(gplx.xowa.apps.Xoa_thread_.Key_special_suggest, this, Invk_search_async).Start(); } private Xowe_wiki wiki; private byte[] search_bry, cbk_func; private Object thread_guard = new Object(); private void Search_async() { diff --git a/400_xowa/src/gplx/xowa/specials/search/Xow_domain_sorter__manual_tid.java b/400_xowa/src/gplx/xowa/specials/search/Xow_domain_sorter__manual_tid.java new file mode 100644 index 000000000..d323d71d8 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/Xow_domain_sorter__manual_tid.java @@ -0,0 +1,121 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.core.primitives.*; import gplx.xowa.wikis.*; import gplx.xowa.langs.*; +import gplx.xowa.wikis.domains.crts.*; +class Xow_domain_sorter__manual implements gplx.lists.ComparerAble { + private final Xow_domain cur_domain; + private final Xow_domain_crt_itm[] ary; private final int ary_len; + public Xow_domain_sorter__manual(Xow_domain cur_domain, Xow_domain_crt_itm[] ary) { + this.cur_domain = cur_domain; this.ary = ary; this.ary_len = ary.length; + } + public int compare(Object lhsObj, Object rhsObj) { + Xow_domain lhs = (Xow_domain)lhsObj; + Xow_domain rhs = (Xow_domain)rhsObj; + int lhs_sort = Get_sort_idx_or_neg1(lhs); + int rhs_sort = Get_sort_idx_or_neg1(rhs); + if (lhs_sort == -1 && rhs_sort != -1) return rhs_sort; + else if (lhs_sort != -1 && rhs_sort == -1) return lhs_sort; + else if (lhs_sort != -1 && rhs_sort != -1) return Int_.Compare(lhs_sort, rhs_sort); + else return Bry_.Compare(lhs.Domain_bry(), rhs.Domain_bry()); + } + private int Get_sort_idx_or_neg1(Xow_domain domain) { + int sort_idx = domain.Sort_idx(); if (sort_idx != -1) return sort_idx; + sort_idx = Int_.MaxValue; + for (int i = 0; i < ary_len; ++i) { + Xow_domain_crt_itm crt = ary[i]; + if (crt.Matches(cur_domain, domain)) {sort_idx = i; break;} + } + domain.Sort_idx_(sort_idx); + return sort_idx; + } + public static void Sort(Xow_domain_sorter__manual sorter, Xow_domain[] ary) { + int len = ary.length; + for (int i = 0; i < len; ++i) + ary[i].Sort_idx_(-1); + Array_.Sort(ary, sorter); + } +} +class Xow_domain_sorter__manual_tid implements gplx.lists.ComparerAble { + private final HashAdp sort_hash = HashAdp_.new_(); private final Int_obj_ref sort_key = Int_obj_ref.neg1_(); + public Xow_domain_sorter__manual_tid(int[] id_ary) { + int len = id_ary.length; + for (int i = 0; i < len; ++i) { + int id_itm = id_ary[i]; + sort_hash.AddReplace(Int_obj_ref.new_(id_itm), Int_obj_ref.new_(i)); + } + } + public int compare(Object lhsObj, Object rhsObj) { + Xow_domain lhs = (Xow_domain)lhsObj; + Xow_domain rhs = (Xow_domain)rhsObj; + int lhs_sort = Get_sort_idx_or_neg1(lhs.Domain_tid()); + int rhs_sort = Get_sort_idx_or_neg1(rhs.Domain_tid()); + if (lhs_sort == -1 && rhs_sort != -1) return rhs_sort; + else if (lhs_sort != -1 && rhs_sort == -1) return lhs_sort; + else if (lhs_sort != -1 && rhs_sort != -1) return Int_.Compare(lhs_sort, rhs_sort); + else return Bry_.Compare(Xow_domain_.Tid__get_bry(lhs.Domain_tid()), Xow_domain_.Tid__get_bry(rhs.Domain_tid())); + } + private int Get_sort_idx_or_neg1(int tid) { + Object o = sort_hash.Fetch(sort_key.Val_(tid)); + return o == null ? -1 : ((Int_obj_ref)o).Val(); + } + public static Xow_domain_sorter__manual_tid new_(byte[]... id_brys) { + int len = id_brys.length; + int[] id_ints = new int[len]; + for (int i = 0; i < len; ++i) { + byte[] id_bry = id_brys[i]; + int id_int = Xow_domain_.Tid__get_int(id_bry); + id_ints[i] = id_int; + } + return new Xow_domain_sorter__manual_tid(id_ints); + } +} +class Xow_domain_sorter__manual_lang implements gplx.lists.ComparerAble { + private final HashAdp sort_hash = HashAdp_.new_(); private final Int_obj_ref sort_key = Int_obj_ref.neg1_(); + public Xow_domain_sorter__manual_lang(int[] id_ary) { + int len = id_ary.length; + for (int i = 0; i < len; ++i) { + int id_int = id_ary[i]; + sort_hash.AddReplace(Int_obj_ref.new_(id_int), Int_obj_ref.new_(i)); + } + } + public int compare(Object lhsObj, Object rhsObj) { + Xow_domain lhs = (Xow_domain)lhsObj; + Xow_domain rhs = (Xow_domain)rhsObj; + int lhs_sort = Get_sort_idx_or_neg1(lhs.Lang_uid()); + int rhs_sort = Get_sort_idx_or_neg1(rhs.Lang_uid()); + if (lhs_sort == -1 && rhs_sort != -1) return rhs_sort; + else if (lhs_sort != -1 && rhs_sort == -1) return lhs_sort; + else if (lhs_sort != -1 && rhs_sort != -1) return Int_.Compare(lhs_sort, rhs_sort); + else return Bry_.Compare(lhs.Lang_key(), rhs.Lang_key()); + } + private int Get_sort_idx_or_neg1(int tid) { + Object o = sort_hash.Fetch(sort_key.Val_(tid)); + return o == null ? -1 : ((Int_obj_ref)o).Val(); + } + public static Xow_domain_sorter__manual_lang new_(byte[]... id_brys) { + int len = id_brys.length; + int[] id_ints = new int[len]; + for (int i = 0; i < len; ++i) { + byte[] id_bry = id_brys[i]; + int id_int = Xol_lang_itm_.Get_by_key_or_intl(id_bry).Id(); + id_ints[i] = id_int; + } + return new Xow_domain_sorter__manual_lang(id_ints); + } +} \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_arg_mgr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_arg_mgr.java index 0796c3050..ce5501c33 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_arg_mgr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_arg_mgr.java @@ -18,11 +18,13 @@ along with this program. If not, see . package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.core.primitives.*; class Xows_arg_mgr { + private final Xows_paging_parser paging_parser = new Xows_paging_parser(); public Xows_ns_mgr Ns_mgr() {return ns_mgr;} private final Xows_ns_mgr ns_mgr = new Xows_ns_mgr(); public byte[] Search_bry() {return search_bry;} private byte[] search_bry; public int Paging_idx() {return paging_idx;} private int paging_idx; public byte Sort_tid() {return sort_tid;} private byte sort_tid; public byte[] Cancel() {return cancel;} private byte[] cancel; + public Xows_paging_itm[] Paging_itms() {return paging_itms;} private Xows_paging_itm[] paging_itms; public Xows_arg_mgr Search_bry_(byte[] v) {search_bry = v; return this;} public Xows_arg_mgr Clear() { ns_mgr.Clear(); @@ -45,6 +47,7 @@ class Xows_arg_mgr { case Arg_page_idx: this.paging_idx = Bry_.Xto_int_or(arg.Val_bry(), 0); break; case Arg_sort: this.sort_tid = Xosrh_rslt_itm_sorter.parse_(String_.new_ascii_(arg.Val_bry())); break; case Arg_cancel: this.cancel = arg.Val_bry(); break; + case Arg_paging: this.paging_itms = paging_parser.Parse(arg.Val_bry()); break; default: break; } } @@ -55,12 +58,17 @@ class Xows_arg_mgr { } ns_mgr.Add_main_if_empty(); } - private static final byte Arg_search = 0, Arg_page_idx = 1, Arg_sort = 2, Arg_cancel = 3; + private static final byte Arg_search = 0, Arg_page_idx = 1, Arg_sort = 2, Arg_cancel = 3, Arg_paging = 4; private static byte[] Ns_bry = Bry_.new_ascii_("ns"); + public static final byte[] + Arg_bry_page_index = Bry_.new_ascii_("xowa_page_index") + , Arg_bry_cancel = Bry_.new_ascii_("cancel") + ; private static final Hash_adp_bry url_args = Hash_adp_bry.ci_ascii_() - .Add_str_byte("xowa_page_index", Arg_page_idx) + .Add_str_byte("xowa_paging", Arg_paging) + .Add_bry_byte(Arg_bry_page_index, Arg_page_idx) .Add_str_byte("xowa_sort", Arg_sort) .Add_str_byte("search", Arg_search) - .Add_str_byte("cancel", Arg_cancel) + .Add_bry_byte(Arg_bry_cancel, Arg_cancel) ; } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_core.java b/400_xowa/src/gplx/xowa/specials/search/Xows_core.java index 794ac5cc7..142d5e1f3 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_core.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_core.java @@ -34,36 +34,37 @@ class Xows_core { } public void Search(Xow_wiki search_wiki, Xoae_page page, Xows_ui_qry qry) { // generate 1 cmd per wiki - byte[][] domain_ary = qry.Wiki_domains(); int domain_ary_len = domain_ary.length; + Xow_domain[] domain_ary = qry.Wiki_domains(); int domain_ary_len = domain_ary.length; for (int i = 0; i < domain_ary_len; ++i) { - byte[] domain = domain_ary[i]; - Xowe_wiki wiki = wiki_mgr.Get_by_key_or_null(domain); if (wiki == null) continue; - Assert_page_count(wiki); - Xows_ui_cmd cmd = new Xows_ui_cmd(this, qry, wiki, page.Tab_data().Close_mgr(), page.Tab_data().Tab().Html_itm()); - qry.Cmds__add(cmd); + Xow_domain domain = domain_ary[i]; + try { + Xowe_wiki wiki = wiki_mgr.Get_by_key_or_make(domain.Domain_bry()); wiki.Init_assert(); + Assert_page_count(wiki); + Xows_ui_cmd cmd = new Xows_ui_cmd(this, qry, wiki, page, page.Tab_data().Close_mgr(), page.Tab_data().Tab().Html_itm()); + qry.Cmds__add(cmd); + } catch (Exception e) {Xoa_app_.Usr_dlg().Warn_many("", "", "search:wiki failed; wiki=~{0} err=~{1}", domain.Domain_str(), Err_.Message_lang(e));} // handle bad wikis, like "en.wikipedia.org-old"; DATE:2015-04-24 } qry.Page_max_(Int_.MaxValue); // do search and generate html - html_wkr.Init_by_wiki(search_wiki.Html_mgr__lnki_wtr_utl(), search_wiki.Lang().Num_mgr()); + html_wkr.Init_by_wiki(search_wiki, search_wiki.Html_mgr__lnki_wtr_utl(), search_wiki.Lang().Num_mgr()); int cmds_len = qry.Cmds__len(); Bry_bfr tmp_bfr = Bry_bfr.new_(); for (int i = 0; i < cmds_len; ++i) { - Xows_ui_cmd cmd = qry.Cmds__get_at(i); - cmd_hash.Del(cmd.Key_for_html()); - cmd_hash.Add_bry_obj(cmd.Key_for_html(), cmd); + Xows_ui_cmd cmd = qry.Cmds__get_at(i); byte[] cmd_key = cmd.Key(); + cmd_hash.AddReplace(cmd_key, cmd); boolean searching_db = cmd.Search(); - html_wkr.Gen_tbl(tmp_bfr, qry, cmd.Rslt(), cmd.Key_for_html(), cmd.Wiki_domain_bry(), searching_db); + html_wkr.Gen_tbl(tmp_bfr, qry, cmd.Rslt(), cmd_key, cmd.Wiki().Domain_bry(), searching_db); } page.Data_raw_(html_wkr.Gen_page(qry, tmp_bfr.Xto_bry_and_clear())); } public void Search_end(Xows_ui_cmd cmd) { - cmd_hash.Del(cmd.Key_for_html()); + cmd_hash.Del(cmd.Key()); } public void Cancel(byte[] cmd_key) { Xows_ui_cmd cmd = (Xows_ui_cmd)cmd_hash.Get_by_bry(cmd_key); if (cmd == null) return; cmd.Cancel(); - cmd_hash.Del(cmd.Key_for_html()); + cmd_hash.Del(cmd.Key()); } private void Assert_page_count(Xowe_wiki wiki) { Xowd_db_file search_db = wiki.Data_mgr__core_mgr().Db__search(); diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java index 82e41f9c9..a93987001 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java @@ -16,25 +16,27 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -class Xows_db_cache { +import gplx.xowa.specials.search.parsers.*; +class Xows_db_cache { // one cache per search term; EX: "Earth* AND (History OR Future) AND -"middle earth"" is one cache private final OrderedHash hash = OrderedHash_.new_bry_(); - public Xows_db_matcher Matcher() {return matcher;} private Xows_db_matcher matcher; - public Xows_db_word[] Words() {return words;} private Xows_db_word[] words; - public boolean Done() {return done;} public void Done_y_() {done = true;} private boolean done; + public Xows_db_word[] Words() {return words;} private Xows_db_word[] words; // words in cache; EX: earth, history, future but not "middle earth" (since not'ed) + public Xows_db_matcher Matcher() {return matcher;} private Xows_db_matcher matcher; // criteria + public boolean Done() {return done;} public void Done_y_() {done = true;} private boolean done; // marks if db search is done public int Count() {return hash.Count();} + public int Itms_end() {return itms_end;} public void Itms_end_(int v) {itms_end = v;} private int itms_end; + public void Init_by_db(Cancelable cxl, byte[] raw, gplx.xowa.wikis.data.tbls.Xowd_search_word_tbl word_tbl) { + this.matcher = new Xow_search_parser().Parse(raw); + this.words = new Xows_db_matcher_bldr().Gather_words_for_db(cxl, matcher, word_tbl); + } public boolean Has(byte[] key) {return hash.Has(key);} - public void Add(Xows_db_row row) {hash.Add(row.Page_ttl_w_ns(), row);} + public Xows_db_row Get_at(int i) {return (Xows_db_row)hash.FetchAt(i);} + public void Add(Xows_db_row row) {hash.Add(row.Page_ttl().Full_db(), row);} public void Get_between(Xows_ui_rslt search_ui, int bgn, int end) { if (bgn >= hash.Count()) return; // requested start not in cache; exit for (int i = bgn; i < end; ++i) { if (i >= hash.Count()) break; - Xows_db_row row = (Xows_db_row)hash.FetchAt(i); - search_ui.Add(row); + search_ui.Add((Xows_db_row)hash.FetchAt(i)); } } public void Sort() {hash.SortBy(Xows_db_row_sorter.Page_len_dsc);} - public void Init_by_db(Cancelable cxl, byte[] raw, gplx.xowa.wikis.data.tbls.Xowd_search_word_tbl word_tbl) { - this.matcher = gplx.xowa.specials.search.parsers.Xow_search_parser.I.Parse(raw); - this.words = Xows_db_matcher_bldr.I.Gather_words_for_db(cxl, matcher, word_tbl); - } } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java index 66bc9dcbb..79ea59751 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java @@ -95,5 +95,4 @@ class Xows_db_matcher_bldr { rv.Add(new Xows_db_word(row.Id(), row.Text(), row.Page_count())); } } - public static final Xows_db_matcher_bldr I = new Xows_db_matcher_bldr(); Xows_db_matcher_bldr() {} } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java index e4b4e0742..d654e1898 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java @@ -17,22 +17,18 @@ along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; public class Xows_db_row { - public Xows_db_row(byte[] wiki_domain, int page_id, int page_ns, int page_len, byte[] page_ttl_w_ns, byte[] page_ttl_wo_ns) { + public Xows_db_row(byte[] wiki_domain, Xoa_ttl page_ttl, int page_id, int page_len) { this.wiki_domain = wiki_domain; + this.page_ttl = page_ttl; this.page_id = page_id; - this.page_ns = page_ns; this.page_len = page_len; - this.page_ttl_w_ns = page_ttl_w_ns; - this.page_ttl_wo_ns = page_ttl_wo_ns; - this.key = Bry_.Add_w_dlm(Byte_ascii.Pipe, wiki_domain, page_ttl_w_ns); + this.key = Bry_.Add(wiki_domain, Byte_ascii.Pipe_bry, page_ttl.Full_db()); } public byte[] Key() {return key;} private final byte[] key; public byte[] Wiki_domain() {return wiki_domain;} private final byte[] wiki_domain; + public Xoa_ttl Page_ttl() {return page_ttl;} private final Xoa_ttl page_ttl; public int Page_id() {return page_id;} private final int page_id; - public int Page_ns() {return page_ns;} private final int page_ns; public int Page_len() {return page_len;} private final int page_len; - public byte[] Page_ttl_w_ns() {return page_ttl_w_ns;} private final byte[] page_ttl_w_ns; - public byte[] Page_ttl_wo_ns() {return page_ttl_wo_ns;} private final byte[] page_ttl_wo_ns; public static Xows_db_row[] Ary(Xows_db_row... v) {return v;} } class Xows_db_row_sorter implements gplx.lists.ComparerAble { diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java index 92ab85e48..2f075efc4 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java @@ -16,81 +16,86 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.core.primitives.*; -import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; +import gplx.core.primitives.*; import gplx.dbs.*; +import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.langs.cases.*; import gplx.gfui.*; class Xows_db_wkr { - private int total_found; + private final Object thread_lock = new Object(); public void Search(Xows_ui_cmd cmd, Xows_ui_qry qry, Xows_ui_rslt rslt, Xows_db_cache cache, Xow_wiki wiki) { - // init - int itms_wanted = qry.Itms_end() - qry.Itms_bgn(), limit = qry.Page_len(); - Xowd_db_file core_db = wiki.Data_mgr__core_mgr().Db__core(); - Xowd_db_file search_db = wiki.Data_mgr__core_mgr().Db__search(); - // assert matcher - if (cache.Matcher() == null) { - cache.Init_by_db - ( cmd - , wiki.Lang().Case_mgr().Case_build_lower(qry.Search_raw()) // lower-case search - , wiki.Data_mgr__core_mgr().Db__search().Tbl__search_word() - ); - } - Xoa_app_.Usr_dlg().Prog_many("", "", "search started (please wait)"); - // load pages for each word - Xows_db_matcher matcher = cache.Matcher(); - Xows_db_word[] word_ary = cache.Words(); - int word_ary_len = word_ary.length; - total_found = 0; - while (true) { - if (cmd.Canceled()) break; - boolean found_none = true; - for (int i = 0; i < word_ary_len; ++i) { - if (cmd.Canceled()) break;; - Xows_db_word word = word_ary[i]; - int read = Search_pages(cmd, qry, rslt, cache, wiki, core_db, search_db, word, matcher, limit, word.Rslts_offset(), i, word_ary_len); - if (read > 0) found_none = false; + synchronized (thread_lock){ + // assert matcher + Xowd_db_file search_db = wiki.Data_mgr__core_mgr().Db__search(); + Xoa_app_.Usr_dlg().Prog_many("", "", "search started (please wait)"); + Xows_db_matcher matcher = cache.Matcher(); + if (matcher == null) { + cache.Init_by_db + ( cmd + , wiki.Lang().Case_mgr().Case_build_lower(qry.Search_raw()) // lower-case search + , search_db.Tbl__search_word() + ); + matcher = cache.Matcher(); } - if (found_none) {cache.Done_y_(); break;} - if (total_found >= itms_wanted) break; + // init + int rslts_wanted = qry.Itms_end() - qry.Itms_bgn(); + Xowd_db_file core_db = wiki.Data_mgr__core_mgr().Db__core(); + Xowd_page_tbl page_tbl = core_db.Tbl__page(); + Xowd_search_link_tbl link_tbl = search_db.Tbl__search_link(); + Xows_db_word[] word_ary = cache.Words(); int word_ary_len = word_ary.length; + // read pages for each word from db + Db_attach_rdr attach_rdr = new Db_attach_rdr(search_db.Conn(), "page_db", core_db.Url()); + attach_rdr.Attach(); + int total_found = 0; + try { + while (true) { + boolean found_none = true; + for (int i = 0; i < word_ary_len; ++i) { // loop each word to get rslts_wanted + if (cmd.Canceled()) return; + Xows_db_word word = word_ary[i]; + if (word.Rslts_done()) continue; // last db_search for word returned 0 results; don't search again; + int offset = word.Rslts_offset(); + Xoa_app_.Usr_dlg().Prog_many("", "", "searching; wiki=~{0} total=~{1} offset=~{2} index=~{3} word=~{4}", wiki.Domain_str(), word_ary_len, offset, i, word.Text()); + String sql = String_.Format(Search_sql, link_tbl.Tbl_name(), link_tbl.Fld_page_id(), link_tbl.Fld_word_id(), word.Id(), "page_len", "DESC", Int_.MaxValue, offset); // need to return enough results to fill qry.Page_len() as many results may be discarded below; DATE:2015-04-24 + int rslts_found = Search_pages(cmd, qry, rslt, cache, wiki, page_tbl, attach_rdr, sql, word, matcher, rslts_wanted); + total_found += rslts_found; + if (rslts_found == -1) return; // canceled + else if (rslts_found > 0) found_none = false; // NOTE: do not reverse and do rslts_found == 0; want to check if any word returns results; + } + if (found_none) {cache.Done_y_(); break;} + if (total_found >= rslts_wanted) break; + } + cache.Itms_end_(qry.Itms_end()); + cache.Sort(); + } finally {attach_rdr.Detach();} } - cache.Sort(); } - private int Search_pages(Xows_ui_cmd cmd, Xows_ui_qry qry, Xows_ui_rslt rslt, Xows_db_cache cache, Xow_wiki wiki, Xowd_db_file core_db, Xowd_db_file search_db, Xows_db_word word, Xows_db_matcher matcher, int limit, int offset, int i, int word_ary_len) { - if (word.Rslts_done()) return 0; // last db_search for word returned 0 results; don't search again; - // get search results - synchronized (cmd) { - if (cmd.Canceled()) return 0; - } - Xoa_app_.Usr_dlg().Prog_many("", "", "searching; total=~{1} offset=~{2} index=~{0} word=~{3}", i, word_ary_len, offset, word.Text()); - Xowd_search_link_tbl link_tbl = search_db.Tbl__search_link(); - Db_attach_rdr attach_rdr = new Db_attach_rdr(search_db.Conn(), "page_db", core_db.Url()); - String sql = String_.Format(Search_sql, link_tbl.Tbl_name(), link_tbl.Fld_page_id(), link_tbl.Fld_word_id(), word.Id(), "page_len", "DESC", limit, offset); - int total_read = 0; + private int Search_pages(Xows_ui_cmd cmd, Xows_ui_qry qry, Xows_ui_rslt rslt, Xows_db_cache cache, Xow_wiki wiki, Xowd_page_tbl page_tbl, Db_attach_rdr attach_rdr, String sql, Xows_db_word word, Xows_db_matcher matcher, int rslts_wanted) { + int rslts_found = 0; + Xow_ns_mgr ns_mgr = wiki.Ns_mgr(); Xol_case_mgr case_mgr = wiki.Lang().Case_mgr(); Db_rdr rdr = attach_rdr.Exec_as_rdr(sql); try { - Xowd_page_tbl page_tbl = core_db.Tbl__page(); - Xow_ns_mgr ns_mgr = wiki.Ns_mgr(); while (rdr.Move_next()) { - if (cmd.Canceled()) break; - ++total_read; + if (cmd.Canceled()) return -1; word.Rslts_offset_add_1(); int page_ns = rdr.Read_int(page_tbl.Fld_page_ns()); - if (!qry.Ns_mgr().Has(page_ns)) continue; + if (!qry.Ns_mgr().Has(page_ns)) continue; // ignore: ns doesn't match byte[] page_ttl = rdr.Read_bry_by_str(page_tbl.Fld_page_title()); - byte[] page_ttl_lc = wiki.Lang().Case_mgr().Case_build_lower(Xoa_ttl.Replace_unders(page_ttl)); + // Io_mgr._.AppendFilStr("C:\\temp.txt", String_.new_utf8_(word.Text()) + "|" + Int_.Xto_str(page_ns) + "|" + String_.new_utf8_(page_ttl) + "\n"); + byte[] page_ttl_lc = case_mgr.Case_build_lower(Xoa_ttl.Replace_unders(page_ttl)); byte[][] page_ttl_words = Bry_.Split(page_ttl_lc, Byte_ascii.Space, Bool_.Y); - if (!matcher.Matches(page_ttl_lc, page_ttl_words)) continue;// ttl doesn't match matcher; ignore; + if (!matcher.Matches(page_ttl_lc, page_ttl_words)) continue; // ignore: ttl doesn't match matcher int page_id = rdr.Read_int(page_tbl.Fld_page_id()); int page_len = rdr.Read_int(page_tbl.Fld_page_len()); Xow_ns ns = ns_mgr.Ids_get_or_null(page_ns); byte[] page_ttl_w_ns = ns.Gen_ttl(page_ttl); - if (cache.Has(page_ttl_w_ns)) continue; // page already added by another word; EX: "A B"; word is "B", but "A B" already added by "A" - Xows_db_row row = new Xows_db_row(wiki.Domain_bry(), page_id, page_ns, page_len, page_ttl_w_ns, page_ttl); + if (cache.Has(page_ttl_w_ns)) continue; // ignore: page already added by another word; EX: "A B"; word is "B", but "A B" already added by "A" + Xoa_ttl ttl = wiki.Ttl_parse(page_ttl_w_ns); + Xows_db_row row = new Xows_db_row(wiki.Domain_bry(), ttl, page_id, page_len); cmd.Add_rslt(row); - ++total_found; + if (++rslts_found == rslts_wanted) break; // stop: found enough results; DATE:2015-04-24 } - } finally {rdr.Rls(); attach_rdr.Rls();} - if (total_read == 0) word.Rslts_done_y_(); - return total_read; + } finally {rdr.Rls();} + if (rslts_found == 0) word.Rslts_done_y_(); // read through entire rdr and nothing found; mark word done + return rslts_found; } private static final String Search_sql = String_.Concat_lines_nl_skip_last ( "SELECT cp.page_id" @@ -104,4 +109,4 @@ class Xows_db_wkr { , "LIMIT {6}" , "OFFSET {7};" ); -} \ No newline at end of file +} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java index a397f96af..8b72929bb 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java @@ -17,76 +17,74 @@ along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.html.*; import gplx.xowa.html.wtrs.*; import gplx.xowa.langs.numbers.*; -class Xows_html_wkr { +class Xows_html_wkr { private final Bry_bfr bfr = Bry_bfr.new_(255); private final Bry_bfr tmp_bfr = Bry_bfr.new_(255); - private Xows_ui_qry qry; private Xoh_lnki_wtr_utl lnki_wtr_utl; private Xol_num_mgr num_mgr; + private Xows_ui_qry qry; private Xow_wiki wiki; private Xol_num_mgr num_mgr; + private Xoh_lnki_bldr lnki_bldr; private Xoh_anchor_kv_bldr self_lnkr = new Xoh_anchor_kv_bldr(); public Xows_html_row Html_rows() {return html_rows;} private final Xows_html_row html_rows = new Xows_html_row(); - public void Init_by_wiki(Xoh_lnki_wtr_utl lnki_wtr_utl, Xol_num_mgr num_mgr) { - this.lnki_wtr_utl = lnki_wtr_utl; this.num_mgr = num_mgr; + public void Init_by_wiki(Xow_wiki wiki, Xoh_lnki_wtr_utl lnki_wtr_utl, Xol_num_mgr num_mgr) { + this.wiki = wiki; this.num_mgr = num_mgr; + this.lnki_bldr = new Xoh_lnki_bldr(wiki.App(), wiki.App().Html__href_parser()); html_rows.Ctor(lnki_wtr_utl); } - @gplx.Internal protected void Qry_(Xows_ui_qry qry) {this.qry = qry;} // TEST: + @gplx.Internal protected void Qry_(Xows_ui_qry qry) {this.qry = qry; self_lnkr.Init_w_qarg(qry.Special_link_base_href());} // TEST: public byte[] Gen_page(Xows_ui_qry qry, byte[] tbls) { synchronized (bfr) { - this.qry = qry; + this.Qry_(qry); byte[] rslts_hdr = fmtr_rslts.Bld_bry_many(tmp_bfr, num_mgr.Format_num(qry.Itms_bgn() + ListAdp_.Base1), num_mgr.Format_num(qry.Itms_end()), qry.Search_raw()); - fmtr_page.Bld_bfr_many(bfr, rslts_hdr, Paging_link(Bool_.N), Paging_link(Bool_.Y), tbls); + byte[] option_link = lnki_bldr.Href_(Bry_.new_ascii_("home"), wiki.Ttl_parse(Bry_.new_ascii_("Help:Options/Search"))).Img_16x16(Xoh_img_path.Img_option).Bld_to_bry(); + fmtr_page.Bld_bfr_many(bfr, rslts_hdr, option_link, Paging_link(Bool_.N), Paging_link(Bool_.Y), tbls); return bfr.Xto_bry_and_clear(); } } public void Gen_tbl(Bry_bfr bfr, Xows_ui_qry qry, Xows_ui_rslt rslt, byte[] cmd_key, byte[] wiki_domain, boolean searching_db) { synchronized (bfr) { - this.qry = qry; + this.Qry_(qry); html_rows.Init(rslt); - fmtr_tbl.Bld_bfr_many(bfr, wiki_domain, searching_db ? Cancel_link(wiki_domain, cmd_key) : Bry_fmtr_arg_.Noop, Bry_hdr_len, Bry_hdr_ttl, Xows_ui_async.Gen_insert_key(wiki_domain), html_rows); + byte[] search_link = lnki_bldr.Href_(wiki_domain, wiki.Ttl_parse(self_lnkr.Bld_to_bry())).Caption_(wiki_domain).Img_16x16(Xoh_img_path.Img_search).Bld_to_bry(); + fmtr_tbl.Bld_bfr_many(bfr, search_link, searching_db ? Cancel_link(wiki_domain, cmd_key) : Bry_.Empty, Bry_hdr_len, Bry_hdr_ttl, Xows_ui_async.Gen_insert_key(wiki_domain), html_rows); } + } + private byte[] Cancel_link(byte[] domain, byte[] cmd_key) { + lnki_bldr.Id_(tmp_bfr.Add_str_ascii("xowa_cancel_").Add(domain).Xto_bry_and_clear()); + lnki_bldr.Href_(wiki, self_lnkr.Add_int(Xows_arg_mgr.Arg_bry_page_index, qry.Page_idx()).Add_bry(Xows_arg_mgr.Arg_bry_cancel, cmd_key).Bld_to_bry()); + lnki_bldr.Title_(Bry_cancel); + lnki_bldr.Img_16x16(Xoh_img_path.Img_cancel); + return lnki_bldr.Bld_to_bry(); } - private Bry_fmtr_arg Cancel_link(byte[] domain, byte[] cmd_key) { - byte[] ttl_bry = tmp_bfr.Add_str_ascii("Special:Search/").Add(qry.Search_raw()).Add_str_ascii("?fulltext=y&xowa_page_index=").Add_int_variable(qry.Page_idx()).Add_str("&cancel=").Add(Html_utl.Encode_id_as_bry(cmd_key)).Xto_bry_and_clear(); - byte[] href = lnki_wtr_utl.Bld_href(ttl_bry); - byte[] title = lnki_wtr_utl.Bld_title(Bry_cancel); - return fmtr_paging_cxl.Vals_("xowa_cancel_" + String_.new_utf8_(domain), href, title, Bry_cancel); - } - public Bry_fmtr_arg Paging_link(boolean fwd) { + public byte[] Paging_link(boolean fwd) { int paging_idx = qry.Page_idx(); - byte[] a_text = null; - Bry_fmtr_vals rv = null; + byte[] title = null, img_path = Bry_.Empty; + boolean img_pos_is_left = true; if (fwd) { ++paging_idx; - a_text = Bry_paging_fwd; - if (paging_idx > qry.Page_max()) return Bry_fmtr_arg_.bry_(a_text); - rv = fmtr_paging_fwd; + // if (paging_idx > qry.Page_max()) return Html_entity_.Nbsp_num_bry; + img_pos_is_left = false; + img_path = Xoh_img_path.Img_go_fwd; + title = Bry_paging_fwd; } else { --paging_idx; - a_text = Bry_paging_bwd; - if (paging_idx < 0) return Bry_fmtr_arg_.bry_(a_text); - rv = fmtr_paging_bwd; + if (paging_idx < 0) return Html_entity_.Nbsp_num_bry; + img_path = Xoh_img_path.Img_go_bwd; + title = Bry_paging_bwd; } - byte[] a_ttl_bry = tmp_bfr.Add_str_ascii("Special:Search/").Add(qry.Search_raw()).Add_str_ascii("?fulltext=y&xowa_page_index=").Add_int_variable(paging_idx).Xto_bry_and_clear(); - byte[] a_href = lnki_wtr_utl.Bld_href(a_ttl_bry); - byte[] a_title = lnki_wtr_utl.Bld_title(a_text); - return rv.Vals_(a_href, a_title, a_text); + return lnki_bldr.Title_(title).Href_(wiki, self_lnkr.Add_int(Xows_arg_mgr.Arg_bry_page_index, paging_idx).Bld_to_bry()).Img_16x16(img_path).Img_pos_is_left_(img_pos_is_left).Caption_(title).Bld_to_bry(); } private static final Bry_fmtr fmtr_page = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last - ( "~{rslts_hdr}" - , "
    ~{bwd_a}~{fwd_a}
    ~{tbls}" - , "
    ~{bwd_a}~{fwd_a}
    " - ), "rslts_hdr", "bwd_a", "fwd_a", "tbls"); - // + ( "~{rslts_hdr}~{option_link}" + , "
    ~{bwd_a}~{fwd_a}
    ~{tbls}" + , "
    ~{bwd_a}~{fwd_a}
    " + ), "rslts_hdr", "option_link", "bwd_a", "fwd_a", "tbls"); private static final Bry_fmtr fmtr_tbl = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last - ( "
    " + ( "
    " , " " - , " " , " " , " " - , " " - , " " - , " " - , " " , " " @@ -95,11 +93,6 @@ class Xows_html_wkr { , " " , "
    Help" // SERVER:"~{wiki}~{cancel}" , "
    ~{wiki}~{cancel}" - , "
    ~{hdr_len}" + , " ~{hdr_len}" , " ~{hdr_ttl}" , "
    " ), "wiki", "cancel", "hdr_len", "hdr_ttl", "insert_key", "rows"); - private static final Bry_fmtr fmtr_link = Bry_fmtr.new_("
    ~{a_text}", "a_href", "a_title", "a_text"); // SERVER:"~{a_text}", "a_id", "a_href", "a_title", "a_text"); // SERVER:"" - , " ~{page_len}" + , " ~{page_len}" , " " - , " ~{a_text}" // SERVER:"~{a_text}" // SERVER:"Next"); - fxt.Test_paging(Bool_.N, 1, "Previous"); - fxt.Test_paging(Bool_.Y, 2, "Next"); - fxt.Test_paging(Bool_.N, 0, "Previous"); + fxt.Test_paging(Bool_.Y, 1, "Next"); + fxt.Test_paging(Bool_.N, 1, "Previous"); + fxt.Test_paging(Bool_.Y, 2, "Next"); + fxt.Test_paging(Bool_.N, 0, " "); } @Test public void Rows() { fxt.Test_rows(Xows_db_row.Ary(fxt.Make_row(10, "A"), fxt.Make_row(20, "B")), String_.Concat_lines_nl_skip_last ( "" , " " - , " 10" + , " 10" , " " - , " A" + , " A" , " " , " " , " " - , " 20" + , " 20" , " " - , " B" + , " B" , " " , " " )); @@ -54,13 +54,12 @@ class Xows_html_wkr_fxt { return this; } public void Test_paging(boolean fwd, int paging_idx, String expd) { - Xows_ui_qry qry = new Xows_ui_qry(Bry_.new_ascii_("A"), paging_idx, 100, Xosrh_rslt_itm_sorter.Tid_len_dsc, new Xows_ns_mgr(), true, Bry_.Ary(wiki.Domain_bry())); + Xows_ui_qry qry = new Xows_ui_qry(Bry_.new_ascii_("A"), paging_idx, 100, Xosrh_rslt_itm_sorter.Tid_len_dsc, new Xows_ns_mgr(), true, new Xow_domain[] {Xow_domain_.parse(wiki.Domain_bry())}); qry.Page_max_(2); - html_mgr.Init_by_wiki(wiki.Html_mgr__lnki_wtr_utl(), wiki.Lang().Num_mgr()); + html_mgr.Init_by_wiki(wiki, wiki.Html_mgr__lnki_wtr_utl(), wiki.Lang().Num_mgr()); html_mgr.Qry_(qry); - Bry_fmtr_arg fmtr_arg = html_mgr.Paging_link(fwd); - fmtr_arg.XferAry(tmp_bfr, 0); - Tfds.Eq(expd, tmp_bfr.Xto_str_and_clear()); + byte[] paging_link = html_mgr.Paging_link(fwd); + Tfds.Eq(expd, String_.new_ascii_(paging_link)); } public void Test_rows(Xows_db_row[] rows, String expd) { Xows_ui_rslt rslt = new Xows_ui_rslt(); @@ -74,6 +73,6 @@ class Xows_html_wkr_fxt { } public Xows_db_row Make_row(int len, String ttl_str) { byte[] ttl_bry = Bry_.new_utf8_(ttl_str); - return new Xows_db_row(Bry_.new_ascii_("w"), 1, Xow_ns_.Id_main, len, ttl_bry, ttl_bry); + return new Xows_db_row(Bry_.new_ascii_("w"), wiki.Ttl_parse(ttl_bry), 1, len); } } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java b/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java index 7d053daa7..2f0def914 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java @@ -19,30 +19,34 @@ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gpl import gplx.core.primitives.*; import gplx.xowa.wikis.*; import gplx.xowa.apis.xowa.specials.*; import gplx.xowa.wikis.domains.crts.*; public class Xows_page__search implements Xows_page, GfoInvkAble, GfoEvObj { - private final Xow_domain wiki_domain; private final Xoapi_search search_api; + private final Xoae_app app; private final Xow_domain wiki_domain; private final Xoapi_search search_api; private final Xows_core search_mgr; private final Xows_arg_mgr args_mgr = new Xows_arg_mgr(); - private Xow_domain_crt_itm multi_wiki_crt; + private Xow_domain[] search_domain_ary; public Xows_page__search(Xowe_wiki wiki) { + this.app = wiki.Appe(); this.wiki_domain = wiki.Domain_itm(); this.search_mgr = new Xows_core(wiki.Appe().Wiki_mgr()); this.ev_mgr = GfoEvMgr.new_(this); this.search_api = wiki.Appe().Api_root().Special().Search(); + GfoEvMgr_.SubSame_many(search_api, this, Xoapi_search.Evt_multi_wikis_changed, Xoapi_search.Evt_multi_wikis_changed); } public GfoEvMgr EvMgr() {return ev_mgr;} private GfoEvMgr ev_mgr; - public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { - if (ctx.Match(k, Xoapi_search.Evt_multi_wiki_rules_changed)) this.multi_wiki_crt = search_api.Multi_wiki_crt(wiki_domain); - else return GfoInvkAble_.Rv_unhandled; - return this; + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__search;} + private void Multi_wikis_changed() { + Xow_domain_crt_itm crt = search_api.Multi_wikis_crt(wiki_domain); + this.search_domain_ary = app.User().Wiki().Xwiki_mgr().Get_by_crt(wiki_domain, crt); + if (search_domain_ary.length == 0) search_domain_ary = new Xow_domain[] {wiki_domain}; // default to current if bad input + Multi_sorts_changed(); } - public boolean Match_ttl(Xoa_ttl ttl) { - return ttl.Ns().Id_special() && Bry_.Eq(ttl.Root_txt(), Bry_search); + private void Multi_sorts_changed() { + Xow_domain_crt_itm[] ary = search_api.Multi_sorts_crt(wiki_domain); + if (ary == null) return; // default to no sort if bad input + Xow_domain_sorter__manual sorter = new Xow_domain_sorter__manual(wiki_domain, ary); + Xow_domain_sorter__manual.Sort(sorter, search_domain_ary); } public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { if (wiki.Domain_tid() == Xow_domain_.Tid_int_home) return; // do not allow search in home wiki; will throw null ref error b/c no search_ttl dirs - if (multi_wiki_crt == null) { - this.multi_wiki_crt = search_api.Multi_wiki_crt(wiki.Domain_itm()); - GfoEvMgr_.SubSame_many(search_api, this, Xoapi_search.Evt_multi_wiki_rules_changed); - } + if (search_domain_ary == null) Multi_wikis_changed(); // get args Xog_search_suggest_mgr search_suggest_mgr = wiki.Appe().Gui_mgr().Search_suggest_mgr(); args_mgr.Clear(); @@ -60,11 +64,11 @@ public class Xows_page__search implements Xows_page, GfoInvkAble, GfoEvObj { && Bry_finder.Find_fwd(search_bry, Byte_ascii.Asterisk) == -1 // search term does not have asterisk ) search_bry = Bry_.Add(search_bry, Byte_ascii.Asterisk); - url.Page_bry_(Bry_.Add(Bry_.new_ascii_("Special:Search/"), search_bry));// HACK: need to re-set Page b/c href_parser does not eliminate qargs; DATE:2013-02-08 + url.Page_bry_(Bry_.Add(Xows_special_meta_.Itm__search.Ttl_bry(), Byte_ascii.Slash_bry, search_bry));// HACK: need to re-set Page b/c href_parser does not eliminate qargs; DATE:2013-02-08 // search wiki Xoa_ttl search_ttl = Xoa_ttl.parse_(wiki, search_bry); Xoae_page search_page = page; - if (!Bry_.Eq(search_bry, Bry_special_name)) // do not lookup page else stack overflow; happens when going directly to Special:Search (from history) + if (!Bry_.Eq(search_bry, Xows_special_meta_.Itm__search.Ttl_bry())) // do not lookup page else stack overflow; happens when going directly to Special:Search (from history) search_page = wiki.Data_mgr().Get_page(search_ttl, false); // try to find page; EX:Special:Searc?search=Earth -> en.w:Earth; needed for search suggest // page not found, or explicit_search invoked if (search_page.Missing() || url.Search_fulltext()) { @@ -74,8 +78,8 @@ public class Xows_page__search implements Xows_page, GfoInvkAble, GfoEvObj { return; } page.Html_data().Html_restricted_n_(); - page.Html_data().Xtn_search_text_(search_bry); - Xows_ui_qry qry = new Xows_ui_qry(search_bry, args_mgr.Paging_idx(), search_api.Results_per_page(), args_mgr.Sort_tid(), args_mgr.Ns_mgr(), search_api.Async_db(), Bry_.Ary(wiki.Domain_bry())); + page.Html_data().Xtn_search_text_(search_bry); + Xows_ui_qry qry = new Xows_ui_qry(search_bry, args_mgr.Paging_idx(), search_api.Results_per_page(), args_mgr.Sort_tid(), args_mgr.Ns_mgr(), search_api.Async_db(), search_domain_ary); search_mgr.Search(wiki, page, qry); } // page found; return it; @@ -87,7 +91,12 @@ public class Xows_page__search implements Xows_page, GfoInvkAble, GfoEvObj { page.Ttl_(search_ttl).Url_(Xoa_url.new_(wiki.Domain_bry(), search_ttl.Full_txt())).Redirected_(true); } } + public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + if (ctx.Match(k, Xoapi_search.Evt_multi_wikis_changed)) Multi_wikis_changed(); + else if (ctx.Match(k, Xoapi_search.Evt_multi_sorts_changed)) Multi_sorts_changed(); + else return GfoInvkAble_.Rv_unhandled; + return this; + } public static final byte Match_tid_all = 0, Match_tid_bgn = 1; public static final byte Version_null = 0, Version_1 = 1, Version_2 = 2; - private static final byte[] Bry_special_name = Bry_.new_ascii_("Special:Search"), Bry_search = Bry_.new_ascii_("Search"); } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_paging_parser.java b/400_xowa/src/gplx/xowa/specials/search/Xows_paging_parser.java new file mode 100644 index 000000000..98d44e2e6 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_paging_parser.java @@ -0,0 +1,40 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.core.brys.*; +class Xows_paging_parser { + private final ListAdp itm_list = ListAdp_.new_(); + private final Bry_rdr rdr = new Bry_rdr(); + public Xows_paging_itm[] Parse(byte[] raw) { // EX: en.wikipedia.org|41|60;en.wiktionary.org|21|40; + rdr.Src_(raw); + while (!rdr.Pos_is_eos()) { + byte[] wiki = rdr.Read_bry_to_pipe(); + int bgn = rdr.Read_int_to_pipe(); + int end = rdr.Read_int_to_semic(); + Xows_paging_itm itm = new Xows_paging_itm(wiki, bgn, end); + itm_list.Add(itm); + } + return (Xows_paging_itm[])itm_list.Xto_ary_and_clear(Xows_paging_itm.class); + } +} +class Xows_paging_itm { + public Xows_paging_itm(byte[] wiki, int bgn, int end) {this.wiki = wiki; this.bgn = bgn; this.end = end;} + public byte[] Wiki() {return wiki;} private final byte[] wiki; + public int Bgn() {return bgn;} private final int bgn; + public int End() {return end;} private final int end; +} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java index 82b7d7681..726727482 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java @@ -34,16 +34,17 @@ class Xows_ui_async_fxt { private Xows_html_row html_row; private static final byte[] Bry_enwiki = Bry_.new_ascii_("w"); private Xows_ui_async async; private Xog_js_wkr__log js_wkr = new Xog_js_wkr__log(); + private Xowe_wiki wiki; public void Clear() { Xoae_app app = Xoa_app_fxt.app_(); - Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "w"); + this.wiki = Xoa_app_fxt.wiki_(app, "w"); html_row = new Xows_html_row(); html_row.Ctor(wiki.Html_mgr__lnki_wtr_utl()); html_row.Fmtr().Fmt_("~{page_key}"); async = new Xows_ui_async(Cancelable_.Never, html_row, js_wkr, 5, Bry_enwiki); } public Xows_db_row Make_rslt(int len, String ttl) { byte[] ttl_bry = Bry_.new_ascii_(ttl); - return new Xows_db_row(Bry_enwiki, 1, Xow_ns_.Id_main, len, ttl_bry, ttl_bry); + return new Xows_db_row(Bry_enwiki, wiki.Ttl_parse(ttl_bry), 1, len); } public Object[] Make_args_append(String uid, String html) {return Object_.Ary(Xog_js_wkr__log.Proc_append_above, uid, html);} public Object[] Make_args_replace(String uid) {return Object_.Ary(Xog_js_wkr__log.Proc_replace_html, uid, "");} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java index bd8d480b8..d2e7bd25b 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java @@ -16,72 +16,98 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.threads.*; import gplx.xowa.wikis.*; import gplx.xowa.files.gui.*; import gplx.xowa.gui.views.*; +import gplx.threads.*; import gplx.html.*; +import gplx.xowa.wikis.*; import gplx.xowa.files.gui.*; import gplx.xowa.gui.views.*; class Xows_ui_cmd implements GfoInvkAble, Cancelable, Xog_tab_close_lnr { - private final Xows_core mgr; - private final Xows_ui_qry qry; private final Xows_ui_rslt rslt; private final Xowe_wiki wiki; private final Xog_tab_close_mgr tab_close_mgr; - private final boolean async; private Xows_ui_async async_wkr; private final Xog_js_wkr js_wkr; + private final Xows_core mgr; private final Xows_ui_qry qry; private final Xows_ui_rslt rslt; + private final Xow_wiki wiki; private final Xoae_page page; private final Xog_tab_close_mgr tab_close_mgr; private final Xog_js_wkr js_wkr; + private final boolean async; private Xows_ui_async async_wkr; private Xows_db_cache cache; - public Xows_ui_cmd(Xows_core mgr, Xows_ui_qry qry, Xowe_wiki wiki, Xog_tab_close_mgr tab_close_mgr, Xog_js_wkr js_wkr) { - this.mgr = mgr; this.qry = qry; this.wiki = wiki; this.tab_close_mgr = tab_close_mgr; this.js_wkr = js_wkr; + private final Object thread_lock = new Object(); + public Xows_ui_cmd(Xows_core mgr, Xows_ui_qry qry, Xow_wiki wiki, Xoae_page page, Xog_tab_close_mgr tab_close_mgr, Xog_js_wkr js_wkr) { + this.mgr = mgr; this.qry = qry; this.wiki = wiki; this.page = page; this.tab_close_mgr = tab_close_mgr; this.js_wkr = js_wkr; this.async = Xoa_app_.Mode_is_gui() && qry.Async_db(); this.rslt = new Xows_ui_rslt(); - this.key = gplx.html.Html_utl.Encode_id_as_bry(Bry_.Add_w_dlm(Byte_ascii.Pipe, qry.Key(), wiki.Domain_bry())); + this.key = Html_utl.Encode_id_as_bry(Bry_.Add(qry.Key(), Byte_ascii.Pipe_bry, wiki.Domain_bry())); } - public byte[] Key_for_html() {return key;} private byte[] key; - public String Wiki_domain_str() {return wiki.Domain_str();} - public byte[] Wiki_domain_bry() {return wiki.Domain_bry();} + public byte[] Key() {return key;} private final byte[] key; + public Xow_wiki Wiki() {return wiki;} public Xows_ui_rslt Rslt() {return rslt;} - public boolean Canceled() {synchronized (this) {return canceled;}} private boolean canceled; + public boolean Canceled() {synchronized (thread_lock) {return canceled;}} private boolean canceled; public void Cancel() { Xoa_app_.Usr_dlg().Prog_many("", "", "search canceled: key=~{0}", key); - synchronized (this) { - canceled = true; - } + synchronized (thread_lock) {canceled = true;} + this.Hide_cancel_btn(); } public void Cancel_reset() {} - public void Search_db() { - tab_close_mgr.Add(this); - mgr.Db().Search(this, qry, rslt, cache, wiki); - mgr.Search_end(this); - synchronized (this) { - if (canceled) return; // NOTE: must check else throws SWT exception - } - js_wkr.Html_atr_set("xowa_cancel_" + wiki.Domain_str(), "style", "display:none;"); - qry.Page_max_(cache.Count() / qry.Page_len()); - Xoa_app_.Usr_dlg().Prog_many("", "", ""); - } public boolean Search() { this.cache = mgr.Get_cache_or_new(key); - boolean rv = false; - if (qry.Itms_end() > cache.Count() && !cache.Done()) { - if (async) - ThreadAdp_.invk_("xowa.special.search", this, Invk_search_db).Start(); + boolean rv = false, fill_from_cache = true; + if (!cache.Done() && (qry.Itms_end() > cache.Itms_end())) { + if (async) { + fill_from_cache = false; // NOTE: do not retrieve cached results to page, else ui_async cmd will add out of order; DATE:2015-04-24 + if (async_wkr == null) async_wkr = new Xows_ui_async(this, mgr.Html_wkr().Html_rows(), js_wkr, qry.Page_len(), wiki.Domain_bry()); + ThreadAdp_.invk_(gplx.xowa.apps.Xoa_thread_.Key_special_search_db, this, Invk_search_db).Start(); + } else Search_db(); rv = true; } - cache.Get_between(rslt, qry.Itms_bgn(), qry.Itms_end()); + if (fill_from_cache) { + cache.Get_between(rslt, qry.Itms_bgn(), qry.Itms_end()); + qry.Page_max_(cache.Count() / qry.Page_len()); + } return rv; } + public void Search_db() { + tab_close_mgr.Add(this); + if (async) { + while (!page.Html_data().Mode_wtxt_shown()) // NOTE:must check for wtxt_shown else async can happen first, and then be overwritten by wtxt; DATE:2015-04-26 + ThreadAdp_.Sleep(100); + // show any existing items in the cache on screen; new updates wil bump these off; SEE:NOTE:show_existing;DATE:2015-04-26 + int qry_itms_bgn = qry.Itms_bgn(), cache_count = cache.Count(); + for (int i = qry_itms_bgn; i < cache_count; ++i) + async_wkr.Add(cache.Get_at(i)); + } + mgr.Db().Search(this, qry, rslt, cache, wiki); + mgr.Search_end(this); + if (this.Canceled()) return; // NOTE: must check else throws SWT exception + this.Hide_cancel_btn(); + if (cache.Done()) + qry.Page_max_(cache.Count() / qry.Page_len()); + Xoa_app_.Usr_dlg().Prog_many("", "", ""); + } + private void Hide_cancel_btn() { + ThreadAdp_.invk_(gplx.xowa.apps.Xoa_thread_.Key_special_search_cancel, this, Invk_hide_cancel).Start(); + } + private void Hide_cancel_btn_async() { + js_wkr.Html_atr_set("xowa_cancel_" + wiki.Domain_str(), "style", "display:none;"); + } + public void Add_rslt(Xows_db_row rslt) { + cache.Add(rslt); + if (async) async_wkr.Add(rslt); + } public boolean When_close(Xog_tab_itm tab) { this.Cancel(); return true; } - public void Add_rslt(Xows_db_row rslt) { - cache.Add(rslt); - if (async) { - if (async_wkr == null) - async_wkr = new Xows_ui_async(this, mgr.Html_wkr().Html_rows(), js_wkr, qry.Page_len(), wiki.Domain_bry()); - synchronized (this) { - if (canceled) return; - } - async_wkr.Add(rslt); - } - } public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_search_db)) Search_db(); + else if (ctx.Match(k, Invk_hide_cancel)) Hide_cancel_btn_async(); else return GfoInvkAble_.Rv_unhandled; return this; - } public static final String Invk_search_db = "search_db"; + } + private static final String Invk_search_db = "search_db", Invk_hide_cancel = "hide_cancel"; } +/* +NOTE:show_existing. code needed to show A1 +EX: search="A*": "A" has 400 words; "A1" has 1; +. search 1-20 returns 20 words for A and 1 word for A1. +.. the 1st A word has a len of 999 and the 20th A word has a length of 900; +.. A1 has a length of 799 +. search 21-40 returns 20 words for A +.. the 21st word has a len of 899 and the 40th has a len of 800 +.. A1 should show up briefly, and then get pushed off screen by 21-40 +. search 61-40 returns 20 words for A +.. A1 must show up +*/ diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java index e8636a26e..1a13856b6 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java @@ -16,13 +16,15 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.xowa.wikis.*; class Xows_ui_qry { private final ListAdp cmd_list = ListAdp_.new_(); - public Xows_ui_qry(byte[] search_raw, int page_idx, int page_len, byte sort_tid, Xows_ns_mgr ns_mgr, boolean async_db, byte[][] wiki_domains) { + public Xows_ui_qry(byte[] search_raw, int page_idx, int page_len, byte sort_tid, Xows_ns_mgr ns_mgr, boolean async_db, Xow_domain[] wiki_domains) { this.search_raw = search_raw; this.page_idx = page_idx; this.page_len = page_len; this.sort_tid = sort_tid; this.ns_mgr = ns_mgr; this.async_db = async_db; this.wiki_domains = wiki_domains; this.itms_bgn = page_idx * page_len; this.page_max = page_idx; // default page_max to page_idx; adjust later when all results are known this.key = Bry_.Add_w_dlm(Byte_ascii.Pipe, search_raw, ns_mgr.To_hash_key()); + this.special_link_base_href = Bry_.Add(Bry_.new_ascii_("Special:Search/"), search_raw, Bry_.new_ascii_("?fulltext=y")); } public byte[] Key() {return key;} private final byte[] key; public byte[] Search_raw() {return search_raw;} private final byte[] search_raw; @@ -34,9 +36,10 @@ class Xows_ui_qry { public int Itms_end() {return itms_bgn + page_len;} public byte Sort_tid() {return sort_tid;} private final byte sort_tid; public Xows_ns_mgr Ns_mgr() {return ns_mgr;} private final Xows_ns_mgr ns_mgr; - public byte[][] Wiki_domains() {return wiki_domains;} private byte[][] wiki_domains; + public Xow_domain[] Wiki_domains() {return wiki_domains;} private final Xow_domain[] wiki_domains; public void Page_max_(int v) {this.page_max = v;} public int Cmds__len() {return cmd_list.Count();} public Xows_ui_cmd Cmds__get_at(int i) {return (Xows_ui_cmd)cmd_list.FetchAt(i);} public void Cmds__add(Xows_ui_cmd cmd) {cmd_list.Add(cmd);} + public byte[] Special_link_base_href() {return special_link_base_href;} private final byte[] special_link_base_href; } diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java b/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java index cd2a142d3..02b6c47db 100644 --- a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java +++ b/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_parser.java @@ -20,7 +20,7 @@ public class Xow_search_parser { private Xow_search_parser_ctx parse_ctx = new Xow_search_parser_ctx(); private byte[] src; public Xows_db_matcher Parse(byte[] src) { this.src = src; - Xow_search_tkn[] tkns = Xow_search_scanner.I.Scan(src); + Xow_search_tkn[] tkns = new Xow_search_scanner().Scan(src); return Parse_itm_or(parse_ctx.Init(tkns)); } private Xows_db_matcher Parse_itm_or(Xow_search_parser_ctx parse_ctx) { @@ -76,7 +76,6 @@ public class Xow_search_parser { return new Xows_db_matcher(tid, tkn.Val(src), null, null); } private static Xows_db_matcher new_join(int tid, Xows_db_matcher lhs, Xows_db_matcher rhs) {return new Xows_db_matcher(tid, null, lhs, rhs);} - public static final Xow_search_parser I = new Xow_search_parser(); Xow_search_parser() {} } class Xow_search_parser_ctx { private Xow_search_tkn[] ary; private int pos = 0; private int ary_len; diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java b/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java index 023f4249b..ab873d9e8 100644 --- a/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java +++ b/400_xowa/src/gplx/xowa/specials/search/parsers/Xow_search_scanner.java @@ -141,5 +141,4 @@ class Xow_search_scanner { .Add_str_byte(")" , Xow_search_tkn.Tid_paren_end) .Add_str_byte("or" , Xow_search_tkn.Tid_or) .Add_str_byte("and" , Xow_search_tkn.Tid_and); - public static final Xow_search_scanner I = new Xow_search_scanner(); Xow_search_scanner() {} } diff --git a/400_xowa/src/gplx/xowa/specials/statistics/Xop_statistics_page.java b/400_xowa/src/gplx/xowa/specials/statistics/Xop_statistics_page.java index fdb568fa4..a7caf2790 100644 --- a/400_xowa/src/gplx/xowa/specials/statistics/Xop_statistics_page.java +++ b/400_xowa/src/gplx/xowa/specials/statistics/Xop_statistics_page.java @@ -21,6 +21,7 @@ public class Xop_statistics_page implements Xows_page { private Xop_statistics_stats_page_grp stats_page = new Xop_statistics_stats_page_grp(); // private Xop_statistics_stats_wiki_grp stats_wiki = new Xop_statistics_stats_wiki_grp(); private Xop_statistics_stats_ns_grp stats_ns = new Xop_statistics_stats_ns_grp(); + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__statistics;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { byte[] html = Build_html(wiki); page.Html_data().Html_restricted_n_(); // [[Special:]] pages allow all HTML diff --git a/400_xowa/src/gplx/xowa/specials/xowa/default_tab/Default_tab_page.java b/400_xowa/src/gplx/xowa/specials/xowa/default_tab/Default_tab_page.java index 7de1d79e2..e3cf0643d 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/default_tab/Default_tab_page.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/default_tab/Default_tab_page.java @@ -17,14 +17,11 @@ along with this program. If not, see . */ package gplx.xowa.specials.xowa.default_tab; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.xowa.*; public class Default_tab_page implements Xows_page { + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__default_tab;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { page.Data_raw_(Bry_.Empty); page.Html_data().Custom_html_(Bry_.Empty); page.Html_data().Custom_name_(Tab_name_bry); } - public static final String Ttl_name_str = "XowaDefaultTab"; - public static final byte[] Ttl_name_bry = Bry_.new_ascii_("XowaDefaultTab"); - public static final String Ttl_full_str = "Special:" + Ttl_name_str; - public static final byte[] Ttl_full_bry = Bry_.new_ascii_(Ttl_full_str); public static final byte[] Tab_name_bry = Bry_.new_ascii_("New Tab"); } diff --git a/400_xowa/src/gplx/xowa/specials/xowa/file_browsers/Xosp_fbrow_special.java b/400_xowa/src/gplx/xowa/specials/xowa/file_browsers/Xosp_fbrow_special.java index c8382a534..be72a8396 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/file_browsers/Xosp_fbrow_special.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/file_browsers/Xosp_fbrow_special.java @@ -19,6 +19,7 @@ package gplx.xowa.specials.xowa.file_browsers; import gplx.*; import gplx.xowa.* import gplx.xowa.specials.*; import gplx.ios.*; public class Xosp_fbrow_special implements Xows_page { private static final Xoa_url_arg_mgr url_args = new Xoa_url_arg_mgr(null); + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__file_browser;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { Xosp_fbrow_rslt rslt = Gen(url.Args(), GfoInvkAble_.Null); page.Html_data().Html_restricted_n_(); @@ -36,5 +37,4 @@ public class Xosp_fbrow_special implements Xows_page { .Add_bry_obj(Xosp_fbrow_cmd__wiki_add.Regy_key, Xosp_fbrow_cmd__wiki_add.I) .Add_bry_obj(Xosp_fbrow_cmd__root_set.Regy_key, Xosp_fbrow_cmd__root_set.I) ; - public static final byte[] Ttl_name_bry = Bry_.new_ascii_("XowaFileBrowser"); } diff --git a/400_xowa/src/gplx/xowa/specials/xowa/popup_history/Popup_history_page.java b/400_xowa/src/gplx/xowa/specials/xowa/popup_history/Popup_history_page.java index 81b78b523..61a5964e1 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/popup_history/Popup_history_page.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/popup_history/Popup_history_page.java @@ -18,6 +18,7 @@ along with this program. If not, see . package gplx.xowa.specials.xowa.popup_history; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.xowa.*; import gplx.xowa.html.modules.popups.*; public class Popup_history_page implements Xows_page { + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__popup_history;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { Xoae_page cur_page = wiki.Appe().Gui_mgr().Browser_win().Active_page(); if (cur_page == null) return; OrderedHash hash = cur_page.Popup_mgr().Itms(); @@ -32,9 +33,8 @@ public class Popup_history_page implements Xows_page { page.Html_data().Html_restricted_n_(); } private Bry_fmtr fmtr_main = Bry_fmtr.new_("~{ttl}\n\n", "href", "ttl"); // NOTE: need to use anchor (as opposed to lnki or lnke) b/c xwiki will not work on all wikis - public static final byte[] Ttl_name_bry = Bry_.new_ascii_("XowaPopupHistory"); public static boolean Ttl_chk(Xoa_ttl ttl) { return ttl.Ns().Id_special() - && Bry_.Eq(ttl.Page_db(), Ttl_name_bry); + && Bry_.Eq(ttl.Page_db(), Xows_special_meta_.Itm__popup_history.Key_bry()); } } diff --git a/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java b/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java index decb421f0..b7b3c68f3 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/system_data/System_data_page.java @@ -19,6 +19,7 @@ package gplx.xowa.specials.xowa.system_data; import gplx.*; import gplx.xowa.*; import gplx.core.primitives.*; public class System_data_page implements Xows_page { private Xoa_url_arg_hash arg_hash = new Xoa_url_arg_hash(); + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__system_data;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { arg_hash.Load(url); byte[] file_type = arg_hash.Get_val_bry_or(Arg_type, null); if (file_type == null) return; diff --git a/400_xowa/src/gplx/xowa/users/data/Xoud_history_mgr.java b/400_xowa/src/gplx/xowa/users/data/Xoud_history_mgr.java index 5c2a69e97..883421354 100644 --- a/400_xowa/src/gplx/xowa/users/data/Xoud_history_mgr.java +++ b/400_xowa/src/gplx/xowa/users/data/Xoud_history_mgr.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package gplx.xowa.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; import gplx.threads.*; import gplx.dbs.*; +import gplx.xowa.specials.*; public class Xoud_history_mgr implements GfoInvkAble { private Xoud_history_tbl history_tbl; public void Conn_(Db_conn new_conn, boolean created, int user_id) { @@ -47,9 +48,9 @@ public class Xoud_history_mgr implements GfoInvkAble { byte[] page_db = ttl.Page_db(); return ( ttl.Ns().Id_special() && ( Bry_.Eq(page_db, gplx.xowa.users.history.Xou_history_mgr.Ttl_name) // do not add XowaPageHistory to history - || Bry_.Eq(page_db, gplx.xowa.specials.xowa.popup_history.Popup_history_page.Ttl_name_bry) - || Bry_.Eq(page_db, gplx.xowa.specials.xowa.default_tab.Default_tab_page.Ttl_name_bry) - || Bry_.Eq(page_db, Xoud_history_special.Ttl_name) + || Bry_.Eq(page_db, Xows_special_meta_.Itm__popup_history.Key_bry()) + || Bry_.Eq(page_db, Xows_special_meta_.Itm__default_tab.Key_bry()) + || Bry_.Eq(page_db, Xows_special_meta_.Itm__page_history.Key_bry()) ) ); } diff --git a/400_xowa/src/gplx/xowa/users/data/Xoud_history_special.java b/400_xowa/src/gplx/xowa/users/data/Xoud_history_special.java index df230d38a..4bb944971 100644 --- a/400_xowa/src/gplx/xowa/users/data/Xoud_history_special.java +++ b/400_xowa/src/gplx/xowa/users/data/Xoud_history_special.java @@ -19,6 +19,7 @@ package gplx.xowa.users.data; import gplx.*; import gplx.xowa.*; import gplx.xow import gplx.xowa.specials.*; public class Xoud_history_special implements Bry_fmtr_arg, Xows_page { private ListAdp rows = ListAdp_.new_(); + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__page_history;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { Xoae_app app = wiki.Appe(); Xoud_history_mgr mgr = app.User().Data_mgr().History_mgr(); @@ -55,5 +56,4 @@ public class Xoud_history_special implements Bry_fmtr_arg, Xows_page { , " " ), "itm_wiki", "itm_page", "itm_count", "itm_last" ); - public static final byte[] Ttl_name = Bry_.new_ascii_("XowaHistory"); } diff --git a/400_xowa/src/gplx/xowa/users/data/Xoud_opt_scope_tst.java b/400_xowa/src/gplx/xowa/users/data/Xoud_opt_scope_tst.java index 631ea8253..1a3ce4e91 100644 --- a/400_xowa/src/gplx/xowa/users/data/Xoud_opt_scope_tst.java +++ b/400_xowa/src/gplx/xowa/users/data/Xoud_opt_scope_tst.java @@ -24,7 +24,7 @@ public class Xoud_opt_scope_tst { fxt.Test_parse("en.w" , fxt.Make(Xol_lang_itm_.Id_en, Xow_domain_.Tid_int_wikipedia)); fxt.Test_parse("en.*" , fxt.Make(Xol_lang_itm_.Id_en, Xoud_opt_scope.Type_id_wildcard)); fxt.Test_parse("*.w" , fxt.Make(Xoud_opt_scope.Lang_id_wildcard, Xow_domain_.Tid_int_wikipedia)); - fxt.Test_parse("*.*" , Xoud_opt_scope.App); + fxt.Test_parse("" , Xoud_opt_scope.App); fxt.Test_parse("en.w,fr.d" , fxt.Make(Xol_lang_itm_.Id_en, Xow_domain_.Tid_int_wikipedia), fxt.Make(Xol_lang_itm_.Id_fr, Xow_domain_.Tid_int_wiktionary)); } } diff --git a/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java b/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java index 4f0e0ba9d..f2ee671b1 100644 --- a/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java +++ b/400_xowa/src/gplx/xowa/users/history/Xou_history_html.java @@ -18,6 +18,21 @@ along with this program. If not, see . package gplx.xowa.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*; import gplx.xowa.specials.*; public class Xou_history_html implements Bry_fmtr_arg, Xows_page { + public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__page_history;} + public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { + this.app = wiki.Appe(); this.mgr = app.User().History_mgr(); + mgr.Sort(); + Bry_bfr bfr = app.Utl__bfr_mkr().Get_m001(); + html_grp.Bld_bfr_many(bfr, this); + page.Data_raw_(bfr.To_bry_and_rls()); + } + public void XferAry(Bry_bfr bfr, int idx) { + int len = mgr.Len(); + for (int i = 0; i < len; i++) { + Xou_history_itm itm = mgr.Get_at(i); + html_itm.Bld_bfr_many(bfr, itm.Wiki(), itm.Page(), itm.View_count(), itm.View_end().XtoStr_fmt_yyyy_MM_dd_HH_mm()); + } + } private Xou_history_mgr mgr; Xoae_app app; public Bry_fmtr Html_grp() {return html_grp;} Bry_fmtr html_grp = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last ( "" , " " @@ -37,18 +52,4 @@ public class Xou_history_html implements Bry_fmtr_arg, Xows_page { , " " , " " ), "itm_wiki", "itm_page", "itm_count", "itm_last"); - public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { - this.app = wiki.Appe(); this.mgr = app.User().History_mgr(); - mgr.Sort(); - Bry_bfr bfr = app.Utl__bfr_mkr().Get_m001(); - html_grp.Bld_bfr_many(bfr, this); - page.Data_raw_(bfr.To_bry_and_rls()); - } - public void XferAry(Bry_bfr bfr, int idx) { - int len = mgr.Len(); - for (int i = 0; i < len; i++) { - Xou_history_itm itm = mgr.Get_at(i); - html_itm.Bld_bfr_many(bfr, itm.Wiki(), itm.Page(), itm.View_count(), itm.View_end().XtoStr_fmt_yyyy_MM_dd_HH_mm()); - } - } private Xou_history_mgr mgr; Xoae_app app; } diff --git a/400_xowa/src/gplx/xowa/wikis/Xoa_wiki_mgr.java b/400_xowa/src/gplx/xowa/wikis/Xoa_wiki_mgr.java index aa968a8b7..7022af3f6 100644 --- a/400_xowa/src/gplx/xowa/wikis/Xoa_wiki_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/Xoa_wiki_mgr.java @@ -42,15 +42,6 @@ public class Xoa_wiki_mgr implements GfoInvkAble { if (rv == null) rv = New_wiki(key); return rv; } - public Xowe_wiki[] Get_by_crt(Xow_domain cur, Xow_domain_crt_itm crt) { - ListAdp rv = ListAdp_.new_(); - int len = this.Count(); - for (int i = 0; i < len; ++i) { - Xow_wiki wiki = this.Get_at(i); - if (crt.Matches(cur, wiki.Domain_itm())) rv.Add(wiki); - } - return (Xowe_wiki[])rv.Xto_ary_and_clear(Xowe_wiki.class); - } public Xowe_wiki Wiki_commons() { Xowe_wiki rv = this.Get_by_key_or_null(Xow_domain_.Domain_bry_commons); if (rv != null) rv.Init_assert(); diff --git a/400_xowa/src/gplx/xowa/wikis/Xow_domain.java b/400_xowa/src/gplx/xowa/wikis/Xow_domain.java index e37ee1929..99e4e4aa9 100644 --- a/400_xowa/src/gplx/xowa/wikis/Xow_domain.java +++ b/400_xowa/src/gplx/xowa/wikis/Xow_domain.java @@ -32,6 +32,7 @@ public class Xow_domain { public int Lang_orig_uid() {return lang_orig_itm.Id();} public byte[] Lang_orig_key() {return lang_orig_itm.Key();} public byte[] Wmf_key() {return wmf_key;} public void Wmf_key_(byte[] v) {wmf_key = v;} private byte[] wmf_key; + public int Sort_idx() {return sort_idx;} public void Sort_idx_(int v) {sort_idx = v;} private int sort_idx = -1; public static Xow_domain new_(byte[] domain_bry, int domain_tid, byte[] lang_key) { Xol_lang_itm lang_itm = Xol_lang_itm_.Get_by_key_or_intl(lang_key); return new Xow_domain(domain_bry, domain_tid, lang_itm, lang_itm); diff --git a/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file.java b/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file.java index c120d0c21..40921d420 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file.java +++ b/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file.java @@ -34,7 +34,7 @@ public class Xowd_db_file { this.tbl__css_file = new Xowd_css_file_tbl(conn); this.tbl__cat_core = new Xowd_cat_core_tbl(conn, schema_is_1); this.tbl__cat_link = new Xowd_cat_link_tbl(conn, schema_is_1); - this.tbl__wbase_qid = new Xowd_wbase_qid_tbl(conn, schema_is_1); + this.tbl__wbase_qid = new Xowd_wbase_qid_tbl(conn, schema_is_1, schema_props.Wbase__qid__src_ttl_has_spaces()); this.tbl__wbase_pid = new Xowd_wbase_pid_tbl(conn, schema_is_1); this.tbl__search_word = new Xowd_search_word_tbl(conn, schema_is_1, schema_props.Search__word__page_count_exists()); this.tbl__search_link = new Xowd_search_link_tbl(conn, schema_is_1); @@ -84,9 +84,11 @@ public class Xowd_db_file { Db_conn conn = Db_conn_bldr.I.Get(url); if (conn == null) { Xoa_app_.Usr_dlg().Warn_many("", "", "wiki.db:missing db; tid=~{0} url=~{1}", Xowd_db_file_.To_key(tid), url.Raw()); - conn = Db_conn_.Empty; + conn = Db_conn_.Noop; } - Db_cfg_tbl cfg_tbl = new Db_cfg_tbl(conn, "xowa_cfg"); - return new Xowd_db_file(cfg_tbl, Xob_info_session.Load(cfg_tbl), Xob_info_file.Load(cfg_tbl), props, Xowd_db_file_schema_props.load_(cfg_tbl), id, tid, url, ns_ids, part_id, guid, conn, Db_cmd_mode.Tid_ignore); + Db_cfg_tbl cfg_tbl = new Db_cfg_tbl(conn, "xowa_cfg"); // NOTE: this loads the cfg tbl for the current db, not the core db + Xob_info_session info_session = Xob_info_session.Load(cfg_tbl); + Xob_info_file info_file = Xob_info_file.Load(cfg_tbl); + return new Xowd_db_file(cfg_tbl, info_session, info_file, props, Xowd_db_file_schema_props.load_(cfg_tbl, tid, info_session.Version()), id, tid, url, ns_ids, part_id, guid, conn, Db_cmd_mode.Tid_ignore); } } diff --git a/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file_schema_props.java b/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file_schema_props.java index 56e8f2b74..e497dd84a 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file_schema_props.java +++ b/400_xowa/src/gplx/xowa/wikis/data/Xowd_db_file_schema_props.java @@ -16,16 +16,19 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wikis.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; -import gplx.dbs.cfgs.*; +import gplx.dbs.cfgs.*; import gplx.xowa.bldrs.infos.*; public class Xowd_db_file_schema_props { - Xowd_db_file_schema_props(boolean search__word__page_count_exists) { + Xowd_db_file_schema_props(boolean search__word__page_count_exists, boolean wbase__qid__src_ttl_has_spaces) { this.search__word__page_count_exists = search__word__page_count_exists; + this.wbase__qid__src_ttl_has_spaces = wbase__qid__src_ttl_has_spaces; } public boolean Search__word__page_count_exists() {return search__word__page_count_exists;} private final boolean search__word__page_count_exists; - public static Xowd_db_file_schema_props make_() {return new Xowd_db_file_schema_props(Bool_.Y);} - public static Xowd_db_file_schema_props load_(Db_cfg_tbl tbl) { + public boolean Wbase__qid__src_ttl_has_spaces() {return wbase__qid__src_ttl_has_spaces;} private final boolean wbase__qid__src_ttl_has_spaces; + public static Xowd_db_file_schema_props make_() {return new Xowd_db_file_schema_props(Bool_.Y, Bool_.N);} + public static Xowd_db_file_schema_props load_(Db_cfg_tbl tbl, int tid, String version) { boolean search__word__page_count_exists = tbl.Select_yn_or(Grp, Key__col_search_word_page_count, Bool_.N); - return new Xowd_db_file_schema_props(search__word__page_count_exists); + boolean wbase__qid__src_ttl_has_spaces = String_.In(version, "2.4.2.1", "2.4.3.1", "2.4.3.2"); + return new Xowd_db_file_schema_props(search__word__page_count_exists, wbase__qid__src_ttl_has_spaces); } public static final String Grp = Xow_cfg_consts.Grp__wiki_schema; public static final String diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java index 56e81736d..0973067cc 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java @@ -52,7 +52,7 @@ public class Xowd_search_word_tbl implements RlsAble { } public Xowd_search_word_row[] Select_in(Cancelable cxl, byte[] word) { if (stmt_select_in == null) { - Db_qry__select_cmd qry = Db_qry_.select_().From_(tbl_name).Where_(Db_crt_.like_(fld_text, "")); + Db_qry__select_cmd qry = Db_qry_.select_().From_(tbl_name).OrderBy_(fld_page_count, Bool_.N).Where_(Db_crt_.like_(fld_text, "")); // order by highest page count to look at most common words stmt_select_in = conn.Stmt_new(qry); } ListAdp list = ListAdp_.new_(); @@ -64,7 +64,7 @@ public class Xowd_search_word_tbl implements RlsAble { if (cxl.Canceled()) break; } Xowd_search_word_row word_row = new_row(rdr); - if (++row_count % 100 == 0) + if (++row_count % 10 == 0) Xoa_app_.Usr_dlg().Prog_many("", "", "search; reading pages for word: word=~{0} pages=~{1}", word_row.Text(), word_row.Page_count()); list.Add(word_row); } diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl.java index 37083a730..475ac0063 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl.java @@ -21,8 +21,9 @@ public class Xowd_wbase_qid_tbl implements RlsAble { private final String tbl_name; private final Db_meta_fld_list flds = Db_meta_fld_list.new_(); private final String fld_src_wiki, fld_src_ns, fld_src_ttl, fld_trg_ttl; private final Db_conn conn; private Db_stmt stmt_select, stmt_insert; - public Xowd_wbase_qid_tbl(Db_conn conn, boolean schema_is_1) { - this.conn = conn; + private boolean src_ttl_has_spaces; + public Xowd_wbase_qid_tbl(Db_conn conn, boolean schema_is_1, boolean src_ttl_has_spaces) { + this.conn = conn; this.src_ttl_has_spaces = src_ttl_has_spaces; String fld_prefix = ""; if (schema_is_1) {tbl_name = "wdata_qids"; fld_prefix = "wq_";} else {tbl_name = "wbase_qid";} @@ -43,8 +44,9 @@ public class Xowd_wbase_qid_tbl implements RlsAble { } public byte[] Select_qid(byte[] src_wiki, byte[] src_ns, byte[] src_ttl) { if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, flds, fld_src_wiki, fld_src_ns, fld_src_ttl); + if (src_ttl_has_spaces) src_ttl = Xoa_ttl.Replace_unders(src_ttl); // NOTE: v2.4.2.1-v2.4.3.2 stores ttl in spaces ("A B"), while xowa will use under form ("A_B"); DATE:2015-04-21 Db_rdr rdr = stmt_select.Clear() - .Crt_bry_as_str(fld_src_wiki, src_wiki).Crt_int(fld_src_ns, Bry_.Xto_int(src_ns)).Crt_bry_as_str(fld_src_ttl,src_ttl) + .Crt_bry_as_str(fld_src_wiki, src_wiki).Crt_int(fld_src_ns, Bry_.Xto_int(src_ns)).Crt_bry_as_str(fld_src_ttl, src_ttl) .Exec_select__rls_manual(); try { return rdr.Move_next() ? rdr.Read_bry_by_str(fld_trg_ttl) : null; diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl_tst.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl_tst.java new file mode 100644 index 000000000..1f7f554cc --- /dev/null +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_wbase_qid_tbl_tst.java @@ -0,0 +1,47 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.wikis.data.tbls; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*; +import org.junit.*; import gplx.dbs.*; +public class Xowd_wbase_qid_tbl_tst { + private final Xowd_wbase_qid_tbl_fxt fxt = new Xowd_wbase_qid_tbl_fxt(); + @Before public void init() {fxt.Clear();} + @Test public void Space() { + fxt.Exec_insert("enwiki", Xow_ns_.Id_main, "A B", "q1"); + fxt.Test_select("enwiki", Xow_ns_.Id_main, "A B", "q1"); + fxt.Test_select("enwiki", Xow_ns_.Id_main, "A_B", "q1"); + } +} +class Xowd_wbase_qid_tbl_fxt { + private Xowd_wbase_qid_tbl qid_tbl; + public void Clear() { + Io_mgr._.InitEngine_mem(); + Db_conn_bldr.I.Reg_default_mem(); + Db_conn conn = Db_conn_bldr.I.New(Io_url_.mem_fil_("mem/db/wbase.xowa")); + this.qid_tbl = new Xowd_wbase_qid_tbl(conn, Bool_.N, Bool_.Y); // simulate v2.4.2 with bad "spaces" + qid_tbl.Create_tbl(); + } + public void Exec_insert(String src_wiki, int src_ns, String src_ttl, String trg_ttl) { + qid_tbl.Insert_bgn(); + qid_tbl.Insert_cmd_by_batch(Bry_.new_utf8_(src_wiki), src_ns, Bry_.new_utf8_(src_ttl), Bry_.new_utf8_(trg_ttl)); + qid_tbl.Insert_end(); + } + public void Test_select(String src_wiki, int src_ns, String src_ttl, String expd) { + byte[] actl = qid_tbl.Select_qid(Bry_.new_utf8_(src_wiki), Bry_.new_ascii_(Int_.Xto_str(src_ns)), Bry_.new_utf8_(src_ttl)); + Tfds.Eq(expd, String_.new_utf8_(actl)); + } +} diff --git a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_.java b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_.java index 2a01e7aa1..2e033abad 100644 --- a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_.java +++ b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_.java @@ -16,6 +16,9 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.wikis.domains.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.domains.*; +class Xow_domain_crt_itm_ { + public static final Xow_domain_crt_itm Null = null; +} class Xow_domain_crt_itm__any_wiki implements Xow_domain_crt_itm { public boolean Matches(Xow_domain cur, Xow_domain comp) {return true;} public static final Xow_domain_crt_itm__any_wiki I = new Xow_domain_crt_itm__any_wiki(); Xow_domain_crt_itm__any_wiki() {} @@ -48,16 +51,16 @@ class Xow_domain_crt_itm__any_standard implements Xow_domain_crt_itm { } public static final Xow_domain_crt_itm__any_standard I = new Xow_domain_crt_itm__any_standard(); Xow_domain_crt_itm__any_standard() {} } -class Xow_domain_crt_itm__null implements Xow_domain_crt_itm { - public boolean Matches(Xow_domain cur, Xow_domain comp) {throw Err_.not_implemented_msg_("null criteria should not be called");} - public static final Xow_domain_crt_itm I = new Xow_domain_crt_itm__null(); Xow_domain_crt_itm__null() {} +class Xow_domain_crt_itm__none implements Xow_domain_crt_itm { + public boolean Matches(Xow_domain cur, Xow_domain comp) {return false;} + public static final Xow_domain_crt_itm__none I = new Xow_domain_crt_itm__none(); Xow_domain_crt_itm__none() {} } class Xow_domain_crt_itm__self implements Xow_domain_crt_itm { public boolean Matches(Xow_domain cur, Xow_domain comp) {return Bry_.Eq(cur.Domain_bry(), comp.Domain_bry());} public static final Xow_domain_crt_itm__self I = new Xow_domain_crt_itm__self(); Xow_domain_crt_itm__self() {} } class Xow_domain_crt_itm__same_lang implements Xow_domain_crt_itm { - public boolean Matches(Xow_domain cur, Xow_domain comp) {return cur.Lang_uid() == comp.Lang_uid();} + public boolean Matches(Xow_domain cur, Xow_domain comp) {return Bry_.Eq(cur.Lang_orig_key(), comp.Lang_orig_key());} public static final Xow_domain_crt_itm__same_lang I = new Xow_domain_crt_itm__same_lang(); Xow_domain_crt_itm__same_lang() {} } class Xow_domain_crt_itm__same_type implements Xow_domain_crt_itm { @@ -67,7 +70,7 @@ class Xow_domain_crt_itm__same_type implements Xow_domain_crt_itm { class Xow_domain_crt_itm__lang implements Xow_domain_crt_itm { private final int lang_uid; public Xow_domain_crt_itm__lang(int lang_uid) {this.lang_uid = lang_uid;} - public boolean Matches(Xow_domain cur, Xow_domain comp) {return comp.Lang_uid() == lang_uid;} + public boolean Matches(Xow_domain cur, Xow_domain comp) {return comp.Lang_orig_uid() == lang_uid;} } class Xow_domain_crt_itm__type implements Xow_domain_crt_itm { private final int wiki_tid; diff --git a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_parser.java b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_parser.java index b517d693a..279f8f3ff 100644 --- a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_parser.java +++ b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_itm_parser.java @@ -18,7 +18,15 @@ along with this program. If not, see . package gplx.xowa.wikis.domains.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.domains.*; import gplx.xowa.langs.*; class Xow_domain_crt_itm_parser { - public Xow_domain_crt_kv[] Parse_as_kv_ary_or_null(byte[] raw) { + public Xow_domain_crt_kv_itm[] Parse_as_kv_itms_or_null(byte[] raw) { + ListAdp rv = Parse_as_obj_or_null(raw, Bool_.N); + return rv == null ? null : (Xow_domain_crt_kv_itm[])rv.Xto_ary_and_clear(Xow_domain_crt_kv_itm.class); + } + public Xow_domain_crt_kv_ary[] Parse_as_kv_arys_or_null(byte[] raw) { + ListAdp rv = Parse_as_obj_or_null(raw, Bool_.Y); + return rv == null ? null : (Xow_domain_crt_kv_ary[])rv.Xto_ary_and_clear(Xow_domain_crt_kv_ary.class); + } + public ListAdp Parse_as_obj_or_null(byte[] raw, boolean is_ary) { ListAdp rv = ListAdp_.new_(); byte[][] line_ary = Bry_.Split_lines(raw); int line_len = line_ary.length; @@ -29,31 +37,45 @@ class Xow_domain_crt_itm_parser { int word_len = word_ary.length; if (word_len != 2) return null; // not A|B; exit now; Xow_domain_crt_itm key_itm = Xow_domain_crt_itm_parser.I.Parse_as_in(word_ary[0]); - if (key_itm == Xow_domain_crt_itm__null.I) return null; // invalid key; exit - Xow_domain_crt_itm val_itm = Xow_domain_crt_itm_parser.I.Parse_as_in(word_ary[1]); - if (val_itm == Xow_domain_crt_itm__null.I) return null; // invalid val; exit - rv.Add(new Xow_domain_crt_kv(key_itm, val_itm)); + if (key_itm == Xow_domain_crt_itm_.Null) return null; // invalid key; exit; + if (is_ary) { + Xow_domain_crt_itm[] ary_itm = Xow_domain_crt_itm_parser.I.Parse_as_ary(word_ary[1]); + if (ary_itm == null) return null; + rv.Add(new Xow_domain_crt_kv_ary(key_itm, ary_itm)); + } + else { + Xow_domain_crt_itm val_itm = Xow_domain_crt_itm_parser.I.Parse_as_in(word_ary[1]); + if (val_itm == Xow_domain_crt_itm_.Null) return null; // invalid val; exit; + rv.Add(new Xow_domain_crt_kv_itm(key_itm, val_itm)); + } } - return (Xow_domain_crt_kv[])rv.Xto_ary_and_clear(Xow_domain_crt_kv.class); + return rv; } public Xow_domain_crt_itm Parse_as_in(byte[] raw) { + Xow_domain_crt_itm[] in_ary = Parse_as_ary(raw); + return in_ary == null ? Xow_domain_crt_itm_.Null : new Xow_domain_crt_itm__in(in_ary); + } + public Xow_domain_crt_itm[] Parse_as_ary(byte[] raw) { byte[][] terms = Bry_.Split(raw, Byte_ascii.Comma, Bool_.Y); int len = terms.length; Xow_domain_crt_itm[] rv_ary = new Xow_domain_crt_itm[len]; - for (int i = 0; i < len; ++i) - rv_ary[i] = Parse_itm(terms[i]); - return new Xow_domain_crt_itm__in(rv_ary); + for (int i = 0; i < len; ++i) { + Xow_domain_crt_itm itm = Parse_itm(terms[i]); + if (itm == Xow_domain_crt_itm_.Null) return null; // invalid val; exit; + rv_ary[i] = itm; + } + return rv_ary; } public Xow_domain_crt_itm Parse_itm(byte[] raw) { Xow_domain_crt_itm rv = (Xow_domain_crt_itm)itm_hash.Get_by_bry(raw); if (rv != null) return rv; // singleton; EX: , , etc.. int raw_len = raw.length; if (Bry_.HasAtBgn(raw, Wild_lang)) { // EX: *.wikipedia int wiki_tid = Xow_domain_.Tid__get_int(raw, Wild_lang.length, raw_len); - return wiki_tid == Xow_domain_.Tid_int_null ? Xow_domain_crt_itm__null.I : new Xow_domain_crt_itm__type(wiki_tid); + return wiki_tid == Xow_domain_.Tid_int_null ? Xow_domain_crt_itm_.Null : new Xow_domain_crt_itm__type(wiki_tid); } else if (Bry_.HasAtEnd(raw, Wild_type)) { // EX: en.* Xol_lang_itm lang_itm = Xol_lang_itm_.Get_by_key(raw, 0, raw_len - Wild_type.length); - return lang_itm == null ? Xow_domain_crt_itm__null.I : new Xow_domain_crt_itm__lang(lang_itm.Id()); + return lang_itm == null ? Xow_domain_crt_itm_.Null : new Xow_domain_crt_itm__lang(lang_itm.Id()); } else return new Xow_domain_crt_itm__wiki(raw); // EX: en.wikipedia.org @@ -62,7 +84,7 @@ class Xow_domain_crt_itm_parser { .Add_str_obj("" , Xow_domain_crt_itm__self.I) .Add_str_obj("" , Xow_domain_crt_itm__same_type.I) .Add_str_obj("" , Xow_domain_crt_itm__same_lang.I) - .Add_str_obj("*.*" , Xow_domain_crt_itm__any_standard.I) + .Add_str_obj("" , Xow_domain_crt_itm__any_wiki.I) ; private static final byte[] Wild_lang = Bry_.new_ascii_("*."), Wild_type = Bry_.new_ascii_(".*"); public static final Xow_domain_crt_itm_parser I = new Xow_domain_crt_itm_parser(); Xow_domain_crt_itm_parser() {} diff --git a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_itm_mgr.java b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_itm_mgr.java new file mode 100644 index 000000000..94c3ea8ed --- /dev/null +++ b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_itm_mgr.java @@ -0,0 +1,67 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.wikis.domains.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.domains.*; +public class Xow_domain_crt_kv_itm_mgr { + private final ListAdp list = ListAdp_.new_(); + public void Clear() {list.Clear();} + @gplx.Internal protected void Add(Xow_domain_crt_kv_itm itm) {list.Add(itm);} + public boolean Parse_as_itms(byte[] raw) { + this.Clear(); + Xow_domain_crt_kv_itm[] ary = Xow_domain_crt_itm_parser.I.Parse_as_kv_itms_or_null(raw); + if (ary == null) return false; // invalid parse; leave current value as is and exit; + int len = ary.length; + for (int i = 0; i < len; ++i) + this.Add(ary[i]); + return true; + } + public boolean Parse_as_arys(byte[] raw) { + this.Clear(); + Xow_domain_crt_kv_ary[] ary = Xow_domain_crt_itm_parser.I.Parse_as_kv_arys_or_null(raw); + if (ary == null) return false; // invalid parse; leave current value as is and exit; + int len = ary.length; + for (int i = 0; i < len; ++i) + list.Add(ary[i]); + return true; + } + public Xow_domain_crt_itm Find_itm(Xow_domain cur, Xow_domain comp) { + int len = list.Count(); + for (int i = 0; i < len; ++i) { + Xow_domain_crt_kv_itm kv = (Xow_domain_crt_kv_itm)list.FetchAt(i); + if (kv.Key().Matches(cur, comp)) return kv.Val(); + } + return Xow_domain_crt_itm__none.I; + } + public Xow_domain_crt_itm[] Find_ary(Xow_domain cur, Xow_domain comp) { + int len = list.Count(); + for (int i = 0; i < len; ++i) { + Xow_domain_crt_kv_ary kv = (Xow_domain_crt_kv_ary)list.FetchAt(i); + if (kv.Key().Matches(cur, comp)) return kv.Val(); + } + return null; + } +} +class Xow_domain_crt_kv_itm { + public Xow_domain_crt_kv_itm(Xow_domain_crt_itm key, Xow_domain_crt_itm val) {this.key = key; this.val = val;} + public Xow_domain_crt_itm Key() {return key;} private final Xow_domain_crt_itm key; + public Xow_domain_crt_itm Val() {return val;} private final Xow_domain_crt_itm val; +} +class Xow_domain_crt_kv_ary { + public Xow_domain_crt_kv_ary(Xow_domain_crt_itm key, Xow_domain_crt_itm[] val) {this.key = key; this.val = val;} + public Xow_domain_crt_itm Key() {return key;} private final Xow_domain_crt_itm key; + public Xow_domain_crt_itm[] Val() {return val;} private final Xow_domain_crt_itm[] val; +} diff --git a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_mgr.java b/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_mgr.java deleted file mode 100644 index 15d7e4c48..000000000 --- a/400_xowa/src/gplx/xowa/wikis/domains/crts/Xow_domain_crt_kv_mgr.java +++ /dev/null @@ -1,45 +0,0 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012 gnosygnu@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ -package gplx.xowa.wikis.domains.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.domains.*; -public class Xow_domain_crt_kv_mgr { - private final ListAdp list = ListAdp_.new_(); - public void Clear() {list.Clear();} - @gplx.Internal protected void Add(Xow_domain_crt_kv itm) {list.Add(list);} - public boolean Parse(byte[] raw) { - Xow_domain_crt_kv[] ary = Xow_domain_crt_itm_parser.I.Parse_as_kv_ary_or_null(raw); - if (ary == null) return false; // invalid parse; leave current value as is and exit; - this.Clear(); - int len = ary.length; - for (int i = 0; i < len; ++i) - this.Add(ary[i]); - return true; - } - public Xow_domain_crt_itm Find(Xow_domain cur, Xow_domain comp) { - int len = list.Count(); - for (int i = 0; i < len; ++i) { - Xow_domain_crt_kv kv = (Xow_domain_crt_kv)list.FetchAt(i); - if (kv.Key().Matches(cur, comp)) return kv.Val(); - } - return Xow_domain_crt_itm__null.I; - } -} -class Xow_domain_crt_kv { - public Xow_domain_crt_kv(Xow_domain_crt_itm key, Xow_domain_crt_itm val) {this.key = key; this.val = val;} - public Xow_domain_crt_itm Key() {return key;} private final Xow_domain_crt_itm key; - public Xow_domain_crt_itm Val() {return val;} private final Xow_domain_crt_itm val; -} diff --git a/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_itm.java b/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_itm.java index 6943c5f18..3239a8c54 100644 --- a/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_itm.java +++ b/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_itm.java @@ -21,11 +21,13 @@ public class Xow_xwiki_itm implements gplx.CompareAble { public Xow_xwiki_itm(byte[] key_bry, byte[] url_fmt, int lang_id, int domain_tid, byte[] domain_bry, byte[] domain_name) { this.key_bry = key_bry; this.key_str = String_.new_utf8_(key_bry); this.url_fmt = url_fmt; this.lang_id = lang_id; + this.url_fmtr = Bry_.Len_eq_0(url_fmt) ? null : Bry_fmtr.new_(url_fmt, "0"); this.domain_tid = domain_tid; this.domain_bry = domain_bry; this.domain_name = domain_name; } public byte[] Key_bry() {return key_bry;} private final byte[] key_bry; // EX: commons public String Key_str() {return key_str;} private final String key_str; public byte[] Url_fmt() {return url_fmt;} private final byte[] url_fmt; // EX: //commons.wikimedia.org/wiki/Category:$1 + public Bry_fmtr Url_fmtr(){return url_fmtr;} private final Bry_fmtr url_fmtr; public int Lang_id() {return lang_id;} private final int lang_id; // EX: Id__unknown public int Domain_tid() {return domain_tid;} private final int domain_tid; // EX: Tid_int_commons public byte[] Domain_bry() {return domain_bry;} private final byte[] domain_bry; // EX: commons.wikimedia.org diff --git a/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_mgr.java b/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_mgr.java index e13bd2e1f..b8260842f 100644 --- a/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/xwikis/Xow_xwiki_mgr.java @@ -49,6 +49,17 @@ public class Xow_xwiki_mgr implements GfoInvkAble { public void Sort_by_key() { list.Sort(); } + public Xow_domain[] Get_by_crt(Xow_domain cur, gplx.xowa.wikis.domains.crts.Xow_domain_crt_itm crt) { + ListAdp rv = ListAdp_.new_(); + int len = this.Len(); + for (int i = 0; i < len; ++i) { + Xow_xwiki_itm wiki = this.Get_at(i); + if (!wiki.Offline()) continue; + Xow_domain domain_itm = Xow_domain_.parse(wiki.Domain_bry()); + if (crt.Matches(cur, domain_itm)) rv.Add(domain_itm); + } + return (Xow_domain[])rv.Xto_ary_and_clear(Xow_domain.class); + } public void Add_bulk(byte[] raw) { byte[][] rows = Bry_.Split(raw, Byte_ascii.NewLine); int rows_len = rows.length; diff --git a/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_itm.java b/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_itm.java index d89d28d67..a0fa2d86d 100644 --- a/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_itm.java +++ b/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_itm.java @@ -142,7 +142,7 @@ class Dpl_itm { ( Known_invalid_keys.Get_by_mid(src, fld_bgn, fld_end) != null || Bry_.HasAtBgn(key_bry, Html_tag_.Comm_bgn) // ignore comment-like keys; EX: will have key of "
    ~{itm_last}