From a38c0e834ee2e80220e3f83853881b9e85c36ac6 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Thu, 17 Nov 2016 10:02:54 -0500 Subject: [PATCH] Page_sync: Implement 'Pages to sync' filter --- .../pages/syncs/core/Xosync_read_mgr.java | 2 +- .../xowa/addons/bldrs/Xoapi_sync_api.java | 14 +++- .../xowa/addons/bldrs/Xopg_match_mgr.java | 76 ++++++++++++++++++- .../addons/bldrs/Xopg_match_mgr__tst.java | 70 +++++++++++++++++ 4 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr__tst.java diff --git a/400_xowa/src/gplx/xowa/addons/wikis/pages/syncs/core/Xosync_read_mgr.java b/400_xowa/src/gplx/xowa/addons/wikis/pages/syncs/core/Xosync_read_mgr.java index 2023b9a65..64953e928 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/pages/syncs/core/Xosync_read_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/pages/syncs/core/Xosync_read_mgr.java @@ -31,7 +31,7 @@ public class Xosync_read_mgr { Xoapi_sync_api sync_api = wiki.App().Api_root().Addon().Bldr().Sync(); if (!sync_api.Auto_enabled()) return; - if (!sync_api.Auto_page_matcher().Match(page_ttl.Full_db())) return; + if (!sync_api.Auto_page_matcher().Match(wiki, page_ttl.Full_db())) return; wiki.Data__core_mgr().Db__core().Tbl__page().Select_by_ttl(tmp_dbpg, page_ttl.Ns(), page_ttl.Page_db()); diff --git a/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xoapi_sync_api.java b/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xoapi_sync_api.java index e03846eb9..64327fdc3 100644 --- a/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xoapi_sync_api.java +++ b/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xoapi_sync_api.java @@ -17,11 +17,19 @@ along with this program. If not, see . */ package gplx.xowa.apps.apis.xowa.addons.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.apis.*; import gplx.xowa.apps.apis.xowa.*; import gplx.xowa.apps.apis.xowa.addons.*; public class Xoapi_sync_api implements Gfo_invk { + private final Xopg_match_mgr auto_page_matcher = new Xopg_match_mgr(); + public Xoapi_sync_api() { + this.Auto_scope_("*:Main_Page"); + } public boolean Manual_enabled() {return manual_enabled;} private boolean manual_enabled = false; public boolean Auto_enabled() {return auto_enabled;} private boolean auto_enabled = false; public int Auto_interval() {return auto_interval;} private int auto_interval = 60 * 24; // in minutes - public String Auto_scope() {return auto_scope;} private String auto_scope = "Main_Page"; - public Xopg_match_mgr Auto_page_matcher() {return auto_page_matcher;} private final Xopg_match_mgr auto_page_matcher = new Xopg_match_mgr(); + public String Auto_scope() {return auto_scope;} private String auto_scope; + private void Auto_scope_(String v) { + this.auto_scope = v; + auto_page_matcher.Set(v); + } + public Xopg_match_mgr Auto_page_matcher() {return auto_page_matcher;} public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk__manual_enabled)) return Yn.To_str(manual_enabled); else if (ctx.Match(k, Invk__manual_enabled_)) manual_enabled = m.ReadBool("v"); @@ -30,7 +38,7 @@ public class Xoapi_sync_api implements Gfo_invk { else if (ctx.Match(k, Invk__auto_interval)) return Int_.To_str(auto_interval); else if (ctx.Match(k, Invk__auto_interval_)) auto_interval = m.ReadInt("v"); else if (ctx.Match(k, Invk__auto_scope)) return auto_scope; - else if (ctx.Match(k, Invk__auto_scope_)) auto_scope = m.ReadStr("v"); + else if (ctx.Match(k, Invk__auto_scope_)) Auto_scope_(m.ReadStr("v")); else return Gfo_invk_.Rv_unhandled; return this; } diff --git a/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr.java b/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr.java index c658e8c75..016411c34 100644 --- a/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr.java +++ b/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr.java @@ -16,8 +16,80 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.apps.apis.xowa.addons.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.apis.*; import gplx.xowa.apps.apis.xowa.*; import gplx.xowa.apps.apis.xowa.addons.*; +import gplx.xowa.apps.urls.*; public class Xopg_match_mgr { - public boolean Match(byte[] page_ttl) { - return true; + private String scope_raw; + private Ordered_hash wikis; + private boolean wildcard_exists; + private Xopg_match_wiki wildcard_wiki; + public void Set(String v) { + this.scope_raw = v; + this.wikis = null; + this.wildcard_exists = false; + this.wildcard_wiki = null; + } + public boolean Match(Xow_wiki wiki, byte[] page_ttl) { + if (wikis == null) Init(wiki.App()); + + if (wildcard_exists) return true; + if (wildcard_wiki != null) { + if (wildcard_wiki.Has(page_ttl)) + return true; + } + Xopg_match_wiki match_wiki = (Xopg_match_wiki)wikis.Get_by(wiki.Domain_bry()); + if (match_wiki == null) return false; + return match_wiki.Has(page_ttl); + } + private void Init(Xoa_app app) { + this.wikis = Ordered_hash_.New_bry(); + String[] lines = String_.SplitLines_nl(scope_raw); + Xow_url_parser url_parser = app.User().Wikii().Utl__url_parser(); + for (String line : lines) { + if (String_.Eq(line, "*")) { + wildcard_exists = true; + } + else { + byte[] wiki_domain = null, page_db = null; + boolean cur_is_wildcard_wiki = false; + if (String_.Has_at_bgn(line, "*:")) { + wiki_domain = Byte_ascii.Star_bry; + page_db = Bry_.Mid(Bry_.new_u8(line), 2); + cur_is_wildcard_wiki = true; + } + else { + Xoa_url url = url_parser.Parse_by_urlbar_or_null(line); + wiki_domain = url.Wiki_bry(); + page_db = url.Page_bry(); + } + Xopg_match_wiki match_wiki = (Xopg_match_wiki)wikis.Get_by(wiki_domain); + if (match_wiki == null) { + match_wiki = new Xopg_match_wiki(wiki_domain); + wikis.Add(wiki_domain, match_wiki); + if (cur_is_wildcard_wiki) { + wildcard_wiki = match_wiki; + } + } + match_wiki.Add(page_db); + } + } + } +} +class Xopg_match_wiki { + private final Ordered_hash hash = Ordered_hash_.New_bry(); + private boolean wildcard_exists; + public Xopg_match_wiki(byte[] domain_bry) { + this.domain_bry = domain_bry; + } + public byte[] Domain_bry() {return domain_bry;} private final byte[] domain_bry; + public boolean Has(byte[] page_db) { + return wildcard_exists ? true : hash.Has(page_db); + } + public void Add(byte[] page_db) { + if (Bry_.Eq(page_db, Byte_ascii.Star_bry)) { + wildcard_exists = true; + } + else { + hash.Add_if_dupe_use_1st(page_db, page_db); + } } } diff --git a/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr__tst.java b/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr__tst.java new file mode 100644 index 000000000..aa36f9a18 --- /dev/null +++ b/400_xowa/src/gplx/xowa/apps/apis/xowa/addons/bldrs/Xopg_match_mgr__tst.java @@ -0,0 +1,70 @@ +/* +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.apis.xowa.addons.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.apis.*; import gplx.xowa.apps.apis.xowa.*; import gplx.xowa.apps.apis.xowa.addons.*; +import org.junit.*; import gplx.core.tests.*; +public class Xopg_match_mgr__tst { + private final Xopg_match_mgr__fxt fxt = new Xopg_match_mgr__fxt(); + @Before public void init() {fxt.Clear();} + @Test public void Specific() { + fxt.Init__set("en.w:A"); + fxt.Test__match_y("A"); + fxt.Test__match_n("AB"); + } + @Test public void Other_wiki() { + fxt.Init__set("fr.w:A"); + fxt.Test__match_n("A"); // note that test defaults to "en.w" as primary wiki + } + @Test public void Wildcard__app() { + fxt.Init__set("*"); + fxt.Test__match_y("A", "B"); + } + @Test public void Wildcard__page() { + fxt.Init__set("en.w:*"); + fxt.Test__match_y("A", "B"); + } + @Test public void Wildcard__page__other() { + fxt.Init__set("fr.w:*"); + fxt.Test__match_n("A", "B"); + } + @Test public void Wildcard__wiki() { + fxt.Init__set("*:A"); + fxt.Test__match_y("A"); + fxt.Test__match_n("B"); + } +} +class Xopg_match_mgr__fxt { + private final Xopg_match_mgr match_mgr = new Xopg_match_mgr(); + private Xowe_wiki wiki; + public void Clear() { + Xoae_app app = Xoa_app_fxt.Make__app__edit(); + this.wiki = Xoa_app_fxt.Make__wiki__edit(app); + app.User().Wikii().Xwiki_mgr().Add_by_atrs(wiki.Domain_bry(), wiki.Domain_bry()); + } + public void Init__set(String url) { + match_mgr.Set(url); + } + public void Test__match_y(String... urls) {Test__match(Bool_.Y, urls);} + public void Test__match_n(String... urls) {Test__match(Bool_.N, urls);} + private void Test__match(boolean expd, String... urls) { + for (int i = 0; i < urls.length; i++) { + String url = urls[i]; + boolean actl = match_mgr.Match(wiki, Bry_.new_u8(url)); + Gftest.Eq__bool(expd, actl, "match failed", "expd", expd, "url", url); + } + } +}