mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
'v3.8.5.1'
This commit is contained in:
@@ -16,6 +16,8 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.wbases; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.langs.jsons.*;
|
||||
import gplx.xowa.wikis.pages.*;
|
||||
public class Wbase_doc_mgr {
|
||||
private final Xoae_app app;
|
||||
private final Wdata_wiki_mgr wbase_mgr;
|
||||
@@ -42,23 +44,58 @@ public class Wbase_doc_mgr {
|
||||
return qid_bry == null ? null : this.Get_by_bry_or_null(qid_bry);
|
||||
}
|
||||
public Wdata_doc Get_by_xid_or_null(byte[] xid) {return Get_by_bry_or_null(Prepend_property_if_needed(xid));}// scribunto passes either p1 or q1; convert p1 to "Property:P1"
|
||||
public Wdata_doc Get_by_bry_or_null(byte[] full_db) { // must be correct format; EX:"Q2" or "Property:P1"
|
||||
Wdata_doc rv = hash.Get_or_null(full_db);
|
||||
public Wdata_doc Get_by_bry_or_null(byte[] ttl_bry) {// must be correct format; EX:"Q2" or "Property:P1"
|
||||
Wdata_doc rv = hash.Get_or_null(ttl_bry);
|
||||
if (rv == null) {
|
||||
byte[] page_src = Load_or_null(full_db); if (page_src == null) return null; // page not found
|
||||
synchronized (hash) { // LOCK:app-level; both hash and jdoc_parser
|
||||
rv = new Wdata_doc(full_db, wbase_mgr, wbase_mgr.Jdoc_parser().Parse(page_src));
|
||||
rv = Load_wdoc_or_null(ttl_bry); if (rv == null) return null; // page not found
|
||||
synchronized (hash) { // LOCK:app-level; hash;
|
||||
Add(ttl_bry, rv);// NOTE: use ttl_bry, not rv.Qid; allows subsequent lookups to skip this redirect cycle
|
||||
}
|
||||
Add(full_db, rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
private byte[] Load_or_null(byte[] full_db) {
|
||||
public Wdata_doc Load_wdoc_or_null(byte[] src_ttl_bry) {
|
||||
if (!enabled) return null;
|
||||
Xoa_ttl page_ttl = Xoa_ttl.Parse(wbase_mgr.Wdata_wiki(), full_db); if (page_ttl == null) {app.Usr_dlg().Warn_many("", "", "invalid qid for ttl: qid=~{0}", full_db); return null;}
|
||||
Xoae_page page_itm = wbase_mgr.Wdata_wiki().Data_mgr().Load_page_by_ttl(page_ttl);
|
||||
return page_itm.Db().Page().Exists() ? page_itm.Db().Text().Text_bry() : null;
|
||||
byte[] cur_ttl_bry = src_ttl_bry;
|
||||
int load_count = -1;
|
||||
while (load_count < 2) { // limit to 2 tries (i.e.: 1 redirect)
|
||||
// parse ttl
|
||||
Xoa_ttl cur_ttl = wbase_mgr.Wdata_wiki().Ttl_parse(cur_ttl_bry);
|
||||
if (cur_ttl == null) {
|
||||
app.Usr_dlg().Warn_many("", "", "invalid wbase ttl: orig=~{0} cur=~{1}", src_ttl_bry, cur_ttl_bry);
|
||||
return null;
|
||||
}
|
||||
|
||||
// get page
|
||||
Xoae_page page = wbase_mgr.Wdata_wiki().Data_mgr().Load_page_by_ttl(cur_ttl);
|
||||
if (!page.Db().Page().Exists()) return null;
|
||||
|
||||
// parse jdoc
|
||||
byte[] jdoc_bry = page.Db().Text().Text_bry();
|
||||
Json_doc jdoc = null;
|
||||
synchronized (hash) { // LOCK:app-level; jdoc_parser
|
||||
jdoc = wbase_mgr.Jdoc_parser().Parse(jdoc_bry);
|
||||
}
|
||||
if (jdoc == null) {
|
||||
app.Usr_dlg().Warn_many("", "", "invalid jdoc for ttl: orig=~{0} cur=~{1}", src_ttl_bry, cur_ttl_bry);
|
||||
return null;
|
||||
}
|
||||
|
||||
// check for redirect; EX: {"entity":"Q22350516","redirect":"Q21006972"}; PAGE:fr.w:Tour_du_Táchira_2016; DATE:2016-08-13
|
||||
Json_nde jdoc_root = jdoc.Root_nde();
|
||||
byte[] redirect_ttl = jdoc_root.Get_as_bry_or(Bry__redirect, null);
|
||||
if (redirect_ttl != null) {
|
||||
cur_ttl_bry = redirect_ttl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// is json doc, and not a redirect; return
|
||||
return new Wdata_doc(cur_ttl_bry, wbase_mgr, jdoc);
|
||||
}
|
||||
app.Usr_dlg().Warn_many("", "", "too many redirects for ttl: orig=~{0} cur=~{1}", src_ttl_bry, cur_ttl_bry);
|
||||
return null;
|
||||
}
|
||||
private static final byte[] Bry__redirect = Bry_.new_a7("redirect");
|
||||
|
||||
private static byte[] Prepend_property_if_needed(byte[] bry) {
|
||||
int len = bry == null ? 0 : bry.length;
|
||||
|
||||
33
400_xowa/src/gplx/xowa/xtns/wbases/Wbase_doc_mgr__tst.java
Normal file
33
400_xowa/src/gplx/xowa/xtns/wbases/Wbase_doc_mgr__tst.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.wbases; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
import gplx.langs.jsons.*; import gplx.xowa.wikis.pages.*;
|
||||
public class Wbase_doc_mgr__tst {
|
||||
@Before public void init() {fxt.Init();} private final Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt();
|
||||
@Test public void Redirect() {
|
||||
// create 2 pages; Q1 redirects to Q2
|
||||
Wdata_wiki_mgr wbase_mgr = fxt.App().Wiki_mgr().Wdata_mgr();
|
||||
fxt.Parser_fxt().Init_page_create(wbase_mgr.Wdata_wiki(), "Q1", Json_doc.Make_str_by_apos("{'entity':'q1','redirect':'Q2'}"));
|
||||
fxt.Parser_fxt().Init_page_create(wbase_mgr.Wdata_wiki(), "Q2", Json_doc.Make_str_by_apos("{'entity':'q2','links':{'enwiki':'q2_en','dewiki':'q2_de'}}"));
|
||||
|
||||
// fetch Q1; assert Q2 comes back
|
||||
Wdata_doc actl = wbase_mgr.Doc_mgr.Load_wdoc_or_null(Bry_.new_u8("Q1"));
|
||||
Gftest.Eq__str("Q2", String_.new_u8(actl.Qid()));
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,9 @@ public class Wdata_wiki_mgr_fxt {
|
||||
parser_fxt.Reset();
|
||||
}
|
||||
return this;
|
||||
} private Xoae_app app; private Xowe_wiki wiki; private Wdata_wiki_mgr wdata_mgr; private Wdata_doc_bldr wdoc_bldr; private Xop_fxt parser_fxt;
|
||||
} private Xoae_app app; private Xowe_wiki wiki; private Wdata_wiki_mgr wdata_mgr; private Wdata_doc_bldr wdoc_bldr;
|
||||
public Xoae_app App() {return app;}
|
||||
public Xop_fxt Parser_fxt() {return parser_fxt;} private Xop_fxt parser_fxt;
|
||||
public void Init_lang_fallbacks(String... fallbacks) {
|
||||
wiki.Lang().Fallback_bry_(Bry_.new_a7(String_.Concat_with_str(",", fallbacks)));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Wdata_pf_property extends Pf_func_base {
|
||||
Xop_log_property_wkr property_wkr = ctx.Xtn__wikidata__property_wkr();
|
||||
long log_time_bgn = 0;
|
||||
if (property_wkr != null) {
|
||||
log_time_bgn = Env_.TickCount();
|
||||
log_time_bgn = System_.Ticks();
|
||||
if (!property_wkr.Eval_bgn(ctx.Page(), pid_ttl)) return;
|
||||
}
|
||||
Xoae_app app = ctx.App();
|
||||
|
||||
@@ -38,9 +38,12 @@ public class Wdata_pf_property_data {
|
||||
int key_bgn = nde_key.Src_bgn(), key_end = nde_key.Src_end();
|
||||
if (key_bgn == key_end && key_bgn == -1) continue; // null arg; ignore, else will throw warning below; EX: {{#property:p1|}}; DATE:2013-11-15
|
||||
byte key_tid = atrs_hash.Get_as_byte_or(src, key_bgn, key_end, Byte_.Max_value_127);
|
||||
if (key_tid == Byte_.Max_value_127) {
|
||||
ctx.App().Usr_dlg().Warn_many("", "", "unknown key for property: ~{0} ~{1}", String_.new_u8(ctx.Page().Ttl().Full_txt_w_ttl_case()), String_.new_u8(src, self.Src_bgn(), self.Src_end()));
|
||||
continue;
|
||||
switch (key_tid) {
|
||||
case Byte_.Max_value_127:
|
||||
ctx.App().Usr_dlg().Warn_many("", "", "unknown key for property: ~{0} ~{1}", String_.new_u8(ctx.Page().Ttl().Full_txt_w_ttl_case()), String_.new_u8(src, self.Src_bgn(), self.Src_end()));
|
||||
continue;
|
||||
case Tid__id: // same as "not-found", but don't warn;
|
||||
continue;
|
||||
}
|
||||
|
||||
// get val
|
||||
@@ -56,10 +59,11 @@ public class Wdata_pf_property_data {
|
||||
tmp_bfr.Mkr_rls();
|
||||
return new Wdata_pf_property_data(of, q, from);
|
||||
}
|
||||
private static final byte Tid__of = 0, Tid__q = 1, Tid__from = 2;
|
||||
private static final byte Tid__of = 0, Tid__q = 1, Tid__from = 2, Tid__id = 3;
|
||||
private static final Hash_adp_bry atrs_hash = Hash_adp_bry.ci_a7()
|
||||
.Add_str_byte("of" , Tid__of)
|
||||
.Add_str_byte("q" , Tid__q)
|
||||
.Add_str_byte("from" , Tid__from) // "from" is alias as "q" except it seems to handle properties; EX: {{#property:p1|from=Q2}} == {{#property:p1|q=Q2}}; EX: {{#property:p1|from=p2}}
|
||||
.Add_str_byte("id" , Tid__id) // "id" has no effect, but appears in articles; ignore and don't warn; EX:{{#property:P277|id=Q1322933}} PAGE:en.w:Symfony; DATE:2016-08-13
|
||||
;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user