v3.3.4 v3.9.4.1
gnosygnu 8 years ago
parent 35d78f6106
commit e3b393650d

@ -603,9 +603,10 @@ public class Bry_ {
}
}
public static byte To_int_as_byte(byte[] ary, int bgn, int end, byte or) {return (byte)To_int_or(ary, bgn, end, or);}
public static int To_int(byte[] ary) {
int rv = To_int_or(ary, 0, ary.length, Int_.Min_value, Bool_.Y, null);
if (rv == Int_.Min_value) throw Err_.new_wo_type("could not parse to int", "val", String_.new_u8(ary));
public static int To_int(byte[] ary) {return To_int_or_fail(ary, 0, ary.length);}
public static int To_int_or_fail(byte[] ary, int bgn, int end) {
int rv = To_int_or(ary, bgn, end, Int_.Min_value, Bool_.Y, null);
if (rv == Int_.Min_value) throw Err_.new_wo_type("could not parse to int", "val", String_.new_u8(ary, bgn, end));
return rv;
}
public static int To_int_or_neg1(byte[] ary) {return To_int_or(ary, 0 , ary.length, -1, Bool_.Y, null);}

@ -20,6 +20,7 @@ public class Err_ {
private static String Type__gplx = "gplx"; @gplx.Internal protected static String Trace_null = null;
public static void Noop(Exception e) {}
public static Err as_(Object obj) {return obj instanceof Err ? (Err)obj : null;}
public static Err New(String msg, Object... args) {return new Err(Bool_.Y, Trace_null, "", String_.Format(msg, args));}
public static Err new_(String type, String msg, Object... args) {return new Err(Bool_.Y, Trace_null, type, msg, args);}
public static Err new_wo_type(String msg, Object... args) {return new Err(Bool_.Y, Trace_null, Type__gplx, msg, args);}
public static Err new_exc(Exception e, String type, String msg, Object... args) {
@ -71,5 +72,5 @@ public class Err_ {
public static String Message_gplx_full(Exception e) {return cast_or_make(e).To_str__full();}
public static String Message_gplx_log(Exception e) {return cast_or_make(e).To_str__log();}
public static Err cast_or_make(Throwable e) {return Type_adp_.Eq_typeSafe(e, Err.class) ? (Err)e : new Err(Bool_.N, Err_.Trace_lang(e), Type_adp_.NameOf_obj(e), Err_.Message_lang(e));}
public static final String Type__op_canceled = "gplx.op_canceled";
public static final String Type__op_canceled = "gplx.op_canceled";
}

@ -173,6 +173,10 @@ public class Bry_rdr {
Object rv = trie.Match_at(trv, src, pos, src_end); if (rv == null) err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16)));
return rv;
}
public byte Chk_or(Btrie_rv trv, Btrie_slim_mgr trie, byte or) {
Object rv_obj = trie.Match_at(trv, src, pos, src_end);
return rv_obj == null ? or : ((gplx.core.primitives.Byte_obj_val)rv_obj).Val();
}
public byte Chk_or(Btrie_slim_mgr trie, byte or) {return Chk_or(trie, pos, src_end, or);}
public byte Chk(Btrie_slim_mgr trie, int itm_bgn, int itm_end) {
byte rv = Chk_or(trie, itm_bgn, itm_end, Byte_.Max_value_127);

@ -87,6 +87,10 @@ public class Btrie_slim_mgr implements Btrie_mgr {
Object rv_obj = Match_at(trv, src, bgn, end);
return rv_obj == null ? or : ((Byte_obj_val)rv_obj).Val();
}
public byte Match_byte_or(Btrie_rv trv, byte[] src, byte or) {
Object rv_obj = Match_at(trv, src, 0, src.length);
return rv_obj == null ? or : ((Byte_obj_val)rv_obj).Val();
}
public Btrie_slim_mgr Add_bry_tid(byte[] bry, byte tid) {return (Btrie_slim_mgr)Add_obj(bry, Byte_obj_val.new_(tid));}
public Btrie_slim_mgr Add_bry_int(byte[] key, int val) {return (Btrie_slim_mgr)Add_obj(key, new Int_obj_val(val));}
public Btrie_slim_mgr Add_str_byte(String key, byte val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), Byte_obj_val.new_(val));}

@ -37,7 +37,7 @@ public class Op_sys {
public boolean Tid_is_drd() {return tid == Tid_drd;}
public String To_str() {return os_name + Bitness_str();}
public static final byte Tid_nil = 0, Tid_wnt = 1, Tid_lnx = 2, Tid_osx = 3, Tid_drd = 4;
public static final byte Tid_nil = 0, Tid_wnt = 1, Tid_lnx = 2, Tid_osx = 3, Tid_drd = 4, Tid_arm = 5;
public static final byte Sub_tid_unknown = 0, Sub_tid_win_xp = 1, Sub_tid_win_7 = 2, Sub_tid_win_8 = 3;
public static final byte Bitness_32 = 1, Bitness_64 = 2;
public static final char Nl_char_lnx = '\n';
@ -77,6 +77,8 @@ public class Op_sys {
else throw Err_.new_wo_type("unknown bitness; expecting 32 or 64; System.getProperty(\"bit.level\")", "val", bitness_str);
os_name = System.getProperty("os.name").toLowerCase();
String os_arch = System.getProperty("os.arch").toLowerCase();
if (String_.Eq(os_arch, "arm")) return new_unx_flavor_(Tid_arm, os_name, bitness_byte); // EX:arm; DATE:2016-09-23;"arm" and "32"
if (String_.Has_at_bgn(os_name, "win")) {
String os_version = System.getProperty("os.version").toLowerCase();// "Windows 7".equals(osName) && "6.1".equals(osVersion);
byte sub_tid = Sub_tid_unknown;
@ -86,7 +88,7 @@ public class Op_sys {
return new_wnt_(bitness_byte, sub_tid);
}
else if (String_.Eq(os_name, "linux")) return new_unx_flavor_(Tid_lnx, os_name, bitness_byte);
else if (String_.Has_at_bgn(os_name, "mac")) return new_unx_flavor_(Tid_osx, os_name, bitness_byte); // EX:Mac OS X
else if (String_.Has_at_bgn(os_name, "mac")) return new_unx_flavor_(Tid_osx, os_name, bitness_byte); // EX:Mac OS X
else throw Err_.new_wo_type("unknown os_name; expecting windows, linux, mac; System.getProperty(\"os.name\")", "val", os_name);
} catch (Exception exc) {Drd.os_name = os_name; return Drd;}
}

@ -19,6 +19,7 @@ package gplx.core.tests; import gplx.*; import gplx.core.*;
import gplx.core.brys.*;
public class Gftest {
private static final Bry_bfr bfr = Bry_bfr_.New();
public static void Eq__ary(boolean[] expd, boolean[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bool, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary(int[] expd, int[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__int, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary(long[] expd, long[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__long, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary__lines(String expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__ary__lines(expd, String_.new_u8(actl), msg_fmt, msg_args);}
@ -150,10 +151,11 @@ public class Gftest {
private static void Write__itm(Bry_bfr bfr, int type_id, Object ary, int len, int idx) {
if (idx < len) {
switch (type_id) {
case Type_adp_.Tid__bry: bfr.Add((byte[])Array_.Get_at(ary, idx)); break;
case Type_adp_.Tid__long: bfr.Add_long_variable(Long_.cast(Array_.Get_at(ary, idx))); break;
case Type_adp_.Tid__int: bfr.Add_int_variable(Int_.cast(Array_.Get_at(ary, idx))); break;
default: throw Err_.new_unhandled_default(type_id);
case Type_adp_.Tid__bool: bfr.Add_yn(Bool_.cast(Array_.Get_at(ary, idx))); break;
case Type_adp_.Tid__bry: bfr.Add((byte[])Array_.Get_at(ary, idx)); break;
case Type_adp_.Tid__long: bfr.Add_long_variable(Long_.cast(Array_.Get_at(ary, idx))); break;
case Type_adp_.Tid__int: bfr.Add_int_variable(Int_.cast(Array_.Get_at(ary, idx))); break;
default: throw Err_.new_unhandled_default(type_id);
}
}
else
@ -173,6 +175,7 @@ public class Gftest {
else if (expd_obj == null || actl_obj == null) eq = false;
else {
switch (tid) {
case Type_adp_.Tid__bool: eq = Bool_.cast(expd_obj) == Bool_.cast(actl_obj); break;
case Type_adp_.Tid__bry: eq = Bry_.Eq((byte[])expd_obj, (byte[])actl_obj); break;
case Type_adp_.Tid__long: eq = Long_.cast(expd_obj) == Long_.cast(actl_obj); break;
case Type_adp_.Tid__int: eq = Int_.cast(expd_obj) == Int_.cast(actl_obj); break;

@ -68,6 +68,7 @@ public class Db_conn {
}
public String Meta_fld_append_if_missing(String tbl_name, Dbmeta_fld_list flds, Dbmeta_fld_itm fld) {
String fld_name = fld.Name();
// if fld doesn't exist, add it; NOTE: need to check if tbl exists first else meta_fld not available
if ( this.Meta_tbl_exists(tbl_name)
&& !this.Meta_fld_exists(tbl_name, fld_name)) {
try {this.Meta_fld_append(tbl_name, fld);}
@ -76,8 +77,11 @@ public class Db_conn {
fld_name = Dbmeta_fld_itm.Key_null;
}
}
else
fld_name = flds.Add(fld);
// if fld does exist, or tbl doesn't exist, just add fld to collection
else {
if (!flds.Has(fld.Name())) // NOTE: need to check if it already exists; DATE:2016-09-22
fld_name = flds.Add(fld);
}
return fld_name;
}
public Dbmeta_tbl_mgr Meta_mgr() {return engine.Meta_mgr();}

@ -45,5 +45,10 @@ public class Db_conn_bldr {
else throw Err_.new_("dbs", "db does not exist", "url", url.Raw());
}
}
public Db_conn Get_or_fail(Io_url url) {
Db_conn rv = Get(url);
if (rv == Db_conn_.Noop) throw Err_.new_wo_type("connection is null; file does not exist: file={0}", "file", url.Raw());
return rv;
}
public static final Db_conn_bldr Instance = new Db_conn_bldr(); Db_conn_bldr() {}
}

@ -1,84 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.lists; import gplx.*; import gplx.core.*;
public class Binary_search_ {
public static int Search(CompareAble[] ary, int ary_len, CompareAble val) {
if (ary_len == 1) return 0;
int interval = ary_len / 2;
int pos = interval - List_adp_.Base1;
int pos_last = ary_len - 1;
int pos_prv = -1;
int loop_count = 0;
while (loop_count++ < 32) { // 32 bit integer
CompareAble lo = ary[pos];
CompareAble hi = pos + 1 == ary_len ? null : ary[pos + 1];
int adj = 0;
int lo_comp = val.compareTo(lo);
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
adj = -1;
else {
if (hi == null) return pos; // hi is null when at last slot in ary
int hi_comp = val.compareTo(hi);
if (hi_comp == CompareAble_.More) // val is > hi; search slots above
adj = 1;
else
return pos; // val is > lo and < hi; return slot
}
interval /= 2;
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
pos += (interval * adj);
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
if (pos < 0) pos = 0;
else if (pos > pos_last) pos = pos_last;
pos_prv = pos;
}
return Int_.Min_value; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
}
public static int Search(List_adp__getable list, int list_len, CompareAble val) {
if (list_len == 1) return 0;
int interval = list_len / 2;
int pos = interval - List_adp_.Base1;
int pos_last = list_len - 1;
int pos_prv = -1;
int loop_count = 0;
while (loop_count++ < 32) { // 32 bit integer
CompareAble lo = (CompareAble)list.Get_at(pos);
CompareAble hi = pos + 1 == list_len ? null : (CompareAble)list.Get_at(pos + 1);
int adj = 0;
int lo_comp = val.compareTo(lo);
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
adj = -1;
else {
if (hi == null) return pos; // hi is null when at last slot in ary
int hi_comp = val.compareTo(hi);
if (hi_comp == CompareAble_.More) // val is > hi; search slots above
adj = 1;
else
return pos; // val is > lo and < hi; return slot
}
interval /= 2;
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
pos += (interval * adj);
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
if (pos < 0) pos = 0;
else if (pos > pos_last) pos = pos_last;
pos_prv = pos;
}
return Int_.Min_value; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
}
}

@ -15,9 +15,7 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.bldrs.sqls; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*;
public class Sql_file_parser_data {
public boolean Cancel_row() {return cancel_row;}
public Sql_file_parser_data Cancel_row_n_() {cancel_row = false; return this;}
public Sql_file_parser_data Cancel_row_y_() {cancel_row = true; return this;} private boolean cancel_row;
}
package gplx.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
public interface Binary_comparer {
int Compare_val_to_obj(Object val, Object obj);
}

@ -0,0 +1,63 @@
/*
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.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
public class Binary_search_ {
public static int Search(CompareAble[] ary , CompareAble val) {return Search(new Binary_search_grp__ary(ary) , new Binary_search_cmp__comparable(val));}
public static int Search(Object[] ary , Binary_comparer comparer, Object val) {return Search(new Binary_search_grp__ary(ary), new Binary_search_cmp__comparer(comparer, val));}
private static int Search(Binary_search_grp grp, Binary_search_cmp cmp) {
int grp_len = grp.Len();
if (grp_len == 1) return 0; // if 1 item, return 0;
if (grp_len == 0) return Bry_find_.Not_found; // if 0 item, return -1
// init
int interval = grp_len / 2;
int pos = interval - List_adp_.Base1;
int pos_last = grp_len - 1;
int pos_prv = -1;
int loop_count = 0;
while (loop_count++ < 32) { // 32=32-bit integer
Object lo = grp.Get_at(pos);
Object hi = pos + 1 == grp_len ? null : grp.Get_at(pos + 1);
int adj = 0;
int lo_comp = cmp.Compare(lo);
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
adj = -1;
else {
if (hi == null) return pos; // hi is null when at last slot in ary
int hi_comp = cmp.Compare(hi);
switch (hi_comp) {
case CompareAble_.More: // val is > hi; search slots above
adj = 1;
break;
case CompareAble_.Same: // val is > hi; search slots above
return pos + 1;
case CompareAble_.Less: // val is > lo and < hi; return slot
return pos;
}
}
interval /= 2;
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
pos += (interval * adj);
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
if (pos < 0) pos = 0;
else if (pos > pos_last) pos = pos_last;
pos_prv = pos;
}
return Bry_find_.Not_found; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
}
}

@ -15,33 +15,41 @@ 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.core.lists; import gplx.*; import gplx.core.*;
package gplx.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
import org.junit.*; import gplx.core.primitives.*;
public class Binary_search__tst {
private Binary_search__fxt fxt = new Binary_search__fxt();
private final Binary_search__fxt fxt = new Binary_search__fxt();
@Test public void Basic() {
fxt.Init_ary("", "e", "j", "o", "t", "y");
fxt.Test_binary_search("a", 0);
fxt.Test_binary_search("f", 1);
fxt.Test_binary_search("k", 2);
fxt.Test_binary_search("p", 3);
fxt.Test_binary_search("u", 4);
fxt.Test_binary_search("z", 5);
fxt.Init__ary("", "e", "j", "o", "t", "y");
fxt.Test__binary_search("a", 0);
fxt.Test__binary_search("f", 1);
fxt.Test__binary_search("k", 2);
fxt.Test__binary_search("p", 3);
fxt.Test__binary_search("u", 4);
fxt.Test__binary_search("z", 5);
}
@Test public void One() {
fxt.Init_ary("");
fxt.Test_binary_search("a", 0);
fxt.Init__ary("");
fxt.Test__binary_search("a", 0);
}
@Test public void Catpage() {
String[] ary = new String[25];
for (int i = 0; i < 25; ++i)
ary[i] = Int_.To_str_pad_bgn_zero(i, 2);
fxt.Init__ary(ary);
fxt.Test__binary_search("10", 10); // was 9
}
}
class Binary_search__fxt {
public void Init_ary(String... v) {
private String_obj_val[] ary;
public void Init__ary(String... v) {
int ary_len = v.length;
ary = new String_obj_val[ary_len];
for (int i = 0; i < ary_len; i++)
ary[i] = String_obj_val.new_(v[i]);
} private String_obj_val[] ary;
public void Test_binary_search(String val, int expd) {
int actl = Binary_search_.Search(ary, ary.length, String_obj_val.new_(val));
}
public void Test__binary_search(String val, int expd) {
int actl = Binary_search_.Search(ary, String_obj_val.new_(val));
Tfds.Eq(expd, actl, val);
}
}

@ -0,0 +1,36 @@
/*
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.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
import gplx.core.lists.*;
interface Binary_search_cmp {
int Compare(Object comp);
}
class Binary_search_cmp__comparable implements Binary_search_cmp {
private final CompareAble val;
public Binary_search_cmp__comparable(CompareAble val) {this.val = val;}
public int Compare(Object comp) {
return val.compareTo((CompareAble)comp);
}
}
class Binary_search_cmp__comparer implements Binary_search_cmp {
private final Binary_comparer comparer; private final Object val;
public Binary_search_cmp__comparer(Binary_comparer comparer, Object val) {this.comparer = comparer; this.val = val;}
public int Compare(Object comp) {
return comparer.Compare_val_to_obj(val, comp);
}
}

@ -0,0 +1,34 @@
/*
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.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
interface Binary_search_grp {
int Len();
Object Get_at(int i);
}
class Binary_search_grp__ary implements Binary_search_grp {
private final Object[] ary;
public Binary_search_grp__ary(Object[] ary) {this.ary = ary;}
public int Len() {return ary.length;}
public Object Get_at(int i) {return ary[i];}
}
class Binary_search_grp__list implements Binary_search_grp {
private final List_adp list;
public Binary_search_grp__list(List_adp list) {this.list = list;}
public int Len() {return list.Len();}
public Object Get_at(int i) {return list.Get_at(i);}
}

@ -22,7 +22,7 @@ public class Hash_adp__int {
private final Int_obj_ref tmp_key = Int_obj_ref.New_neg1();
public void Clear() {hash.Clear();}
public int Len() {return hash.Count();}
public Object Get_by(int key) {return hash.Get_by_or_fail(tmp_key.Val_(key));}
public Object Get_by_or_fail(int key) {return hash.Get_by_or_fail(tmp_key.Val_(key));}
public Object Get_by_or_null(int key) {return hash.Get_by(tmp_key.Val_(key));}
public void Add(int key, Object obj) {hash.Add(Int_obj_ref.New(key), obj);}
public void Add(Int_obj_ref key, Object obj) {hash.Add(key, obj);}

@ -22,10 +22,13 @@ public abstract class Http_download_wkr__base implements Http_download_wkr {
private Io_url tmp_url, checkpoint_url;
private long downloaded;
private long checkpoint_interval = 1024 * 1024, checkpoint_nxt = 0;
protected Io_url Checkpoint_url() {return checkpoint_url;}
protected Io_url Trg_url() {return trg_url;} private Io_url trg_url;
public Io_url Tmp_url() {return tmp_url;}
public String Fail_msg() {return fail_msg;} private String fail_msg;
public abstract Http_download_wkr Make_new();
public byte Exec(gplx.core.progs.Gfo_prog_ui prog_ui, String src_str, Io_url trg_url, long expd_size_val) {
this.trg_url = trg_url;
this.downloaded = this.Checkpoint__load_by_trg_fil(trg_url);
this.checkpoint_nxt = downloaded + checkpoint_interval;
this.expd_size = expd_size_val;

@ -32,7 +32,7 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
File trg_fil = new File(trg_url.Xto_api());
FileOutputStream trg_stream = null;
try {trg_stream = new FileOutputStream(trg_fil.getPath(), prog_resumed);} // pass true for append
catch (FileNotFoundException e) {throw Err_.new_("download_file", "write failed; permission error?", "trg", trg_url, "err", e.toString());}
catch (FileNotFoundException e) {throw Err_.new_wo_type("write failed; permission error?", "trg", trg_url, "err", e.toString());}
// open src stream
InputStream src_stream = null;
@ -41,7 +41,7 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
catch (MalformedURLException e) {
try {if (trg_stream != null) trg_stream.close();}
catch (IOException e1) {}
throw Err_.new_("download_file", "bad url", "src", src_url, "err" + e.toString());
throw Err_.new_wo_type("bad url", "src", src_url, "err" + e.toString());
}
HttpURLConnection src_conn = null;
try {
@ -58,21 +58,25 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
if (response_code != HttpURLConnection.HTTP_PARTIAL) {
try {if (trg_stream != null) trg_stream.close();}
catch (IOException e1) {}
throw Err_.new_("download_file", "server returned non-partial response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
if (response_code == 416 && prog_data_cur > 0) { // 416=Requested Range not satisfiable; if resuming at position > max_len, assume critical failure; delete files to start over from scratch; DATE:2016-09-24
Io_mgr.Instance.DeleteFil(this.Trg_url());
Io_mgr.Instance.DeleteFil(this.Checkpoint_url());
}
throw Err_.new_wo_type("server returned non-partial response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
}
}
else {
if (response_code != HttpURLConnection.HTTP_OK) {
try {if (trg_stream != null) trg_stream.close();}
catch (IOException e1) {}
throw Err_.new_("download_file", "server returned non-OK response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
throw Err_.new_wo_type("server returned non-OK response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
}
}
src_stream = src_conn.getInputStream();
} catch (Exception e) {
try {if (trg_stream != null) trg_stream.close();}
catch (IOException e1) {}
throw Err_.new_("download_file", "src connection failed", "src", src_url, "err",e.toString());
throw Err_.new_wo_type(Err__server_connection_failed, "src", src_url, "err", e.toString());
}
// do downloading
@ -89,7 +93,7 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
if (prog_ui.Prog_notify_and_chk_if_suspended(prog_data_cur, prog_data_end)) return Gfo_prog_ui_.Status__suspended;
}
} catch (Exception e) {
throw Err_.new_("download_file", "downloading failed", "src", src_url, "trg_url", trg_url, "err", e.toString());
throw Err_.new_wo_type(Err__server_download_failed, "src", src_url, "trg_url", trg_url, "err", e.toString());
}
finally {
try {
@ -100,4 +104,8 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
}
return Gfo_prog_ui_.Status__done;
}
}
public static final String
Err__server_connection_failed = "server connection failed"
, Err__server_download_failed = "server download failed"
;
}

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.cfgs; import gplx.*; import gplx.dbs.*;
import gplx.core.primitives.*;
public class Db_cfg_tbl implements Rls_able {
public class Db_cfg_tbl implements Db_tbl {
private final String tbl_name; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_grp, fld_key, fld_val;
private Db_stmt stmt_insert, stmt_update, stmt_select;
@ -34,7 +34,8 @@ public class Db_cfg_tbl implements Rls_able {
stmt_update = Db_stmt_.Rls(stmt_update);
stmt_select = Db_stmt_.Rls(stmt_select);
}
public Db_cfg_tbl Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_grp, fld_key, fld_val))); return this;}
public String Tbl_name() {return tbl_name;}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_grp, fld_key, fld_val)));}
public void Delete_val(String grp, String key) {conn.Stmt_delete(tbl_name, fld_grp, fld_key).Crt_str(fld_grp, grp).Crt_str(fld_key, key).Exec_delete();}
public void Delete_grp(String grp) {conn.Stmt_delete(tbl_name, fld_grp).Crt_str(fld_grp, grp).Exec_delete();}
public void Delete_all() {conn.Stmt_delete(tbl_name, Dbmeta_fld_itm.Str_ary_empty).Exec_delete();}

@ -24,11 +24,11 @@ public class Fsd_bin_itm {
this.bin_data_url = bin_data_url;
this.bin_data = bin_data;
}
public int Bin_owner_id() {return bin_owner_id;} private final int bin_owner_id;
public byte Bin_owner_tid() {return bin_owner_tid;} private final byte bin_owner_tid;
public int Bin_part_id() {return bin_part_id;} private final int bin_part_id;
public String Bin_data_url() {return bin_data_url;} private final String bin_data_url;
public byte[] Bin_data() {return bin_data;} private final byte[] bin_data;
public int Bin_owner_id() {return bin_owner_id;} private final int bin_owner_id;
public byte Bin_owner_tid() {return bin_owner_tid;} private final byte bin_owner_tid;
public int Bin_part_id() {return bin_part_id;} private final int bin_part_id;
public String Bin_data_url() {return bin_data_url;} private final String bin_data_url;
public byte[] Bin_data() {return bin_data;} private final byte[] bin_data;
public static final int Db_row_size_fixed = (3 * 4); // bin_owner_id, bin_part_id, bin_owner_tid (assume byte saved as int in SQLITE)
}

@ -17,10 +17,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_dir_itm {
public Fsd_dir_itm(int dir_id, int owner, byte[] name) {this.dir_id = dir_id; this.owner = owner; this.name = name;}
public int Dir_id() {return dir_id;} private final int dir_id;
public int Owner() {return owner;} private final int owner;
public byte[] Name() {return name;} private final byte[] name;
public Fsd_dir_itm(int dir_id, int owner, byte[] name) {
this.dir_id = dir_id;
this.owner = owner;
this.name = name;
}
public int Dir_id() {return dir_id;} private final int dir_id;
public int Owner() {return owner;} private final int owner;
public byte[] Name() {return name;} private final byte[] name;
public static final int Owner_root = 0;
public static final Fsd_dir_itm Null = null;
}

@ -20,7 +20,7 @@ import gplx.dbs.*;
public class Fsd_dir_tbl implements Rls_able {
private final String tbl_name = "fsdb_dir"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_id, fld_owner_id, fld_name;
private final Db_conn conn; private Db_stmt stmt_insert, stmt_update, stmt_select_by_name;
private final Db_conn conn; private Db_stmt stmt_select_by_name;
public Fsd_dir_tbl(Db_conn conn, boolean schema_is_1) {
this.conn = conn;
this.fld_id = flds.Add_int_pkey ("dir_id");
@ -29,8 +29,6 @@ public class Fsd_dir_tbl implements Rls_able {
conn.Rls_reg(this);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_update = Db_stmt_.Rls(stmt_update);
stmt_select_by_name = Db_stmt_.Rls(stmt_select_by_name);
}
public void Create_tbl() {
@ -39,20 +37,22 @@ public class Fsd_dir_tbl implements Rls_able {
, Dbmeta_idx_itm.new_normal_by_tbl(tbl_name, "name", fld_name, fld_owner_id, fld_id)));
}
public void Insert(int id, byte[] name, int owner_id) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
Db_stmt stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_id, id)
.Val_int(fld_owner_id, owner_id)
.Val_bry_as_str(fld_name, name)
.Exec_insert();
stmt_insert.Rls();
}
public void Update(int id, byte[] name, int owner_id) {
if (stmt_update == null) stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_id);
Db_stmt stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_id);
stmt_update.Clear()
.Val_int(fld_owner_id, owner_id)
.Val_bry_as_str(fld_name, name)
.Crt_int(fld_id, id)
.Exec_update();
stmt_update.Rls();
}
public Fsd_dir_itm Select_or_null(byte[] name) {
if (stmt_select_by_name == null) stmt_select_by_name = conn.Stmt_select(tbl_name, flds, fld_name);

@ -17,26 +17,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_fil_itm {
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Xtn_id() {return xtn_id;} private int xtn_id;
public int Ext_id() {return ext_id;} private int ext_id;
public byte[] Name() {return name;} private byte[] name;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
public long Size() {return size;} private long size;
public String Modified_on() {return modified_on;} private String modified_on;
public String Hash_md5() {return hash_md5;} private String hash_md5;
public Fsd_fil_itm Ctor(int mnt_id, int dir_id, int fil_id, int bin_db_id, byte[] name, int ext_id) {
this.mnt_id = mnt_id; this.dir_id = dir_id; this.fil_id = fil_id; this.bin_db_id = bin_db_id; this.name = name; this.ext_id = ext_id;
return this;
}
public Fsd_fil_itm Load_by_rdr__full(int mnt_id, int dir_id, int fil_id, int xtn_id, int ext_id, byte[] name, long size, String modified_on, String hash_md5, int bin_db_id) {
public Fsd_fil_itm (int mnt_id, int dir_id, int fil_id, int xtn_id, int ext_id, byte[] name, long size, String modified_on, String hash_md5, int bin_db_id) {
this.mnt_id = mnt_id; this.dir_id = dir_id; this.fil_id = fil_id; this.xtn_id = xtn_id; this.ext_id = ext_id;
this.name = name; this.size = size; this.modified_on = modified_on; this.hash_md5 = hash_md5; this.bin_db_id = bin_db_id;
return this;
}
public int Mnt_id() {return mnt_id;} private final int mnt_id;
public int Dir_id() {return dir_id;} private final int dir_id;
public int Fil_id() {return fil_id;} private final int fil_id;
public int Xtn_id() {return xtn_id;} private final int xtn_id;
public int Ext_id() {return ext_id;} private final int ext_id;
public byte[] Name() {return name;} private final byte[] name;
public long Size() {return size;} private final long size;
public String Modified_on() {return modified_on;} private final String modified_on;
public String Hash_md5() {return hash_md5;} private final String hash_md5;
public int Bin_db_id() {return bin_db_id;} private final int bin_db_id;
public int Db_row_size() {return Db_row_size_fixed + name.length;}
private static final int Db_row_size_fixed =
(7 * 4) // 6 int fields + 1 byte field

@ -87,7 +87,7 @@ public class Fsd_fil_tbl implements Rls_able {
.Crt_bry_as_str(fld_name, fil_name)
.Exec_select__rls_manual();
try {
return rdr.Move_next() ? Load_by_rdr(mnt_id, rdr) : Fsd_fil_itm.Null;
return rdr.Move_next() ? New_by_rdr(mnt_id, rdr) : Fsd_fil_itm.Null;
}
finally {rdr.Rls();}
}
@ -95,28 +95,25 @@ public class Fsd_fil_tbl implements Rls_able {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Dbmeta_fld_itm.Str_ary_empty).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
Fsd_fil_itm fil = Load_by_rdr(mnt_id, rdr);
Fsd_fil_itm fil = New_by_rdr(mnt_id, rdr);
byte[] cache_key = Fsd_fil_itm.Gen_cache_key(key_bfr, fil.Dir_id(), fil.Name());
cache.Add(cache_key, fil);
}
}
finally {rdr.Rls();}
}
public Fsd_fil_itm Load_by_rdr(int mnt_id, Db_rdr rdr) {
return new Fsd_fil_itm().Ctor(mnt_id, rdr.Read_int(fld_owner_id), rdr.Read_int(fld_id), rdr.Read_int(fld_bin_db_id), rdr.Read_bry_by_str(fld_name), rdr.Read_int(fld_ext_id));
}
public Fsd_fil_itm Load_by_rdr__full(int mnt_id, Db_rdr rdr) {
return new Fsd_fil_itm()
.Load_by_rdr__full(mnt_id
, rdr.Read_int(fld_owner_id)
, rdr.Read_int(fld_id)
, rdr.Read_int(fld_xtn_id)
, rdr.Read_int(fld_ext_id)
, rdr.Read_bry_by_str(fld_name)
, rdr.Read_long(fld_size)
, rdr.Read_str(fld_modified)
, rdr.Read_str(fld_hash)
, rdr.Read_int(fld_bin_db_id)
);
public Fsd_fil_itm New_by_rdr(int mnt_id, Db_rdr rdr) {
return new Fsd_fil_itm
( mnt_id
, rdr.Read_int(fld_owner_id)
, rdr.Read_int(fld_id)
, rdr.Read_int(fld_xtn_id)
, rdr.Read_int(fld_ext_id)
, rdr.Read_bry_by_str(fld_name)
, rdr.Read_long(fld_size)
, rdr.Read_str(fld_modified)
, rdr.Read_str(fld_hash)
, rdr.Read_int(fld_bin_db_id)
);
}
}

@ -17,11 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_img_itm {
public void Ctor(int mnt_id, int dir_id, int fil_id, int bin_db_id) {
public Fsd_img_itm(int mnt_id, int dir_id, int fil_id, int bin_db_id) {
this.mnt_id = mnt_id; this.dir_id = dir_id; this.fil_id = fil_id; this.bin_db_id = bin_db_id;
}
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
public int Mnt_id() {return mnt_id;} private final int mnt_id;
public int Dir_id() {return dir_id;} private final int dir_id;
public int Fil_id() {return fil_id;} private final int fil_id;
public int Bin_db_id() {return bin_db_id;} private final int bin_db_id;
}

@ -22,21 +22,21 @@ public class Fsd_thm_itm {
this.w = w; this.h = h; this.time = time; this.page = page;
this.size = size; this.modified = modified; this.hash = hash;
}
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Thm_id() {return thm_id;} private int thm_id;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
public int W() {return w;} private int w;
public int H() {return h;} private int h;
public double Time() {return time;} private double time;
public int Page() {return page;} private int page;
public long Size() {return size;} private long size;
public String Modified() {return modified;} private String modified;
public String Hash() {return hash;} private String hash;
public int Req_w() {return req_w;} private int req_w;
public double Req_time() {return req_time;} private double req_time;
public int Req_page() {return req_page;} private int req_page;
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Thm_id() {return thm_id;} private int thm_id;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
public int W() {return w;} private int w;
public int H() {return h;} private int h;
public double Time() {return time;} private double time;
public int Page() {return page;} private int page;
public long Size() {return size;} private long size;
public String Modified() {return modified;} private String modified;
public String Hash() {return hash;} private String hash;
public int Req_w() {return req_w;} private int req_w;
public double Req_time() {return req_time;} private double req_time;
public int Req_page() {return req_page;} private int req_page;
public void Init_by_req(int w, double time, int page) {this.w = w; this.time = time; this.page = page;}
public void Init_by_match(Fsd_thm_itm comp) {
this.req_w = w; this.req_time = time; this.req_page = page;

@ -39,17 +39,15 @@ public class Fsm_atr_fil {
public boolean Select_thm(boolean exact, Fsd_thm_itm rv, int dir_id, int fil_id) {
return exact ? tbl_thm.Select_itm_by_w_exact(dir_id, fil_id, rv) : tbl_thm.Select_itm_by_w_near(dir_id, fil_id, rv);
}
public int Insert_fil(Fsd_fil_itm rv, byte[] dir, byte[] fil, int ext_id, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
public Fsd_fil_itm Insert_fil(byte[] dir, byte[] fil, int ext_id, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
int dir_id = Get_dir_id_or_make(dir);
int fil_id = Get_fil_id_or_make(Tid_none, dir_id, fil, ext_id, bin_db_id, bin_len);
rv.Ctor(mnt_id, fil_id, dir_id, bin_db_id, fil, ext_id);
return fil_id;
return new Fsd_fil_itm(mnt_id, dir_id, fil_id, 0, ext_id, fil, bin_len, null, null, bin_db_id);
}
public int Insert_img(Fsd_img_itm rv, byte[] dir, byte[] fil, int ext_id, int img_w, int img_h, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
public Fsd_img_itm Insert_img(byte[] dir, byte[] fil, int ext_id, int img_w, int img_h, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
int dir_id = Get_dir_id_or_make(dir);
int fil_id = Get_fil_id_or_make(Tid_img, dir_id, fil, ext_id, bin_db_id, bin_len);
rv.Ctor(mnt_id, dir_id, fil_id, bin_db_id);
return fil_id;
return new Fsd_img_itm(mnt_id, dir_id, fil_id, bin_db_id);
}
public int Insert_thm(Fsd_thm_itm rv, byte[] dir, byte[] fil, int ext_id, int w, int h, double time, int page, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
int dir_id = Get_dir_id_or_make(dir);

@ -43,13 +43,15 @@ public class Fsm_mnt_itm {
Fsd_fil_itm fil_itm = atr_mgr.Select_fil_or_null(dir, fil);
return fil_itm == Fsd_fil_itm.Null ? Bool_.N : atr_mgr.Select_thm(exact, rv, fil_itm.Dir_id(), fil_itm.Fil_id());
}
public void Insert_img(Fsd_img_itm rv, Fsm_atr_fil atr_fil, Fsm_bin_fil bin_fil, byte[] dir, byte[] fil, int ext_id, int img_w, int img_h, long bin_len, Io_stream_rdr bin_rdr) {
int fil_id = atr_fil.Insert_img(rv, dir, fil, ext_id, img_w, img_h, bin_fil.Id(), bin_len, bin_rdr);
bin_fil.Insert(fil_id, Fsd_bin_tbl.Owner_tid_fil, bin_len, bin_rdr);
public Fsd_img_itm Insert_img(Fsm_atr_fil atr_fil, Fsm_bin_fil bin_fil, byte[] dir, byte[] fil, int ext_id, int img_w, int img_h, long bin_len, Io_stream_rdr bin_rdr) {
Fsd_img_itm rv = atr_fil.Insert_img(dir, fil, ext_id, img_w, img_h, bin_fil.Id(), bin_len, bin_rdr);
bin_fil.Insert(rv.Fil_id(), Fsd_bin_tbl.Owner_tid_fil, bin_len, bin_rdr);
return rv;
}
public void Insert_fil(Fsd_fil_itm rv, Fsm_atr_fil atr_fil, Fsm_bin_fil bin_fil, byte[] dir, byte[] fil, int ext_id, long bin_len, gplx.core.ios.streams.Io_stream_rdr bin_rdr) {
int fil_id = atr_fil.Insert_fil(rv, dir, fil, ext_id, bin_fil.Id(), bin_len, bin_rdr);
bin_fil.Insert(fil_id, Fsd_bin_tbl.Owner_tid_fil, bin_len, bin_rdr);
public Fsd_fil_itm Insert_fil(Fsm_atr_fil atr_fil, Fsm_bin_fil bin_fil, byte[] dir, byte[] fil, int ext_id, long bin_len, gplx.core.ios.streams.Io_stream_rdr bin_rdr) {
Fsd_fil_itm rv = atr_fil.Insert_fil(dir, fil, ext_id, bin_fil.Id(), bin_len, bin_rdr);
bin_fil.Insert(rv.Fil_id(), Fsd_bin_tbl.Owner_tid_fil, bin_len, bin_rdr);
return rv;
}
public void Insert_thm(Fsd_thm_itm rv, Fsm_atr_fil atr_fil, Fsm_bin_fil bin_fil, byte[] dir, byte[] fil, int ext_id, int w, int h, double time, int page, long bin_len, Io_stream_rdr bin_rdr) {
int thm_id = atr_fil.Insert_thm(rv, dir, fil, ext_id, w, h, time, page, bin_fil.Id(), bin_len, bin_rdr);

@ -76,6 +76,7 @@ public class Gfh_tag_ { // NOTE: not serialized; used by tag_rdr
, Id__blockquote = 52
, Id__map = 53
, Id__bdo = 54
, Id__time = 55
;
// private static final int Id__ary_max = 54;
public static final byte[]
@ -156,6 +157,7 @@ public class Gfh_tag_ { // NOTE: not serialized; used by tag_rdr
.Add_str_int("blockquote" , Id__blockquote)
.Add_str_int("map" , Id__map)
.Add_str_int("bdo" , Id__bdo)
.Add_str_int("time" , Id__time)
;
public static String To_str(int tid) {
switch (tid) {
@ -217,6 +219,7 @@ public class Gfh_tag_ { // NOTE: not serialized; used by tag_rdr
case Id__blockquote: return "blockquote";
case Id__map: return "map";
case Id__bdo: return "bdo";
case Id__time: return "time";
default: throw Err_.new_unhandled(tid);
}
}

@ -85,6 +85,13 @@ public class Gfo_url_encoder_ {
return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent).Init_common(Bool_.Y)
.Init__same__many(Byte_ascii.Paren_bgn, Byte_ascii.Paren_end, Byte_ascii.Apos, Byte_ascii.Semic);
}
public static Gfo_url_encoder_mkr New__mw_ttl() {
return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent)
.Init__same__rng(0, 255)
.Init__diff__many(Byte_ascii.Percent, Byte_ascii.Amp, Byte_ascii.Apos, Byte_ascii.Eq, Byte_ascii.Plus)
.Init__diff__one(Byte_ascii.Space, Byte_ascii.Underline)
;
}
public static final Gfo_url_encoder
Id = Gfo_url_encoder_.New__html_id().Make()
, Href = Gfo_url_encoder_.New__html_href_mw(Bool_.Y).Make()
@ -95,5 +102,6 @@ public class Gfo_url_encoder_ {
, Xourl = Gfo_url_encoder_.New__html_href_mw(Bool_.Y).Init__same__many(Byte_ascii.Underline).Make()
, Http_url = Gfo_url_encoder_.New__http_url().Make()
, Http_url_ttl = Gfo_url_encoder_.New__http_url_ttl().Make()
, Mw_ttl = Gfo_url_encoder_.New__mw_ttl().Make()
;
}

@ -32,6 +32,8 @@ public class Gfo_url_encoder_tst {
fxt.Encoder_id().Encoder().Decode(tmp_bfr, Bool_.N, raw, 0, raw.length);
Tfds.Eq("0%.jpg", tmp_bfr.To_str_and_clear());
}
@Test public void Ttl__syms__diff() {fxt.Encoder_ttl().Test__encode(" &'=+", "_%26%27%3D%2B");}
@Test public void Ttl__syms__same() {fxt.Encoder_ttl().Test__encode("!\"#$%()*,-./:;<>?@[\\]^_`{|}~", "!\"#$%()*,-./:;<>?@[\\]^_`{|}~");}
@Test public void Url__syms() {fxt.Encoder_url().Test__bicode("!?^~", "%21%3F%5E%7E");}
@Test public void Url__foreign() {fxt.Encoder_url().Test__bicode("aéb", "a%C3%A9b");}
@Test public void Url__space() {fxt.Encoder_url().Test__bicode("a b", "a+b");}
@ -54,6 +56,7 @@ class Gfo_url_encoder_fxt {
public Gfo_url_encoder_fxt Encoder_id() {encoder = Gfo_url_encoder_.Id; return this;}
public Gfo_url_encoder_fxt Encoder_href() {encoder = Gfo_url_encoder_.Href; return this;}
public Gfo_url_encoder_fxt Encoder_url() {encoder = Gfo_url_encoder_.Http_url; return this;}
public Gfo_url_encoder_fxt Encoder_ttl() {encoder = Gfo_url_encoder_.Mw_ttl; return this;}
public Gfo_url_encoder_fxt Encoder_fsys_safe() {encoder = Gfo_url_encoder_.New__fsys_wnt().Make(); return this;}
public void Test__bicode(String raw, String encoded) {
Test__encode(raw, encoded);

@ -32,7 +32,7 @@ public class Xoa_app_ {
}
}
public static final String Name = "xowa";
public static final String Version = "3.9.2.1";
public static final String Version = "3.9.4.1";
public static String Build_date = "2012-12-30 00:00:00";
public static String Op_sys_str;
public static String User_agent = "";

@ -20,7 +20,7 @@ import gplx.core.primitives.*; import gplx.core.btries.*;
import gplx.langs.htmls.entitys.*;
import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.xwikis.*;
import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.miscs.*;
import gplx.xowa.apps.urls.*; import gplx.langs.htmls.encoders.*; import gplx.xowa.langs.cases.*;
import gplx.xowa.apps.utls.*; import gplx.langs.htmls.encoders.*; import gplx.xowa.langs.cases.*;
public class Xoa_ttl { // PAGE:en.w:http://en.wikipedia.org/wiki/Help:Link; REF.MW: Ttl.php|secureAndSplit;
private int wik_bgn = -1, ns_bgn = -1, page_bgn = 0, leaf_bgn = -1, anch_bgn = -1, root_bgn = -1;
private byte[] tors_txt;

@ -171,7 +171,6 @@ public class Xop_fxt {
}
public void Init_defn_clear() {wiki.Cache_mgr().Defn_cache().Free_mem_all();}
public Xop_fxt Init_id_create(int id, int fil_idx, int row_idx, boolean type_redirect, int itm_len, int ns_id, String ttl) {Xow_hive_mgr_fxt.Create_id(app, wiki.Hive_mgr(), id, fil_idx, row_idx, type_redirect, itm_len, ns_id, ttl); return this;}
public Xop_fxt Init_ctg_create(String ctg, int... pages) {Xow_hive_mgr_fxt.Create_ctg(app, wiki.Hive_mgr(), ctg, pages); return this;}
public Xop_fxt Init_page_create(String ttl) {return Init_page_create(wiki, ttl, "");}
public Xop_fxt Init_page_create(String ttl, String txt) {return Init_page_create(wiki, ttl, txt);}
public Xop_fxt Init_page_create(Xowe_wiki wiki, String ttl, String txt) {Init_page_create_static(wiki, ttl, txt);return this;}

@ -41,7 +41,7 @@ public class Xoax_addon_mgr {
, new gplx.xowa.addons.bldrs.wmdumps.imglinks .Imglnk_addon()
, new gplx.xowa.addons.bldrs.utils_rankings .Xoax_builds_utils_rankings_addon()
, new gplx.xowa.addons.wikis.searchs .Xoax_builds_search_addon()
, new gplx.xowa.addons.bldrs.updates.files .Xoax_updates_files_addon()
, new gplx.xowa.addons.bldrs.updates.files .Xodel_addon()
, new gplx.xowa.addons.bldrs.htmls .Html__dump_to_fsys__addon()
, new gplx.xowa.addons.bldrs.exports .Export_addon()
, new gplx.xowa.addons.wikis.pages.randoms .Rndm_addon()

@ -34,25 +34,35 @@ public class Xobc_cmd__download extends Xobc_cmd__base {
@Override protected void Cmd_exec_hook(Xobc_cmd_ctx ctx) {
int error_wait = 10000, error_tries_max = 6, error_tries_cur = 0; // retry every 10 seconds for a total of 6 tries (1 min)
// loop while "server ... " error
while (true) {
long trg_size_bgn = Io_mgr.Instance.QueryFil(wkr.Tmp_url()).Size();
long trg_size_bgn = Tmp_url_size();
byte status = wkr.Exec(this, src_url, trg_url, expd_size);
if (status == Gfo_prog_ui_.Status__fail) {
// check if anything more downloaded; if so, then reset to 0; DATE:2016-09-03
long trg_size_cur = Io_mgr.Instance.QueryFil(wkr.Tmp_url()).Size();
if (trg_size_cur > trg_size_bgn) {
error_tries_cur = 0;
trg_size_bgn = trg_size_cur;
}
// retry
if (error_tries_cur++ < error_tries_max) {
task_mgr.Work_mgr().On_stat(this.Task_id(), String_.Format("connection interrupted: retrying in {0} seconds; attempt {1} of {2}", error_wait / 1000, error_tries_cur, error_tries_max));
Gfo_usr_dlg_.Instance.Log_many("", "", "xobc_cmd task download interrupted; ~{0} ~{1} ~{2} ~{3}", this.Task_id(), this.Step_id(), trg_url, Io_mgr.Instance.QueryFil(trg_url).Size());
gplx.core.threads.Thread_adp_.Sleep(error_wait);
continue;
// check if server error; note: must not loop if bad size; DATE:2016-09-24
String fail_msg = wkr.Fail_msg();
if (String_.Has_at_bgn(fail_msg, Http_download_wkr__jre.Err__server_download_failed)) {
// check if anything more downloaded; if so, then reset to 0; DATE:2016-09-03
long trg_size_cur = Tmp_url_size();
if (trg_size_cur > trg_size_bgn) {
error_tries_cur = 0;
trg_size_bgn = trg_size_cur;
}
// retry
if (error_tries_cur++ < error_tries_max) {
task_mgr.Work_mgr().On_stat(this.Task_id(), String_.Format("connection interrupted: retrying in {0} seconds; attempt {1} of {2}", error_wait / 1000, error_tries_cur, error_tries_max));
Gfo_usr_dlg_.Instance.Log_many("", "", "xobc_cmd task download interrupted; ~{0} ~{1} ~{2} ~{3}", this.Task_id(), this.Step_id(), trg_url, Io_mgr.Instance.QueryFil(trg_url).Size());
gplx.core.threads.Thread_adp_.Sleep(error_wait);
continue;
}
}
this.Cmd_exec_err_(wkr.Fail_msg());
// otherewise exit loop
this.Cmd_exec_err_(fail_msg);
break;
}
else
@ -60,6 +70,9 @@ public class Xobc_cmd__download extends Xobc_cmd__base {
}
Gfo_log_.Instance.Info("xobc_cmd task download", "task_id", this.Task_id(), "step_id", this.Step_id(), "trg_url", trg_url, "trg_len", Io_mgr.Instance.QueryFil(trg_url).Size());
}
private long Tmp_url_size() {
return wkr.Tmp_url() == null ? 0 : Io_mgr.Instance.QueryFil(wkr.Tmp_url()).Size(); // NOTE: wkr.Tmp_url is null in some extreme exceptions; DATE:2016-09-24
}
@Override public void Cmd_cleanup() {
wkr.Exec_cleanup();
}

@ -0,0 +1,46 @@
/*
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.addons.bldrs.centrals.cmds; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.centrals.*;
import gplx.dbs.*;
import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.addons.bldrs.updates.files.*;
public class Xobc_cmd__fsdb_delete extends Xobc_cmd__base {
private final Io_url deletion_db_url;
public Xobc_cmd__fsdb_delete(Xobc_task_mgr task_mgr, int task_id, int step_id, int cmd_idx, Io_url deletion_db_url) {super(task_mgr, task_id, step_id, cmd_idx);
this.deletion_db_url = deletion_db_url;
}
@Override public String Cmd_type() {return CMD_TYPE;} public static final String CMD_TYPE = "xowa.fsdb.delete";
@Override public String Cmd_name() {return "deleting old files";}
@Override public boolean Cmd_suspendable() {return true;}
@Override protected void Cmd_exec_hook(Xobc_cmd_ctx ctx) {
if (!Io_mgr.Instance.ExistsFil(deletion_db_url)) throw Err_.New("deletion db does not exist; file={0}", deletion_db_url.Raw());
boolean pass = false;
try {
new Xodel_exec_mgr().Exec_delete(this, ctx.App().Bldr(), deletion_db_url);
pass = true;
}
catch (Exception e) {
this.Cmd_exec_err_(Err_.Message_gplx_log(e));
}
Gfo_log_.Instance.Info("xobc_cmd task delete", "task_id", this.Task_id(), "step_id", this.Step_id(), "delete_url", deletion_db_url.Raw(), "pass", pass);
}
@Override public void Cmd_cleanup() {
if (Io_mgr.Instance.ExistsFil(deletion_db_url))
new Xodel_exec_mgr().Exec_cleanup(deletion_db_url);
}
}

@ -20,9 +20,9 @@ import gplx.core.progs.*;
import gplx.core.security.*; import gplx.core.security.files.*;
public class Xobc_cmd__verify_dir extends Xobc_cmd__base {
private final Io_url delete_fil, checksum_fil;
public Xobc_cmd__verify_dir(Xobc_task_mgr task_mgr, int task_id, int step_id, int cmd_idx, Io_url dir_url, String checksum_fil_name, Io_url delete_fil) {super(task_mgr, task_id, step_id, cmd_idx);
public Xobc_cmd__verify_dir(Xobc_task_mgr task_mgr, int task_id, int step_id, int cmd_idx, Io_url checksum_fil, Io_url delete_fil) {super(task_mgr, task_id, step_id, cmd_idx);
this.checksum_fil = checksum_fil;
this.delete_fil = delete_fil;
this.checksum_fil = dir_url.GenSubFil(checksum_fil_name);
}
@Override public String Cmd_type() {return CMD_TYPE;} public static final String CMD_TYPE = "xowa.core.hash_dir";
@Override public String Cmd_name() {return "verify";}

@ -18,13 +18,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.addons.bldrs.centrals.dbs.datas.imports; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.centrals.*; import gplx.xowa.addons.bldrs.centrals.dbs.*; import gplx.xowa.addons.bldrs.centrals.dbs.datas.*;
public class Xobc_import_type {
public static final int // SERIALIZED: bc_db; import_step
Tid__ignore = 0
, Tid__pack = 1
, Tid__wiki__core = 2
, Tid__wiki__srch = 3
, Tid__wiki__html = 4
, Tid__wiki__text = 5
, Tid__file__core = 6
, Tid__file__data = 7
Tid__ignore = 0
, Tid__pack = 1
, Tid__wiki__core = 2
, Tid__wiki__srch = 3
, Tid__wiki__html = 4
, Tid__wiki__text = 5
, Tid__file__core = 6
, Tid__file__data = 7
, Tid__fsdb__delete = 8
, Tid__wiki__ctg = 9
;
}

@ -20,6 +20,9 @@ import gplx.core.brys.evals.*; import gplx.core.primitives.*;
import gplx.xowa.addons.bldrs.centrals.tasks.*; import gplx.xowa.addons.bldrs.centrals.cmds.*; import gplx.xowa.addons.bldrs.centrals.steps.*; import gplx.xowa.addons.bldrs.centrals.utils.*;
import gplx.xowa.addons.bldrs.centrals.dbs.*; import gplx.xowa.addons.bldrs.centrals.dbs.datas.*; import gplx.xowa.addons.bldrs.centrals.dbs.datas.imports.*; import gplx.xowa.addons.bldrs.centrals.hosts.*;
import gplx.xowa.addons.bldrs.exports.merges.*;
import gplx.xowa.addons.bldrs.updates.files.*;
import gplx.xowa.addons.bldrs.exports.packs.files.*;
import gplx.xowa.bldrs.*;
import gplx.xowa.wikis.domains.*;
public class Xobc_step_factory {
private final Xobc_task_mgr task_mgr;
@ -60,16 +63,24 @@ public class Xobc_step_factory {
Io_url zip_file_url = Eval_url(Bry_eval_wkr__builder_central.Make_str(Bry_eval_wkr__builder_central.Type__download_fil, wiki_domain, file_name));
Io_url unzip_dir_url = Eval_url(Bry_eval_wkr__builder_central.Make_str(Bry_eval_wkr__builder_central.Type__unzip_dir, wiki_domain, file_name));
Io_url wiki_dir_url = Eval_url(Bry_eval_wkr__builder_central.Make_str(Bry_eval_wkr__builder_central.Type__wiki_dir, wiki_domain, file_name));
list.Add(new Xobc_cmd__download (task_mgr, task_id, step_id, 0, src_http_url, zip_file_url, import_itm.Import_size_zip));
list.Add(new Xobc_cmd__verify_fil (task_mgr, task_id, step_id, 1, zip_file_url, import_itm.Import_md5, import_itm.Import_size_zip));
list.Add(new Xobc_cmd__unzip (task_mgr, task_id, step_id, 2, zip_file_url, unzip_dir_url, import_itm.Import_size_raw));
list.Add(new Xobc_cmd__verify_dir (task_mgr, task_id, step_id, 3, unzip_dir_url, String_.Replace(file_name, ".zip", ".md5"), zip_file_url));
// list.Add(new Xobc_cmd__wiki_merge (task_mgr, task_id, step_id, 4, merge_mgr, wiki_domain, unzip_dir_url, import_itm.Import_prog_data_max, import_itm.Import_prog_row_max, step_seqn));
list.Add(new Xobc_cmd__move_fils (task_mgr, task_id, step_id, 4, unzip_dir_url, wiki_dir_url));
if (import_itm.Import_type == Xobc_import_type.Tid__wiki__core) {
list.Add(new Xobc_cmd__wiki_reg (task_mgr, task_id, step_id, 5, wiki_dir_url, wiki_domain));
Io_url checksum_url = unzip_dir_url.GenSubFil(file_name + ".md5");
int cmd_idx = 0;
list.Add(new Xobc_cmd__download (task_mgr, task_id, step_id, cmd_idx++, src_http_url, zip_file_url, import_itm.Import_size_zip));
list.Add(new Xobc_cmd__verify_fil (task_mgr, task_id, step_id, cmd_idx++, zip_file_url, import_itm.Import_md5, import_itm.Import_size_zip));
list.Add(new Xobc_cmd__unzip (task_mgr, task_id, step_id, cmd_idx++, zip_file_url, unzip_dir_url, import_itm.Import_size_raw));
list.Add(new Xobc_cmd__verify_dir (task_mgr, task_id, step_id, cmd_idx++, checksum_url, zip_file_url));
// list.Add(new Xobc_cmd__wiki_merge (task_mgr, task_id, step_id, cmd_idx++, merge_mgr, wiki_domain, unzip_dir_url, import_itm.Import_prog_data_max, import_itm.Import_prog_row_max, step_seqn));
list.Add(new Xobc_cmd__move_fils (task_mgr, task_id, step_id, cmd_idx++, unzip_dir_url, wiki_dir_url));
switch (import_itm.Import_type) {
case Xobc_import_type.Tid__wiki__core: list.Add(new Xobc_cmd__wiki_reg (task_mgr, task_id, step_id, cmd_idx++, wiki_dir_url, wiki_domain)); break;
case Xobc_import_type.Tid__fsdb__delete: list.Add(new Xobc_cmd__fsdb_delete (task_mgr, task_id, step_id, cmd_idx++, Pack_zip_name_bldr.To_wiki_url(wiki_dir_url, zip_file_url.OwnerDir()))); break;
}
return (Xobc_cmd_itm[])list.To_ary_and_clear(Xobc_cmd_itm.class);
}
private Io_url Eval_url(String src) {return Io_url_.new_any_(String_.new_u8(eval_mgr.Eval(Bry_.new_u8(src))));}
public static Xow_wiki Get_wiki_by_abrv(Xoa_app app, byte[] wiki_abrv) {
Xow_domain_itm domain_itm = Xow_abrv_xo_.To_itm(wiki_abrv);
return app.Wiki_mgri().Get_by_or_make_init_y(domain_itm.Domain_bry());
}
}

@ -79,8 +79,8 @@ public class Xobc_task_regy__work extends Xobc_task_regy__base {
thread_mgr.Halt(cmd_uid, Thread_halt_cbk_.Noop);
}
private void Redo_task(Xobc_task_itm task, Xobc_step_itm step, Xobc_cmd_itm cmd) {
cmd.Cmd_clear();
cmd = step.Step_fallback_to(cmd.Cmd_fallback());
cmd.Cmd_clear();
task.Task_status_(gplx.core.progs.Gfo_prog_ui_.Status__working);
task_mgr.Send_json("xo.bldr.work.prog__start__recv", task.Save_to(Gfobj_nde.New()));
thread_mgr.Add(cmd.Cmd_uid(), Thread_adp_.Start_by_val("xobc: " + cmd.Cmd_name(), cmd, cmd, Xobc_cmd__base.Invk__exec, ctx));

@ -22,7 +22,7 @@ public class Bry_eval_wkr__builder_central implements Bry_eval_wkr {
public Bry_eval_wkr__builder_central(Io_url wiki_dir) {this.wiki_dir = wiki_dir.RawBry();}
public String Key() {return "builder_central";}
public void Resolve(Bry_bfr rv, byte[] src, int args_bgn, int args_end) {
// EX: "~{builder_central|download_fil|en.wikipedia.org|en.wikipedia.org-2016.05-html-ns.000-db.001.zip}" -> "/xowa/wiki/en.wikipedia.org/tmp/bldr/en.wikipedia.org-2016.05-html-ns.000-db.001.zip/download.zip"
// EX: "~{builder_central|download_fil|en.wikipedia.org|Xowa_enwiki_2016-05_html_ns.000_db.001.zip}" -> "/xowa/wiki/en.wikipedia.org/tmp/bldr/Xowa_enwiki_2016-05_html_ns.000_db.001.zip/download.zip"
byte[][] args = Bry_split_.Split(src, args_bgn, args_end, Byte_ascii.Pipe, Bool_.N);
int type = hash.Get_as_byte_or(args[0], Byte_.Max_value_127);
if (type == Byte_.Max_value_127) throw Err_.new_wo_type("unknown eval type", "src", src);
@ -32,7 +32,7 @@ public class Bry_eval_wkr__builder_central implements Bry_eval_wkr {
if (type == Type__wiki_dir) return;
rv.Add_str_a7("tmp").Add_byte(dir_spr); // "tmp/"
rv.Add_str_a7("bldr").Add_byte(dir_spr); // "bldr/"
rv.Add(args[2]).Add_byte(dir_spr); // "en.wikipedia.org-2016.05-html-ns.000-db.001.zip/"
rv.Add(args[2]).Add_byte(dir_spr); // "Xowa_enwiki_2016-05_html_ns.000_db.001.zip/"
switch (type) {
case Type__download_fil: rv.Add_str_a7("download.zip"); break;
case Type__unzip_dir: rv.Add_str_a7("unzip").Add_byte(dir_spr); break;

@ -21,6 +21,7 @@ public class Pack_file_bldr_cfg implements Gfo_invk {
public Io_url Deploy_dir() {return deploy_dir;} private Io_url deploy_dir;
public boolean Pack_html() {return pack_html;} private boolean pack_html = true;
public boolean Pack_file() {return pack_file;} private boolean pack_file = true;
public boolean Pack_fsdb_delete() {return pack_fsdb_delete;} private boolean pack_fsdb_delete;
public DateAdp Pack_file_cutoff() {return pack_file_cutoff;} private DateAdp pack_file_cutoff = null;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
@ -28,10 +29,12 @@ public class Pack_file_bldr_cfg implements Gfo_invk {
else if (ctx.Match(k, Invk__pack_html_)) pack_html = m.ReadYn("v");
else if (ctx.Match(k, Invk__pack_file_)) pack_file = m.ReadYn("v");
else if (ctx.Match(k, Invk__pack_file_cutoff_)) pack_file_cutoff = m.ReadDate("v");
else if (ctx.Match(k, Invk__pack_fsdb_delete_)) pack_fsdb_delete = m.ReadYn("v");
else return Gfo_invk_.Rv_unhandled;
return this;
}
private static final String Invk__deploy_dir_ = "deploy_dir_"
, Invk__pack_html_ = "pack_html_", Invk__pack_file_ = "pack_file_", Invk__pack_file_cutoff_ = "pack_file_cutoff_"
, Invk__pack_fsdb_delete_ = "pack_fsdb_delete_"
;
}

@ -27,7 +27,7 @@ class Pack_file_mgr {
Io_url pack_dir = wiki_dir.GenSubDir_nest("tmp", "pack");
Io_mgr.Instance.DeleteDirDeep(pack_dir); Io_mgr.Instance.CreateDirIfAbsent(pack_dir);
String wiki_date = wiki.Props().Modified_latest().XtoStr_fmt("yyyy.MM");
Pack_hash hash = Pack_hash_bldr.Bld(wiki, wiki_dir, pack_dir, wiki_date, cfg.Pack_html(), cfg.Pack_file(), cfg.Pack_file_cutoff());
Pack_hash hash = Pack_hash_bldr.Bld(wiki, wiki_dir, pack_dir, wiki_date, cfg.Pack_html(), cfg.Pack_file(), cfg.Pack_file_cutoff(), cfg.Pack_fsdb_delete());
// get import_tbl
byte[] wiki_abrv = wiki.Domain_itm().Abrv_xo();
@ -51,9 +51,9 @@ class Pack_file_mgr {
// build tasks
if (cfg.Pack_html())
Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "html", Xobc_import_type.Tid__wiki__core, Xobc_import_type.Tid__wiki__srch, Xobc_import_type.Tid__wiki__html);
Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "html", Xobc_import_type.Tid__wiki__core, Xobc_import_type.Tid__wiki__srch, Xobc_import_type.Tid__wiki__html, Xobc_import_type.Tid__wiki__ctg);
if (cfg.Pack_file())
Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "file", Xobc_import_type.Tid__file__core, Xobc_import_type.Tid__file__data);
Make_task(tmp_bfr, wiki, wiki_date, bc_db, hash, "file", Xobc_import_type.Tid__file__core, Xobc_import_type.Tid__file__data); // , Xobc_import_type.Tid__fsdb__delete
bc_conn.Txn_end();
// deploy
@ -163,7 +163,7 @@ class Pack_file_mgr {
}
}
class Pack_hash_bldr {
public static Pack_hash Bld(Xow_wiki wiki, Io_url wiki_dir, Io_url pack_dir, String wiki_date, boolean pack_html, boolean pack_file, DateAdp pack_file_cutoff) {
public static Pack_hash Bld(Xow_wiki wiki, Io_url wiki_dir, Io_url pack_dir, String wiki_date, boolean pack_html, boolean pack_file, DateAdp pack_file_cutoff, boolean pack_fsdb_delete) {
Pack_hash rv = new Pack_hash();
Pack_zip_name_bldr zip_name_bldr = new Pack_zip_name_bldr(pack_dir, wiki.Domain_str(), String_.new_a7(wiki.Domain_itm().Abrv_wm()), wiki_date);
Xow_db_mgr db_mgr = wiki.Data__core_mgr();
@ -200,6 +200,13 @@ class Pack_hash_bldr {
}
}
}
// bld pack_fsdb_delete
if (pack_fsdb_delete) {
gplx.xowa.bldrs.Xob_db_file fsdb_deletion_db = gplx.xowa.bldrs.Xob_db_file.New__deletion_db(wiki);
if (!Io_mgr.Instance.ExistsFil(fsdb_deletion_db.Url())) throw Err_.new_wo_type("deletion db does not exists: url=" + fsdb_deletion_db.Url().Raw());
rv.Add(zip_name_bldr, Xobc_import_type.Tid__fsdb__delete, fsdb_deletion_db.Url());
}
return rv;
}
private static int Get_pack_tid(byte db_file_tid) {
@ -209,6 +216,9 @@ class Pack_hash_bldr {
case Xow_db_file_.Tid__search_link: return Xobc_import_type.Tid__wiki__srch;
case Xow_db_file_.Tid__html_solo:
case Xow_db_file_.Tid__html_data: return Xobc_import_type.Tid__wiki__html;
case Xow_db_file_.Tid__cat:
case Xow_db_file_.Tid__cat_core:
case Xow_db_file_.Tid__cat_link: return Xobc_import_type.Tid__wiki__ctg;
case Xow_db_file_.Tid__file_core: return Xobc_import_type.Tid__file__core;
case Xow_db_file_.Tid__file_solo:
case Xow_db_file_.Tid__file_data: return Xobc_import_type.Tid__file__data;
@ -216,20 +226,3 @@ class Pack_hash_bldr {
}
}
}
class Pack_zip_name_bldr { // en.wikipedia.org-file-ns.000-db.001.xowa -> Xowa_enwiki_2016-05_file_ns.000_db.001.zip
private final Io_url pack_dir;
private final byte[] wiki_domain, zip_name_prefix;
public Pack_zip_name_bldr(Io_url pack_dir, String wiki_domain_str, String wiki_abrv, String wiki_date) {
this.pack_dir = pack_dir;
this.wiki_domain = Bry_.new_u8(wiki_domain_str);
this.zip_name_prefix = Bry_.new_u8("Xowa_" + wiki_abrv + "_" + String_.Replace(wiki_date, ".", "-"));
}
public Io_url Bld(Io_url orig_url) {
String orig_str = String_.Replace(orig_url.NameAndExt(), ".xowa", ".zip");
byte[] orig_bry = Bry_.new_u8(orig_str);
orig_bry = Bry_.Replace(orig_bry, Byte_ascii.Dash, Byte_ascii.Underline);
orig_bry = Bry_.Replace(orig_bry, wiki_domain, zip_name_prefix);
return pack_dir.GenSubFil(String_.new_u8(orig_bry));
}
}

@ -0,0 +1,56 @@
/*
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.addons.bldrs.exports.packs.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.exports.*; import gplx.xowa.addons.bldrs.exports.packs.*;
public class Pack_zip_name_bldr { // en.wikipedia.org-file-ns.000-db.001.xowa -> Xowa_enwiki_2016-05_file_ns.000_db.001.zip
private final Io_url pack_dir;
private final byte[] wiki_domain, zip_name_prefix;
public Pack_zip_name_bldr(Io_url pack_dir, String wiki_domain_str, String wiki_abrv, String wiki_date) {
this.pack_dir = pack_dir;
this.wiki_domain = Bry_.new_u8(wiki_domain_str);
this.zip_name_prefix = Bry_.new_u8("Xowa_" + wiki_abrv + "_" + String_.Replace(wiki_date, ".", "-"));
}
public Io_url Bld(Io_url orig_url) {
String orig_str = orig_url.NameOnly() + ".zip";
byte[] orig_bry = Bry_.new_u8(orig_str);
orig_bry = Bry_.Replace(orig_bry, Byte_ascii.Dash, Byte_ascii.Underline);
orig_bry = Bry_.Replace(orig_bry, wiki_domain, zip_name_prefix);
return pack_dir.GenSubFil(String_.new_u8(orig_bry));
}
public static Io_url To_wiki_url(Io_url wiki_dir, Io_url zip_dir) {
// get wiki_url based on wiki_dir and xobc_zip_fil; EX: "/wiki/en.wikipedia.org/", "/wiki/tmp/Xowa_enwiki_2016-09_file_core_deletion_2016-09/" -> "/wiki/en.wikipedia.org-file-core-deletion-2016.09.zip"
String name_str = zip_dir.NameOnly() + ".xowa";
byte[] name_bry = Bry_.new_u8(name_str);
int pos = Bry_find__Find_fwd_idx(name_bry, Byte_ascii.Underline, 2);
name_bry = Bry_.Mid(name_bry, pos, name_bry.length);
name_bry = Bry_.Add(Bry_.new_u8(wiki_dir.NameOnly()), name_bry);
name_bry = Bry_.Replace(name_bry, Byte_ascii.Underline, Byte_ascii.Dash);
return wiki_dir.GenSubFil(String_.new_u8(name_bry));
}
private static int Bry_find__Find_fwd_idx(byte[] src, byte val, int find_max) {
int src_len = src.length;
int find_cur = 0;
int cur_pos = 0;
while (true) {
int new_pos = Bry_find_.Find_fwd(src, val, cur_pos, src_len);
if (new_pos == -1) throw Err_.New("failed to find value; src={0} val={1}", src, val);
if (find_cur++ == find_max) return new_pos;
cur_pos = new_pos + 1;
}
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.exports.packs.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.exports.*; import gplx.xowa.addons.bldrs.exports.packs.*;
import org.junit.*; import gplx.core.tests.*;
public class Pack_zip_name_bldr__tst {
private Pack_zip_name_bldr__fxt fxt = new Pack_zip_name_bldr__fxt();
@Test public void Basic() {
fxt.Test__to_wiki_url("mem/wiki/en.wikipedia.org/", "mem/wiki/en.wikipedia.org/tmp/Xowa_enwiki_2016-09_file_deletion_2016.09/", "mem/wiki/en.wikipedia.org/en.wikipedia.org-file-deletion-2016.09.xowa");
}
}
class Pack_zip_name_bldr__fxt {
public void Test__to_wiki_url(String wiki_dir, String zip_fil, String expd) {
Gftest.Eq__str(expd, Pack_zip_name_bldr.To_wiki_url(Io_url_.mem_fil_(wiki_dir), Io_url_.mem_dir_(zip_fil)).Raw(), "wiki_url");
}
}

@ -47,7 +47,7 @@ class Split_meta_wkr__fil extends Split_meta_wkr_base {
);
}
@Override protected Object Load_itm(Db_rdr rdr) {
return tbl.Load_by_rdr__full(Fsm_mnt_mgr.Mnt_idx_main, rdr);
return tbl.New_by_rdr(Fsm_mnt_mgr.Mnt_idx_main, rdr);
}
@Override protected void Save_itm(Split_ctx ctx, Split_rslt_mgr rslt_mgr, Object itm_obj) {
Fsd_fil_itm itm = (Fsd_fil_itm)itm_obj;

@ -185,7 +185,7 @@ public class Xobldr__fsdb_db__create_data extends Xob_cmd__base implements Xob_c
tier_id_val = fsdb.Lnki_tier_id();
page_id_val = fsdb.Lnki_page_id();
lnki_id_val = fsdb.Lnki_id();
fsdb.Orig_repo_name_(fsdb.Orig_repo_id() == Xof_repo_itm_.Repo_local ? wiki.Domain_bry() : Xow_domain_itm_.Bry__commons);
fsdb.Orig_repo_name_(fsdb.Orig_repo_id() == Xof_repo_tid_.Tid__local ? wiki.Domain_bry() : Xow_domain_itm_.Bry__commons);
Download_exec(fsdb);
++exec_count;
if (exec_count % progress_interval == 0) Print_progress(fsdb);

@ -17,16 +17,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.files.cmds; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.files.*;
import gplx.dbs.*; import gplx.core.ios.*; import gplx.xowa.files.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sqls.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sql_dumps.*;
import gplx.xowa.addons.bldrs.files.dbs.*;
public class Xobldr__image__create extends Xob_itm_dump_base implements Xob_cmd, Gfo_invk, Sql_file_parser_cmd {
public class Xobldr__image__create extends Xob_itm_dump_base implements Xob_cmd, Gfo_invk, Xosql_dump_cbk {
private Xosql_dump_parser parser;
private Db_conn conn = null; private Db_stmt stmt = null;
private Xob_image_tbl tbl_image = new Xob_image_tbl();
private byte[] cur_ttl, cur_media_type, cur_minor_mime, cur_timestamp; private int cur_size, cur_width, cur_height, cur_bits, cur_ext_id;
private int commit_count = 10000;
public Xobldr__image__create(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);}
public Xobldr__image__create(Xob_bldr bldr, Xowe_wiki wiki) {
this.parser = new Xosql_dump_parser(this, "img_name", "img_size", "img_width", "img_height", "img_bits", "img_media_type", "img_minor_mime", "img_timestamp");
this.Cmd_ctor(bldr, wiki);
}
public Io_url Src_fil() {return src_fil;} public Xobldr__image__create Src_fil_(Io_url v) {src_fil = v; return this;} private Io_url src_fil;
public Sql_file_parser Parser() {return parser;} private Sql_file_parser parser = new Sql_file_parser();
public Xosql_dump_parser Parser() {return parser;}
public void Cmd_init(Xob_bldr bldr) {}
public void Cmd_bgn(Xob_bldr bldr) {
wiki.Init_assert(); // NOTE: must init wiki for db_mgr_as_sql
@ -35,7 +39,7 @@ public class Xobldr__image__create extends Xob_itm_dump_base implements Xob_cmd,
src_fil = Xob_page_wkr_cmd.Find_fil_by(wiki.Fsys_mgr().Root_dir(), "*-image.sql");
if (src_fil == null) throw Err_.new_wo_type(".sql file not found in dir", "dir", wiki.Fsys_mgr().Root_dir());
}
parser.Src_fil_(src_fil).Trg_fil_gen_(dump_url_gen).Fld_cmd_(this).Flds_req_idx_(20, Fld_img_name, Fld_img_size, Fld_img_width, Fld_img_height, Fld_img_bits, Fld_img_media_type, Fld_img_minor_mime, Fld_img_timestamp);
parser.Src_fil_(src_fil);
this.conn = Xob_db_file.New__wiki_image(wiki.Fsys_mgr().Root_dir()).Conn();
conn.Txn_bgn("bldr__image");
this.tbl_image = new Xob_image_tbl();
@ -47,16 +51,16 @@ public class Xobldr__image__create extends Xob_itm_dump_base implements Xob_cmd,
tbl_image.Create_index(conn);
conn.Txn_end();
}
public void Exec(byte[] src, byte[] fld_key, int fld_idx, int fld_bgn, int fld_end, Bry_bfr file_bfr, Sql_file_parser_data data) {
public void On_fld_done(int fld_idx, byte[] src, int val_bgn, int val_end) {
switch (fld_idx) {
case Fld_img_name: cur_ttl = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld_img_size: cur_size = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld_img_width: cur_width = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld_img_height: cur_height = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld_img_bits: cur_bits = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld_img_media_type: cur_media_type = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld_img_minor_mime: cur_minor_mime = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld_img_timestamp: cur_timestamp = Bry_.Mid(src, fld_bgn, fld_end);
case Fld_img_name: cur_ttl = Bry_.Mid(src, val_bgn, val_end); break;
case Fld_img_size: cur_size = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld_img_width: cur_width = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld_img_height: cur_height = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld_img_bits: cur_bits = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld_img_media_type: cur_media_type = Bry_.Mid(src, val_bgn, val_end); break;
case Fld_img_minor_mime: cur_minor_mime = Bry_.Mid(src, val_bgn, val_end); break;
case Fld_img_timestamp: cur_timestamp = Bry_.Mid(src, val_bgn, val_end);
cur_ext_id = Calc_ext_id(show_issues ? app.Usr_dlg() : Gfo_usr_dlg_.Noop, cur_ttl, cur_media_type, cur_minor_mime, cur_width, cur_height);
tbl_image.Insert(stmt, cur_ttl, cur_media_type, cur_minor_mime, cur_size, cur_width, cur_height, cur_bits, cur_ext_id, cur_timestamp);
++commit_count;
@ -70,7 +74,8 @@ public class Xobldr__image__create extends Xob_itm_dump_base implements Xob_cmd,
public void Cmd_end() {}
public void Cmd_term() {}
private boolean show_issues = true;
private static final int Fld_img_name = 0, Fld_img_size = 1, Fld_img_width = 2, Fld_img_height = 3, Fld_img_bits = 5, Fld_img_media_type = 6, Fld_img_minor_mime = 8, Fld_img_timestamp = 12;
private static final int Fld_img_name = 0, Fld_img_size = 1, Fld_img_width = 2, Fld_img_height = 3, Fld_img_bits = 4, Fld_img_media_type = 5, Fld_img_minor_mime = 6, Fld_img_timestamp = 7;
// Fld_img_name = 0, Fld_img_size = 1, Fld_img_width = 2, Fld_img_height = 3, Fld_img_bits = 5, Fld_img_media_type = 6, Fld_img_minor_mime = 8, Fld_img_timestamp = 12;
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_src_fil_)) src_fil = m.ReadIoUrl("v");
else if (ctx.Match(k, Invk_show_issues_)) show_issues = m.ReadYn("v");

@ -28,14 +28,14 @@ public class Xobldr__page_regy__create extends Xob_cmd__base {
commons_wiki.Init_assert();
if (build_commons) {
Xob_page_regy_tbl.Reset_table(page_regy_provider);
Xob_page_regy_tbl.Create_data(bldr.Usr_dlg(), page_regy_provider, Xof_repo_itm_.Repo_remote, commons_wiki);
Xob_page_regy_tbl.Create_data(bldr.Usr_dlg(), page_regy_provider, Xof_repo_tid_.Tid__remote, commons_wiki);
Sqlite_engine_.Idx_create(usr_dlg, page_regy_provider, "repo_page", Xob_page_regy_tbl.Idx_main);
}
else {
if (!Bry_.Eq(commons_wiki.Domain_bry(), wiki.Domain_bry())) { // skip local wiki if cur wiki is commons
wiki.Init_assert();
Xob_page_regy_tbl.Delete_local(page_regy_provider);
Xob_page_regy_tbl.Create_data(bldr.Usr_dlg(), page_regy_provider, Xof_repo_itm_.Repo_local, wiki);
Xob_page_regy_tbl.Create_data(bldr.Usr_dlg(), page_regy_provider, Xof_repo_tid_.Tid__local, wiki);
}
}
}

@ -29,7 +29,7 @@ public class Xob_orig_regy_tbl {
Sqlite_engine_.Idx_create(usr_dlg, p, "orig_regy", Idx_ttl_local);
Sqlite_engine_.Db_attach(p, "page_db", file_registry_db.Url().Raw());
Io_url repo_0_dir = repo_0_wiki.Fsys_mgr().Root_dir(), repo_1_dir = repo_1_wiki.Fsys_mgr().Root_dir();
byte repo_0_tid = Xof_repo_itm_.Repo_local, repo_1_tid = Xof_repo_itm_.Repo_remote;
byte repo_0_tid = Xof_repo_tid_.Tid__local, repo_1_tid = Xof_repo_tid_.Tid__remote;
boolean local_is_remote = Bry_.Eq(repo_0_wiki.Domain_bry(), repo_1_wiki.Domain_bry());
Xowe_wiki local_wiki = repo_0_wiki;
if ( repo_0_is_remote // .gfs manually marked specifes repo_0 as remote
@ -37,8 +37,8 @@ public class Xob_orig_regy_tbl {
&& local_is_remote // repo_0 = repo_1
)
) {
repo_0_tid = Xof_repo_itm_.Repo_remote;
repo_1_tid = Xof_repo_itm_.Repo_local;
repo_0_tid = Xof_repo_tid_.Tid__remote;
repo_1_tid = Xof_repo_tid_.Tid__local;
local_wiki = repo_1_wiki;
}
Create_data_for_repo(usr_dlg, p, local_wiki, Byte_.By_int(repo_0_tid), repo_0_dir.GenSubFil(Xob_db_file.Name__wiki_image));
@ -54,18 +54,18 @@ public class Xob_orig_regy_tbl {
}
private static void Create_data_for_repo(Gfo_usr_dlg usr_dlg, Db_conn conn, Xowe_wiki local_wiki, byte repo_tid, Io_url join) {
usr_dlg.Note_many("", "", "inserting page for xowa.wiki.image: ~{0}", join.OwnerDir().NameOnly());
boolean wiki_has_cs_file = repo_tid == Xof_repo_itm_.Repo_remote && local_wiki.Ns_mgr().Ns_file().Case_match() == Xow_ns_case_.Tid__all;
boolean wiki_has_cs_file = repo_tid == Xof_repo_tid_.Tid__remote && local_wiki.Ns_mgr().Ns_file().Case_match() == Xow_ns_case_.Tid__all;
String lnki_ttl_fld = wiki_has_cs_file ? "Coalesce(o.lnki_commons_ttl, o.lnki_ttl)" : "o.lnki_ttl"; // NOTE: use lnki_commons_ttl if [[File]] is cs PAGE:en.d:water EX:[[image:wikiquote-logo.png|50px|none|alt=]]; DATE:2014-09-05
if (wiki_has_cs_file)
Sqlite_engine_.Idx_create(usr_dlg, conn, "orig_regy", Idx_ttl_remote);
new Db_attach_mgr(conn, new Db_attach_itm("image_db", join))
.Exec_sql_w_msg("orig_regy:updating page" , Sql_update_repo_page, repo_tid, lnki_ttl_fld)
.Exec_sql_w_msg("orig_regy:updating redirect" , Sql_update_repo_redirect, repo_tid, lnki_ttl_fld);
.Exec_sql_w_msg("orig_regy:updating page" , Sql_update_repo_page , repo_tid, lnki_ttl_fld)
.Exec_sql_w_msg("orig_regy:updating redirect" , Sql_update_repo_redirect , repo_tid, lnki_ttl_fld);
}
private static void Create_data_for_cs(Gfo_usr_dlg usr_dlg, Db_conn p, Xowe_wiki local_wiki, Io_url repo_remote_dir) {
p.Exec_sql(Xob_orig_regy_tbl.Sql_cs_mark_dupes); // orig_regy: find dupes; see note in SQL
p.Exec_sql(Xob_orig_regy_tbl.Sql_cs_update_ttls); // orig_regy: update lnki_ttl with lnki_commons_ttl
Create_data_for_repo(usr_dlg, p, local_wiki, Xof_repo_itm_.Repo_remote, repo_remote_dir.GenSubFil(Xob_db_file.Name__wiki_image));
Create_data_for_repo(usr_dlg, p, local_wiki, Xof_repo_tid_.Tid__remote, repo_remote_dir.GenSubFil(Xob_db_file.Name__wiki_image));
p.Exec_sql(Xob_lnki_regy_tbl.Sql_cs_mark_changed); // lnki_regy: update lnki_commons_flag
p.Exec_sql(Xob_lnki_regy_tbl.Sql_cs_update_ttls); // lnki_regy: update cs
}

@ -26,7 +26,7 @@ public class Xob_page_regy_tbl {
Create_data__insert_redirect(usr_dlg, p, repo_tid, wiki.Fsys_mgr().Root_dir().GenSubFil(Xob_db_file.Name__wiki_redirect));
}
public static void Delete_local(Db_conn p) {
p.Exec_sql("DELETE FROM page_regy WHERE repo_id = " + Xof_repo_itm_.Repo_local);
p.Exec_sql("DELETE FROM page_regy WHERE repo_id = " + Xof_repo_tid_.Tid__local);
}
private static void Create_data__insert_page(Gfo_usr_dlg usr_dlg, Db_conn cur, byte repo_tid, Io_url join) {
usr_dlg.Note_many("", "", "inserting page: ~{0}", join.NameOnly());

@ -41,7 +41,8 @@ public class Xob_bin_db_mgr {
Xob_bin_db_itm itm = schema_is_1 ? Xob_bin_db_itm.new_v1(fil) : Xob_bin_db_itm.new_v2(fil);
int ns_id = itm.Ns_id();
Xob_bin_db_itm nth = (Xob_bin_db_itm)nth_hash.Get_by(tier_key.Val_(ns_id));
if (itm.Pt_id() > nth.Pt_id()) // update max pt_id
if ( nth != null // occurs when existing fsdb_dbb has "file-ns.014-db.001", but 14 no longer specified in fsdb_make; DATE:2016-09-23
&& itm.Pt_id() > nth.Pt_id()) // update max pt_id
nth.Set(itm.Id(), itm.Pt_id(), itm.Db_url()); // note that ns_id is same
}
len = nth_hash.Count();

@ -134,7 +134,7 @@ class Xob_xfer_temp_itm_fxt {
public Xob_xfer_temp_itm_fxt Init_rdr_image() {
GfoFldList flds = GfoFldList_.str_(Flds);
nde = GfoNde_.vals_(flds, Object_.Ary
( Xof_ext_.Id_png, 1, 1, Xof_repo_itm_.Repo_remote
( Xof_ext_.Id_png, 1, 1, Xof_repo_tid_.Tid__remote
, "A.png", Xof_ext_.Id_png, "A.png", Xop_lnki_type.Id_thumb, Xop_file_logger_.Tid__file
, 220, 200, 1, 2, 440, 400, 3
, Xop_lnki_tkn.Upright_null, Xof_lnki_time.Null, Xof_lnki_page.Null

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.mass_parses.dbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*;
import gplx.dbs.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*;
import gplx.xowa.addons.bldrs.mass_parses.parses.pools.*; import gplx.xowa.addons.bldrs.mass_parses.parses.locks.*;
public class Xomp_mgr_db {
public Xomp_mgr_db(Io_url url) {
@ -24,18 +24,20 @@ public class Xomp_mgr_db {
this.conn = Db_conn_bldr.Instance.Get_or_autocreate(true, url);
this.page_tbl = new Xomp_page_tbl(conn);
this.wkr_tbl = new Xomp_wkr_tbl(conn);
this.cfg_tbl = new Db_cfg_tbl(conn, "xowa_cfg");
// this.lock_mgr = new Xomp_lock_mgr__db(conn, 5000);
this.lock_mgr = new Xomp_lock_mgr__fsys(5000, this.Dir());
}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public Io_url Url() {return url;} private final Io_url url;
public Io_url Dir() {return url.OwnerDir();}
public Xomp_page_tbl Page_tbl() {return page_tbl;} private final Xomp_page_tbl page_tbl;
public Xomp_wkr_tbl Wkr_tbl() {return wkr_tbl;} private final Xomp_wkr_tbl wkr_tbl;
public Xomp_lock_mgr Lock_mgr() {return lock_mgr;} private final Xomp_lock_mgr lock_mgr;
public Db_conn Conn() {return conn;} private final Db_conn conn;
public Io_url Url() {return url;} private final Io_url url;
public Io_url Dir() {return url.OwnerDir();}
public Xomp_page_tbl Tbl__page() {return page_tbl;} private final Xomp_page_tbl page_tbl;
public Xomp_wkr_tbl Tbl__wkr() {return wkr_tbl;} private final Xomp_wkr_tbl wkr_tbl;
public Db_cfg_tbl Tbl__cfg() {return cfg_tbl;} private final Db_cfg_tbl cfg_tbl;
public Xomp_lock_mgr Lock_mgr() {return lock_mgr;} private final Xomp_lock_mgr lock_mgr;
public void Remake() {
conn.Meta_tbl_remake_many(page_tbl, wkr_tbl);
conn.Meta_tbl_remake_many(page_tbl, wkr_tbl, cfg_tbl);
lock_mgr.Remake();
}

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.mass_parses.inits; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*;
import gplx.dbs.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*;
import gplx.xowa.bldrs.*;
import gplx.xowa.addons.bldrs.mass_parses.parses.*; import gplx.xowa.addons.bldrs.mass_parses.dbs.*;
class Xomp_init_mgr {
@ -27,9 +27,12 @@ class Xomp_init_mgr {
Xomp_mgr_db mgr_db = Xomp_mgr_db.New__make(wiki);
Db_conn mgr_conn = mgr_db.Conn();
// remake all
// remake all tbls
mgr_db.Remake();
// insert ns into cfg; need for lnki_temp.tier in xomp.make
mgr_db.Tbl__cfg().Insert_str("", gplx.xowa.addons.bldrs.mass_parses.parses.wkrs.Xomp_parse_wkr.Cfg__ns_ids, Int_.Ary_concat("|", cfg.Ns_ids()));
// fill page tbl
Db_attach_mgr attach_mgr = new Db_attach_mgr(mgr_conn, new Db_attach_itm("page_db", wiki.Data__core_mgr().Db__core().Conn()));
int[] ns_ary = cfg.Ns_ids();

@ -23,7 +23,7 @@ class Xomp_html_db_rdr {
private final Xomp_mgr_db mgr_db;
public Xomp_html_db_rdr(Xowe_wiki wiki) {
this.mgr_db = Xomp_mgr_db.New__load(wiki);
this.src_tbls = new Xowd_html_tbl[mgr_db.Wkr_tbl().Select_count()];
this.src_tbls = new Xowd_html_tbl[mgr_db.Tbl__wkr().Select_count()];
}
public void Rows__get(Xowd_html_row rv, int wkr_uid, int page_id) {
Xowd_html_tbl src_tbl = src_tbls[wkr_uid];

@ -17,11 +17,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.mass_parses.makes; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*;
import gplx.dbs.*; import gplx.xowa.htmls.core.dbs.*; import gplx.xowa.wikis.data.*;
import gplx.xowa.bldrs.cmds.*;
class Xomp_html_db_wtr {
private final long len_max;
private final Xowe_wiki wiki; private final Xow_db_mgr db_mgr;
private long len_cur;
private int prv_ns_id = -1;
private Xow_db_file html_db; private Xowd_html_tbl html_tbl;
private Xob_ns_file_itm ns_itm;
public Xomp_html_db_wtr(Xowe_wiki wiki) {
this.wiki = wiki; this.db_mgr = wiki.Data__core_mgr();
this.len_max = wiki.Appe().Api_root().Bldr().Wiki().Import().Html_db_max();
@ -34,18 +37,19 @@ class Xomp_html_db_wtr {
public Xowd_html_tbl Tbls__get_or_new(int ns_id, long html_len) {
long len_new = len_cur + html_len;
boolean not_inited = html_tbl == null, out_of_space = len_new > len_max;
if (not_inited || out_of_space) {
if (out_of_space)
Commit();
if ( db_mgr.Props().Layout_html().Tid_is_all_or_few() // is not "lot"
&& not_inited // not_inited; set html_db
boolean is_all_or_few = db_mgr.Props().Layout_html().Tid_is_all_or_few();
boolean ns_changed = ns_id != prv_ns_id;
if (not_inited || out_of_space || ns_changed) {
Commit();
if ( is_all_or_few // is not "lot"
&& not_inited // not_inited; set html_db
) {
this.html_db = wiki.Data__core_mgr().Dbs__get_by_tid_or_null(Xow_db_file_.Tid__html_data);
if (html_db == null)
this.html_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__html_data);
Make_html_db(is_all_or_few, ns_id);
}
else
this.html_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__html_data);
Make_html_db(is_all_or_few, ns_id);
this.html_tbl = new Xowd_html_tbl(html_db.Conn());
html_tbl.Create_tbl();
@ -56,10 +60,20 @@ class Xomp_html_db_wtr {
len_cur = len_new;
return html_tbl;
}
private void Make_html_db(boolean is_all_or_few, int ns_id) {
if (prv_ns_id != ns_id
|| ns_itm == null) {
prv_ns_id = ns_id;
ns_itm = new Xob_ns_file_itm(Xow_db_file_.Tid__html_data, "ns." + Int_.To_str_pad_bgn_zero(ns_id, 3), Int_.Ary(ns_id));
}
String file_name = is_all_or_few ? "-html.xowa" : ns_itm.Make_file_name();
this.html_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__html_data, Int_.To_str(ns_id), ns_itm.Nth_db_idx(), file_name);
}
public void Rls() {
this.Commit();
}
private void Commit() {
if (html_tbl == null) return;
html_tbl.Conn().Txn_end();
html_tbl.Conn().Rls_conn();

@ -26,10 +26,10 @@ class Xomp_make_html {
Db_conn mgr_conn = mgr_db.Conn();
// update wkr_uid; note that this cannot be done in parse_wkr, b/c multiple-writer-errors for xomp.db|page
int wkrs_len = mgr_db.Wkr_tbl().Select_count();
int wkrs_len = mgr_db.Tbl__wkr().Select_count();
for (int i = 0; i < wkrs_len; ++i) {
Xomp_wkr_db wkr_db = Xomp_wkr_db.New(mgr_db.Dir(), i);
mgr_db.Page_tbl().Update_wkr_uid(i, wkr_db.Conn());
mgr_db.Tbl__page().Update_wkr_uid(i, wkr_db.Conn());
}
// init more

@ -30,7 +30,7 @@ class Xomp_make_lnki {
lnki_temp_tbl.Insert_bgn();
// create ary; add index
int wkr_count = xomp_db.Wkr_tbl().Select_count();
int wkr_count = xomp_db.Tbl__wkr().Select_count();
Xomp_wkr_db[] db_ary = new Xomp_wkr_db[wkr_count];
for (int i = 0; i < wkr_count; ++i) {
Xomp_wkr_db wkr_db = Xomp_wkr_db.New(xomp_db.Dir(), i);

@ -51,10 +51,13 @@ public class Xomp_parse_mgr {
// assert wkr_tbl
int wkr_len = cfg.Num_wkrs();
int wkr_uid_bgn = mgr_db.Wkr_tbl().Init_wkrs(cfg.Wkr_machine_name(), wkr_len);
int wkr_uid_bgn = mgr_db.Tbl__wkr().Init_wkrs(cfg.Wkr_machine_name(), wkr_len);
latch = new Gfo_countdown_latch(wkr_len);
Xomp_parse_wkr[] wkrs = new Xomp_parse_wkr[wkr_len];
// init ns_ord_mgr
Xomp_ns_ord_mgr ns_ord_mgr = new Xomp_ns_ord_mgr(Int_.Ary_parse(mgr_db.Tbl__cfg().Select_str("", Xomp_parse_wkr.Cfg__ns_ids), "|"));
// init parse_wkrs
for (int i = 0; i < wkr_len; ++i) {
// make wiki
@ -62,7 +65,7 @@ public class Xomp_parse_mgr {
wkr_wiki.Cache_mgr().Page_cache_(page_cache).Commons_cache_(commons_cache).Ifexist_cache_(ifexist_cache);
// make wkr
Xomp_parse_wkr wkr = new Xomp_parse_wkr(this, cfg, mgr_db, page_pool, prog_mgr, file_orig_wkr, wkr_wiki, i + wkr_uid_bgn);
Xomp_parse_wkr wkr = new Xomp_parse_wkr(this, cfg, mgr_db, page_pool, prog_mgr, file_orig_wkr, ns_ord_mgr, wkr_wiki, i + wkr_uid_bgn);
wkrs[i] = wkr;
}

@ -0,0 +1,29 @@
/*
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.addons.bldrs.mass_parses.parses.utls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.mass_parses.*; import gplx.xowa.addons.bldrs.mass_parses.parses.*;
import gplx.core.primitives.*; import gplx.core.lists.hashs.*;
public class Xomp_ns_ord_mgr {
private final Hash_adp__int hash = new Hash_adp__int();
public Xomp_ns_ord_mgr(int[] ns_id_ary) {
int len = ns_id_ary.length;
for (int i = 0; i < len; ++i) {
hash.Add(ns_id_ary[i], new Int_obj_val(i));
}
}
public int Get_ord_by_ns_id(int ns_id) {return ((Int_obj_val)hash.Get_by_or_fail(ns_id)).Val();}
}

@ -28,6 +28,7 @@ public class Xomp_parse_wkr implements Gfo_invk {
private final Xomp_prog_mgr prog_mgr;
private final Xomp_page_pool page_pool;
private final Xof_orig_wkr file_orig_wkr;
private final Xomp_ns_ord_mgr ns_ord_mgr;
// cfg vars
private final Xomp_parse_mgr_cfg cfg;
@ -42,10 +43,11 @@ public class Xomp_parse_wkr implements Gfo_invk {
private final List_adp list = List_adp_.New(); private int list_idx = 0, list_len = 0;
private int done_count; private long done_time;
public Xomp_parse_wkr(Xomp_parse_mgr mgr, Xomp_parse_mgr_cfg cfg, Xomp_mgr_db mgr_db, Xomp_page_pool page_pool, Xomp_prog_mgr prog_mgr, Xof_orig_wkr file_orig_wkr, Xowe_wiki wiki, int uid) {
public Xomp_parse_wkr(Xomp_parse_mgr mgr, Xomp_parse_mgr_cfg cfg, Xomp_mgr_db mgr_db, Xomp_page_pool page_pool, Xomp_prog_mgr prog_mgr, Xof_orig_wkr file_orig_wkr, Xomp_ns_ord_mgr ns_ord_mgr, Xowe_wiki wiki, int uid) {
// mgr vars
this.mgr = mgr; this.mgr_db = mgr_db;
this.page_pool = page_pool; this.prog_mgr = prog_mgr; this.file_orig_wkr = file_orig_wkr;
this.ns_ord_mgr = ns_ord_mgr;
// cfg vars
this.cfg = cfg;
@ -67,7 +69,7 @@ public class Xomp_parse_wkr implements Gfo_invk {
wiki.File__orig_mgr().Wkrs__set(file_orig_wkr);
wiki.File_mgr().Fsdb_mode().Tid__v2__mp__y_();
// disable categories b/c categories will be retrieved at run-time
// enable disable categories according to flag
wiki.Html_mgr().Page_wtr_mgr().Wkr(gplx.xowa.wikis.pages.Xopg_page_.Tid_read).Ctgs_enabled_(cfg.Hdump_catboxs());
// enable lnki_temp
@ -84,14 +86,15 @@ public class Xomp_parse_wkr implements Gfo_invk {
wkr_db.Conn().Txn_bgn("xomp");
// set status to running
mgr_db.Wkr_tbl().Update_status(uid, Xomp_wkr_tbl.Status__running);
mgr_db.Tbl__wkr().Update_status(uid, Xomp_wkr_tbl.Status__running);
// main loop
int prv_ns = -1;
while (true) {
// get page from page pool
Xomp_page_itm ppg = Get_next();
if (ppg == Xomp_page_itm.Null) {
mgr_db.Wkr_tbl().Update_status(uid, Xomp_wkr_tbl.Status__sleeping);
mgr_db.Tbl__wkr().Update_status(uid, Xomp_wkr_tbl.Status__sleeping);
break; // no more pages
}
if (ppg.Text() == null) continue; // some pages have no text; ignore them else null ref; PAGE: it.d:miercuri DATE:2015-12-05
@ -99,8 +102,16 @@ public class Xomp_parse_wkr implements Gfo_invk {
try {
// init page
long done_bgn = gplx.core.envs.System_.Ticks();
Xoa_ttl ttl = wiki.Ttl_parse(ppg.Ns_id(), ppg.Ttl_bry());
int cur_ns = ppg.Ns_id();
Xoa_ttl ttl = wiki.Ttl_parse(cur_ns, ppg.Ttl_bry());
// if ns changed and prv_ns is main
if (cur_ns != prv_ns) {
if (prv_ns == gplx.xowa.wikis.nss.Xow_ns_.Tid__main)
wiki.Cache_mgr().Free_mem_all(Bool_.Y); // NOTE: this clears all caches, include imglinks
prv_ns = cur_ns;
}
Xoae_page wpg = Xoae_page.New(wiki, ttl);
wpg.Bldr__ns_ord_(ns_ord_mgr.Get_ord_by_ns_id(cur_ns)); // NOTE: must set ns_id for tier_id in lnki_temp; DATE:2016-09-19
wpg.Db().Text().Text_bry_(ppg.Text());
wpg.Db().Page().Id_(ppg.Id());
@ -153,7 +164,7 @@ public class Xomp_parse_wkr implements Gfo_invk {
}
private Xomp_page_itm Get_next() {
if (list_idx == list_len) {
mgr_db.Wkr_tbl().Update_exec(uid, done_count, done_time);
mgr_db.Tbl__wkr().Update_exec(uid, done_count, done_time);
list.Clear();
page_pool.Get_next(mgr_db, cfg.Wkr_machine_name(), list);
list_len = list.Len();
@ -168,4 +179,5 @@ public class Xomp_parse_wkr implements Gfo_invk {
return this;
}
public static final String Invk__exec = "exec";
public static final String Cfg__ns_ids = "xomp.ns_ids";
}

@ -1,139 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*;
import gplx.fsdb.*; import gplx.fsdb.meta.*; import gplx.xowa.files.fsdb.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
import gplx.xowa.addons.bldrs.files.cmds.*;
public class Xobldr__deletion_db__exec extends Xob_cmd__base {
private Io_url deletion_db_url;
public Xobldr__deletion_db__exec(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, null);}
@Override public void Cmd_run() {
if (deletion_db_url == null) throw Err_.new_("bldr", "no file specified");
Db_conn conn = Db_conn_bldr.Instance.Get_or_noop(deletion_db_url);
if (conn == Db_conn_.Noop) throw Err_.new_("bldr", "file does not exist", "file", deletion_db_url.Raw());
Db_cfg_tbl cfg_tbl = gplx.xowa.wikis.data.Xowd_cfg_tbl_.Get_or_null(conn);
if (cfg_tbl == null) throw Err_.new_("bldr", "xowa_cfg tbl does not exist", "file", deletion_db_url.Raw());
byte[] domain_bry = cfg_tbl.Select_bry_or("", Xobldr__deletion_db__make.Cfg__deletion_db__domain, null);
if (domain_bry == null) throw Err_.new_("bldr", "no domain found in deletion db", "file", deletion_db_url.Raw());
this.wiki = bldr.App().Wiki_mgr().Get_by_or_make(domain_bry);
wiki.Init_assert();
Delete_by_url(wiki, deletion_db_url);
conn.Rls_conn();
Io_mgr.Instance.DeleteFil(deletion_db_url);
}
private void Delete_by_url(Xowe_wiki wiki, Io_url delete_url) {
Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr();
Fsm_mnt_itm mnt_itm = fsdb_mgr.Mnt_mgr().Mnts__get_main();
Db_conn core_conn = mnt_itm.Atr_mgr().Db__core().Conn();
Db_conn delete_conn = Db_conn_bldr.Instance.Get_or_new(delete_url).Conn();
core_conn.Env_db_attach("delete_db", delete_conn);
int dbs_len = mnt_itm.Bin_mgr().Dbs__len();
String dbs_len_str = Int_.To_str(dbs_len - Int_.Base1);
for (int i = 0; i < dbs_len; ++i) {
Fsm_bin_fil bin_db = mnt_itm.Bin_mgr().Dbs__get_at(i);
Delete_by_db(core_conn, bin_db, dbs_len_str);
}
core_conn.Env_db_detach("delete_db");
}
private void Delete_by_db(Db_conn conn, Fsm_bin_fil bin_db, String dbs_len_str) {
Gfo_usr_dlg usr_dlg = Xoa_app_.Usr_dlg();
// get rows to delete in db
List_adp list = List_adp_.New();
int bin_db_id = bin_db.Id();
String bin_db_id_str = Int_.To_str(bin_db_id);
usr_dlg.Prog_many("", "", "processing files for deletion in database " + bin_db_id_str + " of " + dbs_len_str);
Db_rdr rdr = conn.Exec_rdr(String_.Concat_lines_nl
( "SELECT ff.fil_id AS item_id"
, ", 1 AS item_is_orig"
, "FROM fsdb_fil ff"
, "JOIN delete_db.delete_regy dr ON ff.fil_id = dr.fil_id AND dr.thm_id = -1"
, "WHERE ff.fil_bin_db_id = " + bin_db_id_str
, "UNION"
, "SELECT ft.thm_id AS item_id"
, ", 0 AS item_is_orig"
, "FROM fsdb_thm ft"
, " JOIN delete_db.delete_regy dr ON ft.thm_owner_id = dr.fil_id AND ft.thm_id = dr.thm_id"
, "WHERE ft.thm_bin_db_id = " + bin_db_id_str
));
try {
while (rdr.Move_next()) {
int item_id = rdr.Read_int("item_id");
int item_is_orig = rdr.Read_int("item_is_orig");
list.Add(new Xob_img_prune_itm(item_id, item_is_orig == 1));
}
} finally {rdr.Rls();}
int len = list.Count();
if (len == 0) return; // no files; exit, else will vacuum below
conn.Env_db_attach("bin_db", bin_db.Conn());
conn.Txn_bgn("img_prune__" + bin_db_id_str);
// delete bin
Db_stmt delete_bin_stmt = conn.Stmt_sql("DELETE FROM bin_db.fsdb_bin WHERE bin_owner_id = ?");
for (int i = 0; i < len; ++i) {
Xob_img_prune_itm itm = (Xob_img_prune_itm)list.Get_at(i);
delete_bin_stmt.Clear().Crt_int("bin_owner_id", itm.Item_id);
delete_bin_stmt.Exec_delete();
if (i % 10000 == 0) usr_dlg.Prog_many("", "", "deleting data in database " + bin_db_id_str + " of " + dbs_len_str);
}
delete_bin_stmt.Rls();
// delete meta
Db_stmt delete_fil_stmt = conn.Stmt_sql("DELETE FROM fsdb_fil WHERE fil_id = ?");
Db_stmt delete_thm_stmt = conn.Stmt_sql("DELETE FROM fsdb_thm WHERE thm_id = ?");
for (int i = 0; i < len; ++i) {
Xob_img_prune_itm itm = (Xob_img_prune_itm)list.Get_at(i);
if (itm.Item_is_orig) {
delete_fil_stmt.Clear().Crt_int("fil_id", itm.Item_id);
delete_fil_stmt.Exec_delete();
}
else {
delete_thm_stmt.Clear().Crt_int("thm_id", itm.Item_id);
delete_thm_stmt.Exec_delete();
}
if (i % 10000 == 0) usr_dlg.Prog_many("", "", "deleting meta in database " + bin_db_id_str + " of " + dbs_len_str);
}
delete_fil_stmt.Rls();
delete_thm_stmt.Rls();
conn.Txn_end();
conn.Env_db_detach("bin_db");
bin_db.Conn().Env_vacuum();
}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk__file_)) this.deletion_db_url = Io_url_.new_any_(m.ReadStr("v"));
else return Gfo_invk_.Rv_unhandled;
return this;
} private static final String Invk__file_ = "file_";
public static final String BLDR_CMD_KEY = "fsdb.deletion_db.exec";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}
public static final Xob_cmd Prototype = new Xobldr__deletion_db__exec(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xobldr__deletion_db__exec(bldr, wiki);}
}
class Xob_img_prune_itm {
public Xob_img_prune_itm(int item_id, boolean item_is_orig) {
this.Item_id = item_id;
this.Item_is_orig = item_is_orig;
}
public final int Item_id;
public final boolean Item_is_orig;
}

@ -18,12 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.xowa.bldrs.wkrs.*;
import gplx.xowa.addons.bldrs.utils_rankings.bldrs.*;
public class Xoax_updates_files_addon implements Xoax_addon_itm, Xoax_addon_itm__bldr {
public class Xodel_addon implements Xoax_addon_itm, Xoax_addon_itm__bldr {
public Xob_cmd[] Bldr_cmds() {
return new Xob_cmd[]
{ Xobldr__deletion_db__make.Prototype
, Xobldr__deletion_db__exec.Prototype
, Xobldr__deletion_db__small_files.Prototype
{ Xodel_make_cmd.Prototype
, Xodel_exec_cmd.Prototype
, Xodel_small_cmd.Prototype
};
}

@ -0,0 +1,36 @@
/*
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.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
public class Xodel_exec_cmd extends Xob_cmd__base {
private Io_url deletion_db_url;
public Xodel_exec_cmd(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);}
@Override public void Cmd_run() {
new Xodel_exec_mgr().Exec_delete(gplx.core.progs.Gfo_prog_ui_.Noop, bldr, deletion_db_url);
}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk__file_)) this.deletion_db_url = Io_url_.new_any_(m.ReadStr("v"));
else return Gfo_invk_.Rv_unhandled;
return this;
} private static final String Invk__file_ = "file_";
public static final String BLDR_CMD_KEY = "fsdb.deletion_db.exec";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}
public static final Xob_cmd Prototype = new Xodel_exec_cmd(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xodel_exec_cmd(bldr, wiki);}
}

@ -0,0 +1,134 @@
/*
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.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.core.progs.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.xowa.wikis.data.*;
import gplx.xowa.bldrs.*;
import gplx.xowa.files.fsdb.*; import gplx.fsdb.meta.*;
public class Xodel_exec_mgr {
public void Exec_delete(Gfo_prog_ui prog_ui, Xob_bldr bldr, Io_url deletion_db_url) {
// get domain bry from deletion_conn's cfg_tbl
Db_conn deletion_conn = Db_conn_bldr.Instance.Get_or_fail(deletion_db_url);
Db_cfg_tbl cfg_tbl = Xowd_cfg_tbl_.Get_or_fail(deletion_conn);
byte[] domain_bry = cfg_tbl.Select_bry("", Xodel_exec_mgr.Cfg__deletion_db__domain);
// get wiki; init it; do delete
Xowe_wiki wiki = bldr.App().Wiki_mgr().Get_by_or_make(domain_bry);
wiki.Init_assert();
Delete_by_url(prog_ui, wiki, deletion_conn, cfg_tbl);
// cleanup
deletion_conn.Rls_conn();
Io_mgr.Instance.DeleteFil(deletion_db_url);
}
public void Exec_cleanup(Io_url deletion_db_url) {
Db_conn deletion_conn = Db_conn_bldr.Instance.Get_or_fail(deletion_db_url);
Db_cfg_tbl cfg_tbl = Xowd_cfg_tbl_.Get_or_fail(deletion_conn);
cfg_tbl.Delete_val("", Xodel_exec_mgr.Cfg__deletion_db__db_bgn);
}
private void Delete_by_url(Gfo_prog_ui prog_ui, Xowe_wiki wiki, Db_conn deletion_conn, Db_cfg_tbl cfg_tbl) {
// get fsdb_mgr
Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr();
Fsm_mnt_itm mnt_itm = fsdb_mgr.Mnt_mgr().Mnts__get_main();
Db_conn core_conn = mnt_itm.Atr_mgr().Db__core().Conn();
try {
core_conn.Env_db_attach("delete_db", deletion_conn);
// loop dbs
int dbs_len = mnt_itm.Bin_mgr().Dbs__len();
String dbs_len_str = Int_.To_str(dbs_len - Int_.Base1);
int db_bgn = cfg_tbl.Select_int_or("", Cfg__deletion_db__db_bgn, 0);
for (int i = db_bgn; i < dbs_len; ++i) {
if (prog_ui.Prog_notify_and_chk_if_suspended(i, dbs_len)) return;
Fsm_bin_fil bin_db = mnt_itm.Bin_mgr().Dbs__get_at(i);
Delete_by_db(core_conn, bin_db, dbs_len_str);
cfg_tbl.Upsert_int("", Cfg__deletion_db__db_bgn, i + 1);
}
} finally {core_conn.Env_db_detach("delete_db");}
}
private void Delete_by_db(Db_conn deletion_conn, Fsm_bin_fil bin_db, String dbs_len_str) {
Gfo_usr_dlg usr_dlg = Xoa_app_.Usr_dlg();
// get rows to delete in db
List_adp list = List_adp_.New();
int bin_db_id = bin_db.Id();
String bin_db_id_str = Int_.To_str(bin_db_id);
usr_dlg.Prog_many("", "", "processing files for deletion in database " + bin_db_id_str + " of " + dbs_len_str);
Db_rdr rdr = deletion_conn.Exec_rdr(String_.Concat_lines_nl
( "SELECT ff.fil_id AS item_id"
, ", 1 AS item_is_orig"
, "FROM fsdb_fil ff"
, "JOIN delete_db.delete_regy dr ON ff.fil_id = dr.fil_id AND dr.thm_id = -1"
, "WHERE ff.fil_bin_db_id = " + bin_db_id_str
, "UNION"
, "SELECT ft.thm_id AS item_id"
, ", 0 AS item_is_orig"
, "FROM fsdb_thm ft"
, " JOIN delete_db.delete_regy dr ON ft.thm_owner_id = dr.fil_id AND ft.thm_id = dr.thm_id"
, "WHERE ft.thm_bin_db_id = " + bin_db_id_str
));
try {
while (rdr.Move_next()) {
int item_id = rdr.Read_int("item_id");
int item_is_orig = rdr.Read_int("item_is_orig");
list.Add(new Xodel_prune_itm(item_id, item_is_orig == 1));
}
} finally {rdr.Rls();}
int len = list.Count();
if (len == 0) return; // no files; exit, else will vacuum below
deletion_conn.Env_db_attach("bin_db", bin_db.Conn());
deletion_conn.Txn_bgn("img_prune__" + bin_db_id_str);
// delete bin
Db_stmt delete_bin_stmt = deletion_conn.Stmt_sql("DELETE FROM bin_db.fsdb_bin WHERE bin_owner_id = ?");
for (int i = 0; i < len; ++i) {
Xodel_prune_itm itm = (Xodel_prune_itm)list.Get_at(i);
delete_bin_stmt.Clear().Crt_int("bin_owner_id", itm.Item_id);
delete_bin_stmt.Exec_delete();
if (i % 10000 == 0) usr_dlg.Prog_many("", "", "deleting data in database " + bin_db_id_str + " of " + dbs_len_str);
}
delete_bin_stmt.Rls();
// delete meta
Db_stmt delete_fil_stmt = deletion_conn.Stmt_sql("DELETE FROM fsdb_fil WHERE fil_id = ?");
Db_stmt delete_thm_stmt = deletion_conn.Stmt_sql("DELETE FROM fsdb_thm WHERE thm_id = ?");
for (int i = 0; i < len; ++i) {
Xodel_prune_itm itm = (Xodel_prune_itm)list.Get_at(i);
if (itm.Item_is_orig) {
delete_fil_stmt.Clear().Crt_int("fil_id", itm.Item_id);
delete_fil_stmt.Exec_delete();
}
else {
delete_thm_stmt.Clear().Crt_int("thm_id", itm.Item_id);
delete_thm_stmt.Exec_delete();
}
if (i % 10000 == 0) usr_dlg.Prog_many("", "", "deleting meta in database " + bin_db_id_str + " of " + dbs_len_str);
}
delete_fil_stmt.Rls();
delete_thm_stmt.Rls();
// cleanup
deletion_conn.Txn_end();
deletion_conn.Env_db_detach("bin_db");
bin_db.Conn().Env_vacuum();
}
public static final String Cfg__deletion_db__domain = "file.deletion_db.domain", Cfg__deletion_db__db_bgn = "file.deletion_db.db_bgn";
}

@ -0,0 +1,31 @@
/*
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.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
public class Xodel_make_cmd extends Xob_cmd__base implements Xob_cmd {
public Xodel_make_cmd(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);}
@Override public void Cmd_run() {
wiki.Init_assert();
new Xodel_make_mgr().Exec(wiki);
}
public static final String BLDR_CMD_KEY = "file.deletion_db.make";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}
public static final Xob_cmd Prototype = new Xodel_make_cmd(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xodel_make_cmd(bldr, wiki);}
}

@ -16,13 +16,10 @@ 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.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.dbs.engines.sqlite.*; import gplx.xowa.addons.bldrs.files.dbs.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
import gplx.fsdb.meta.*;
public class Xobldr__deletion_db__make extends Xob_cmd__base implements Xob_cmd {
public Xobldr__deletion_db__make(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);}
@Override public void Cmd_run() {
wiki.Init_assert();
import gplx.dbs.*;
import gplx.xowa.bldrs.*;
class Xodel_make_mgr {
public void Exec(Xow_wiki wiki) {
// mark the records deleted
Db_conn make_conn = Xob_db_file.New__file_make(wiki.Fsys_mgr().Root_dir()).Conn();
make_conn.Exec_sql_concat_w_msg
@ -39,16 +36,15 @@ public class Xobldr__deletion_db__make extends Xob_cmd__base implements Xob_cmd
, "AND xr.file_w = fsdb_regy.fsdb_w"
, "AND xr.lnki_time = fsdb_regy.fsdb_time"
, "AND xr.lnki_page = fsdb_regy.fsdb_page"
, ")"
);
, ")");
// create deletion db
Xob_db_file deletion_db = Xob_db_file.New__deletion_db(wiki);
Db_conn deletion_conn = deletion_db.Conn();
deletion_db.Tbl__cfg().Upsert_str("", Xobldr__deletion_db__make.Cfg__deletion_db__domain, wiki.Domain_str());
deletion_db.Tbl__cfg().Upsert_str("", Xodel_exec_mgr.Cfg__deletion_db__domain, wiki.Domain_str());
// copy records over to it
Xob_delete_regy delete_regy_tbl = new Xob_delete_regy(deletion_conn);
Xob_delete_regy_tbl delete_regy_tbl = new Xob_delete_regy_tbl(deletion_conn);
deletion_conn.Meta_tbl_remake(delete_regy_tbl.Meta());
deletion_conn.Env_db_attach("make_db", make_conn);
deletion_conn.Exec_sql_concat_w_msg
@ -64,19 +60,13 @@ public class Xobldr__deletion_db__make extends Xob_cmd__base implements Xob_cmd
deletion_conn.Env_db_detach("make_db");
deletion_conn.Meta_idx_create(Dbmeta_idx_itm.new_normal_by_tbl(delete_regy_tbl.tbl_name, "main", delete_regy_tbl.fld_fil_id, delete_regy_tbl.fld_thm_id));
}
public static final String Cfg__deletion_db__domain = "file.deletion_db.domain";
public static final String BLDR_CMD_KEY = "file.deletion_db.make";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}
public static final Xob_cmd Prototype = new Xobldr__deletion_db__make(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xobldr__deletion_db__make(bldr, wiki);}
}
class Xob_delete_regy {
class Xob_delete_regy_tbl {
public final String tbl_name = "delete_regy";
public final Dbmeta_fld_list flds = new Dbmeta_fld_list();
public final String fld_fil_id, fld_thm_id, fld_reason;
public final Db_conn conn;
public Xob_delete_regy(Db_conn conn) {
public Xob_delete_regy_tbl(Db_conn conn) {
this.conn = conn;
this.fld_fil_id = flds.Add_int("fil_id");
this.fld_thm_id = flds.Add_int("thm_id");

@ -0,0 +1,26 @@
/*
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.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
class Xodel_prune_itm {
public Xodel_prune_itm(int item_id, boolean item_is_orig) {
this.Item_id = item_id;
this.Item_is_orig = item_is_orig;
}
public final int Item_id;
public final boolean Item_is_orig;
}

@ -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.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
public class Xodel_small_cmd extends Xob_cmd__base {
public Xodel_small_cmd(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);}
private final int[] ext_max_ary = Xobldr__fsdb_db__delete_small_files_.New_ext_max_ary();
@Override public void Cmd_run() {
wiki.Init_assert();
new Xodel_small_mgr().Exec(wiki, ext_max_ary);
}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return this;}
public static final String BLDR_CMD_KEY = "file.deletion_db.small_files";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}
public static final Xob_cmd Prototype = new Xodel_small_cmd(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xodel_small_cmd(bldr, wiki);}
}

@ -17,12 +17,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*;
import gplx.dbs.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
import gplx.xowa.bldrs.*;
import gplx.fsdb.*; import gplx.fsdb.meta.*; import gplx.xowa.files.*;
public class Xobldr__deletion_db__small_files extends Xob_cmd__base {
public Xobldr__deletion_db__small_files(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);}
private final int[] ext_max_ary = Xobldr__fsdb_db__delete_small_files_.New_ext_max_ary();
@Override public void Cmd_run() {
class Xodel_small_mgr {
public void Exec(Xowe_wiki wiki, int[] ext_max_ary) {
wiki.Init_assert();
// get atr_conn
Fsdb_db_mgr db_core_mgr = Fsdb_db_mgr_.new_detect(wiki, wiki.Fsys_mgr().Root_dir(), wiki.Fsys_mgr().File_dir());
@ -54,13 +52,7 @@ public class Xobldr__deletion_db__small_files extends Xob_cmd__base {
, "AND t.thm_size <= " + Int_.To_str(max)
);
}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return this;}
public static final String BLDR_CMD_KEY = "file.deletion_db.small_files";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}
public static final Xob_cmd Prototype = new Xobldr__deletion_db__small_files(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xobldr__deletion_db__small_files(bldr, wiki);}
}
}
class Xobldr__fsdb_db__delete_small_files_ {
public static int[] New_ext_max_ary() {
int[] rv = new int[Xof_ext_.Id__max];

@ -17,24 +17,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.bldrs.wmdumps.imglinks; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.wmdumps.*;
import gplx.dbs.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sqls.*;
public class Imglnk_bldr_cmd extends Xob_sql_dump_base implements Sql_file_parser_cmd {
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sql_dumps.*;
public class Imglnk_bldr_cmd extends Xob_sql_dump_base implements Xosql_dump_cbk {
private Imglnk_bldr_mgr mgr;
private int tmp_page_id;
private int rows = 0;
public Imglnk_bldr_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki); this.make_fil_len = Io_mgr.Len_mb;}
@Override public String Sql_file_name() {return "imagelinks";}
@Override protected Xosql_dump_parser New_parser() {return new Xosql_dump_parser(this, "il_from", "il_to");}
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Sql_file_parser parser) {
parser.Save_csv_n_().Fld_cmd_(this).Flds_req_idx_(3, 0, 1);
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Xosql_dump_parser parser) {
mgr = new Imglnk_bldr_mgr(wiki);
}
public void Exec(byte[] src, byte[] fld_key, int fld_idx, int fld_bgn, int fld_end, Bry_bfr file_bfr, Sql_file_parser_data data) {
public void On_fld_done(int fld_idx, byte[] src, int val_bgn, int val_end) {
switch (fld_idx) {
case Fld__il_from: this.tmp_page_id = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld__il_from: this.tmp_page_id = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld__il_to:
mgr.Tmp_tbl().Insert_by_batch(tmp_page_id, Bry_.Mid(src, fld_bgn, fld_end));
mgr.Tmp_tbl().Insert_by_batch(tmp_page_id, Bry_.Mid(src, val_bgn, val_end));
if (++rows % 100000 == 0) usr_dlg.Prog_many("", "", "reading row ~{0}", Int_.To_str_fmt(rows, "#,##0"));
break;
}

@ -41,8 +41,8 @@ class Imglnk_bldr_mgr {
Imglnk_reg_tbl reg_tbl = new Imglnk_reg_tbl(conn);
conn.Meta_tbl_remake(reg_tbl);
reg_tbl.Create_idx__src_ttl();
reg_tbl.Insert(conn, Xof_repo_itm_.Repo_local , wiki);
reg_tbl.Insert(conn, Xof_repo_itm_.Repo_remote, wiki.Appe().Wiki_mgr().Wiki_commons());
reg_tbl.Insert(conn, Xof_repo_tid_.Tid__local , wiki);
reg_tbl.Insert(conn, Xof_repo_tid_.Tid__remote, wiki.Appe().Wiki_mgr().Wiki_commons());
reg_tbl.Create_idx__trg_ttl();
// Imglnk_bulk_cmd__img_id.Bulk_exec(conn, Bool_.Y, wiki);

@ -23,8 +23,8 @@ public class Xof_orig_wkr__img_links_ {
public static void Load_all(Xof_orig_wkr__img_links wkr) {
Xowe_wiki wiki = wkr.Wiki();
Db_conn conn = Xob_db_file.New__img_link(wiki).Conn();
Load_all_by_wiki(wkr, conn, Xof_repo_itm_.Repo_local , wiki);
Load_all_by_wiki(wkr, conn, Xof_repo_itm_.Repo_remote, wiki.Appe().Wiki_mgr().Wiki_commons());
Load_all_by_wiki(wkr, conn, Xof_repo_tid_.Tid__local , wiki);
Load_all_by_wiki(wkr, conn, Xof_repo_tid_.Tid__remote, wiki.Appe().Wiki_mgr().Wiki_commons());
}
public static Xof_orig_itm Load_itm(Xof_orig_wkr__img_links wkr, Db_conn conn, Xowe_wiki wiki, byte[] ttl) {
Imglnk_reg_tbl imglnk_reg_tbl = wkr.Tbl__imglnk_reg();
@ -39,7 +39,7 @@ public class Xof_orig_wkr__img_links_ {
else // ttl missing; EX:</*_File:Chehov_v_serpuhove11.JPG; DATE:2016-08-10
return Xof_orig_itm.Null;
} finally {rdr.Rls();}
Xowe_wiki image_wiki = img_repo == Xof_repo_itm_.Repo_local ? wiki : wiki.Appe().Wiki_mgr().Wiki_commons();
Xowe_wiki image_wiki = img_repo == Xof_repo_tid_.Tid__local ? wiki : wiki.Appe().Wiki_mgr().Wiki_commons();
return Load_itm_by_wiki(wkr, conn, image_wiki, img_repo, ttl, img_trg);
}
private static Xof_orig_itm Load_itm_by_wiki(Xof_orig_wkr__img_links wkr, Db_conn conn, Xowe_wiki wiki, byte repo_id, byte[] img_src, byte[] img_trg) {

@ -16,18 +16,18 @@ 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.addons.bldrs.wmdumps.pagelinks.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.wmdumps.*; import gplx.xowa.addons.bldrs.wmdumps.pagelinks.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sqls.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sql_dumps.*;
import gplx.dbs.*; import gplx.dbs.qrys.*; import gplx.xowa.wikis.data.*; import gplx.xowa.addons.bldrs.wmdumps.pagelinks.dbs.*;
public class Pglnk_bldr_cmd extends Xob_sql_dump_base implements Sql_file_parser_cmd {
public class Pglnk_bldr_cmd extends Xob_sql_dump_base implements Xosql_dump_cbk {
private Db_conn conn;
private Pglnk_page_link_temp_tbl temp_tbl;
private int tmp_src_id, tmp_trg_ns;
private int rows = 0;
public Pglnk_bldr_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki); this.make_fil_len = Io_mgr.Len_mb;}
@Override public String Sql_file_name() {return Dump_type_key;} public static final String Dump_type_key = "pagelinks";
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Sql_file_parser parser) {
@Override protected Xosql_dump_parser New_parser() {return new Xosql_dump_parser(this, "pl_from", "pl_namespace", "pl_title");}
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Xosql_dump_parser parser) {
wiki.Init_assert();
parser.Fld_cmd_(this).Flds_req_idx_(4, 0, 1, 2);
Xob_db_file page_link_db = Xob_db_file.New__page_link(wiki);
this.conn = page_link_db.Conn();
this.temp_tbl = new Pglnk_page_link_temp_tbl(conn);
@ -49,12 +49,12 @@ public class Pglnk_bldr_cmd extends Xob_sql_dump_base implements Sql_file_parser
actl_tbl.Create_idx__trg_src();
conn.Env_vacuum();
}
public void Exec(byte[] src, byte[] fld_key, int fld_idx, int fld_bgn, int fld_end, Bry_bfr file_bfr, Sql_file_parser_data data) {
public void On_fld_done(int fld_idx, byte[] src, int val_bgn, int val_end) {
switch (fld_idx) {
case Fld__pl_from: this.tmp_src_id = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld__pl_namespace: this.tmp_trg_ns = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld__pl_from: this.tmp_src_id = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld__pl_namespace: this.tmp_trg_ns = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld__pl_title:
byte[] tmp_trg_ttl = Bry_.Mid(src, fld_bgn, fld_end);
byte[] tmp_trg_ttl = Bry_.Mid(src, val_bgn, val_end);
temp_tbl.Insert(tmp_src_id, tmp_trg_ns, tmp_trg_ttl);
if (++rows % 100000 == 0) usr_dlg.Prog_many("", "", "reading row ~{0}", Int_.To_str_fmt(rows, "#,##0"));
break;

@ -140,7 +140,7 @@ class Xoh_toc_wkr__txt {
int rhs_bgn = -1, rhs_end = -1, new_pos = lhs_end;
if (lhs_is_pair) { // get rhs unless inline
if (tag_id == Gfh_tag_.Id__any) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "unknown tag: page=~{0} tag=~{1}", page_name, lhs_bry);
Gfo_usr_dlg_.Instance.Warn_many("", "", "unknown tag: page=~{0} tag=~{1}", page_name, lhs_bry);
Gfh_tag rhs = tag_rdr.Tag__peek_fwd_tail(lhs_bry);
if (rhs.Name_id() == Gfh_tag_.Id__eos) return false;
rhs_bgn = rhs.Src_bgn(); rhs_end = rhs.Src_end();

@ -58,7 +58,7 @@ public class Xoa_ctg_mgr implements Gfo_invk {
}
}
public static final byte Version_null = Byte_.Zero, Version_1 = 1, Version_2 = 2;
public static final byte Tid_null = Byte_.Max_value_127, Tid_subc = 0, Tid_file = 1, Tid_page = 2, Tid__max = 3; // SERIALIZED
public static final byte Tid__subc = 0, Tid__file = 1, Tid__page = 2, Tid___max = 3; // SERIALIZED; cat_link.cl_type_id
public static final byte Hidden_n = Byte_.Zero, Hidden_y = (byte)1;
public static final String Html__cls__str = "CategoryTreeLabel CategoryTreeLabelNs14 CategoryTreeLabelCategory";
public static final byte[] Html__cls__bry = Bry_.new_a7(Html__cls__str);

@ -16,33 +16,33 @@ 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.addons.wikis.ctgs.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sqls.*;
public class Xob_catlink_cmd extends Xob_sql_dump_base implements Sql_file_parser_cmd {
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sql_dumps.*;
public class Xob_catlink_cmd extends Xob_sql_dump_base implements Xosql_dump_cbk {
private final Xob_catlink_mgr mgr = new Xob_catlink_mgr();
private int tmp_page_id;
private byte[] tmp_ctg_ttl, tmp_sortkey, tmp_timestamp, tmp_sortkey_prefix, tmp_collation, tmp_type;
public Xob_catlink_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);}
@Override public String Sql_file_name() {return Dump_file_name;} public static final String Dump_file_name = "categorylinks";
@Override protected Xosql_dump_parser New_parser() {return new Xosql_dump_parser(this, "cl_from", "cl_to", "cl_sortkey", "cl_timestamp", "cl_sortkey_prefix", "cl_collation", "cl_type");}
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Sql_file_parser parser) {
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Xosql_dump_parser parser) {
wiki.Init_assert();
parser.Save_csv_n_().Fld_cmd_(this).Flds_req_idx_(7, 0, 1, 2, 3, 4, 5, 6);
mgr.On_cmd_bgn(wiki);
}
@Override public void Cmd_end() {
mgr.On_cmd_end();
this.Cmd_cleanup_sql();
}
public void Exec(byte[] src, byte[] fld_key, int fld_idx, int fld_bgn, int fld_end, Bry_bfr file_bfr, Sql_file_parser_data data) {
public void On_fld_done(int fld_idx, byte[] src, int val_bgn, int val_end) {
switch (fld_idx) {
case Fld__cl_from: this.tmp_page_id = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld__cl_to: this.tmp_ctg_ttl = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld__cl_sortkey: this.tmp_sortkey = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld__cl_timestamp: this.tmp_timestamp = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld__cl_sortkey_prefix: this.tmp_sortkey_prefix = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld__cl_collation: this.tmp_collation = Bry_.Mid(src, fld_bgn, fld_end); break;
case Fld__cl_type: this.tmp_type = Bry_.Mid(src, fld_bgn, fld_end);
case Fld__cl_from: this.tmp_page_id = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld__cl_to: this.tmp_ctg_ttl = Bry_.Mid(src, val_bgn, val_end); break;
case Fld__cl_sortkey: this.tmp_sortkey = Bry_.Mid(src, val_bgn, val_end); break;
case Fld__cl_timestamp: this.tmp_timestamp = Bry_.Mid(src, val_bgn, val_end); break;
case Fld__cl_sortkey_prefix: this.tmp_sortkey_prefix = Bry_.Mid(src, val_bgn, val_end); break;
case Fld__cl_collation: this.tmp_collation = Bry_.Mid(src, val_bgn, val_end); break;
case Fld__cl_type: this.tmp_type = Bry_.Mid(src, val_bgn, val_end);
mgr.On_cmd_row(tmp_page_id, tmp_ctg_ttl, tmp_sortkey, tmp_timestamp, tmp_sortkey_prefix, tmp_collation, tmp_type);
break;
}

@ -37,7 +37,8 @@ class Xob_catlink_mgr {
}
public void On_cmd_row(int page_id, byte[] ctg_ttl, byte[] sortkey_orig, byte[] timestamp_bry, byte[] sortkey_prefix, byte[] collation_bry, byte[] type_bry) {
// convert strings to numbers
long timestamp = DateAdp_.parse_fmt(String_.new_u8(timestamp_bry), "YYYY-MM-dd HH:mm:ss").Timestamp_unix();
String timestamp_str = String_.new_u8(timestamp_bry);
long timestamp = String_.Len_eq_0(timestamp_str) ? 0 : DateAdp_.parse_fmt(timestamp_str, "YYYY-MM-dd HH:mm:ss").Timestamp_unix();
byte collation_id = collation_enum.To_tid_or_fail(collation_bry);
byte type_id = type_enum.To_tid_or_fail(type_bry);
@ -64,11 +65,17 @@ class Xob_catlink_mgr {
public void On_cmd_end() {
tmp_link_tbl.Insert_end();
// create cat_sort
// get cat_core conn
tmp_link_tbl.Create_idx__sortkey(); // index should make SELECT DISTINCT faster
Db_conn cat_core_conn = wiki.Data__core_mgr().Props().Layout_text().Tid_is_lot()
? wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__cat_core).Conn()
: wiki.Data__core_mgr().Db__core().Conn();
Db_conn cat_core_conn = wiki.Data__core_mgr().Db__core().Conn();
if (wiki.Data__core_mgr().Props().Layout_text().Tid_is_lot()) {
Xow_db_file cat_core_db = wiki.Data__core_mgr().Dbs__get_by_tid_or_null(Xow_db_file_.Tid__cat_core);
if (cat_core_db == null)
cat_core_db = wiki.Data__core_mgr().Dbs__make_by_tid(Xow_db_file_.Tid__cat_core);
cat_core_conn = cat_core_db.Conn();
}
// create tbl
Xodb_cat_sort_tbl cat_sort_tbl = new Xodb_cat_sort_tbl(cat_core_conn);
cat_core_conn.Meta_tbl_remake(cat_sort_tbl);
cat_sort_tbl.Insert_by_select(tmp_conn);

@ -16,9 +16,9 @@ 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.addons.wikis.ctgs.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sqls.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.sql_dumps.*;
import gplx.dbs.*; import gplx.xowa.addons.wikis.ctgs.dbs.*;
public class Xob_pageprop_cmd extends Xob_sql_dump_base implements Sql_file_parser_cmd {
public class Xob_pageprop_cmd extends Xob_sql_dump_base implements Xosql_dump_cbk {
private int tmp_id;
private boolean tmp_key_is_hiddencat;
private int rows;
@ -26,10 +26,10 @@ public class Xob_pageprop_cmd extends Xob_sql_dump_base implements Sql_file_pars
public Xob_pageprop_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);}
@Override public String Sql_file_name() {return Dump_file_name;} public static final String Dump_file_name = "page_props";
@Override protected Xosql_dump_parser New_parser() {return new Xosql_dump_parser(this, "pp_page", "pp_propname", "pp_value");} // NOTE: 4 b/c MW added fld_3:pp_sortkey; DATE:2014-04-28
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Sql_file_parser parser) {
@Override public void Cmd_bgn_hook(Xob_bldr bldr, Xosql_dump_parser parser) {
wiki.Init_assert();
parser.Save_csv_n_().Fld_cmd_(this).Flds_req_idx_(4, 0, 1, 2); // NOTE: 4 b/c MW added fld_3:pp_sortkey; DATE:2014-04-28
Xodb_tmp_cat_db tmp_db = new Xodb_tmp_cat_db(wiki);
tbl = new Xodb_tmp_cat_hidden_tbl(tmp_db.Conn());
tbl.Insert_bgn();
@ -38,18 +38,18 @@ public class Xob_pageprop_cmd extends Xob_sql_dump_base implements Sql_file_pars
tbl.Insert_end();
this.Cmd_cleanup_sql();
}
public void Exec(byte[] src, byte[] fld_key, int fld_idx, int fld_bgn, int fld_end, Bry_bfr file_bfr, Sql_file_parser_data data) {
public void On_fld_done(int fld_idx, byte[] src, int val_bgn, int val_end) {
switch (fld_idx) {
case Fld__id: this.tmp_id = Bry_.To_int_or(src, fld_bgn, fld_end, -1); break;
case Fld__key: this.tmp_key_is_hiddencat = Bry_.Eq(src, fld_bgn, fld_end, Key_hiddencat); break;
case Fld__val:
if (!tmp_key_is_hiddencat) {data.Cancel_row_y_(); return;}
tbl.Insert_cmd_by_batch(tmp_id);
case Fld__pp_page: this.tmp_id = Bry_.To_int_or(src, val_bgn, val_end, -1); break;
case Fld__pp_propname: this.tmp_key_is_hiddencat = Bry_.Eq(src, val_bgn, val_end, Key_hiddencat); break;
case Fld__pp_value:
if (tmp_key_is_hiddencat)
tbl.Insert_cmd_by_batch(tmp_id);
if (++rows % 10000 == 0) usr_dlg.Prog_many("", "", "parsing pageprops sql: row=~{0}", Int_.To_str_fmt(rows, "#,##0"));
break;
}
}
private static final byte Fld__id = 0, Fld__key = 1, Fld__val = 2;
private static final byte Fld__pp_page = 0, Fld__pp_propname = 1, Fld__pp_value = 2;
public static final String BLDR_CMD_KEY = "wiki.page_props";
@Override public String Cmd_key() {return BLDR_CMD_KEY;}

@ -19,34 +19,56 @@ package gplx.xowa.addons.wikis.ctgs.htmls.catpages; import gplx.*; import gplx.x
import gplx.xowa.wikis.dbs.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*; import gplx.xowa.htmls.core.htmls.*;
import gplx.xowa.wikis.nss.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.fmts.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.fmts.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.utls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.urls.*;
public class Xoctg_catpage_mgr {
private final Hash_adp_bry cache = Hash_adp_bry.cs();
private final Xoctg_catpage_loader loader = new Xoctg_catpage_loader();
private final Xoctg_catpage_url tmp_catpage_url = new Xoctg_catpage_url();
private final Xoctg_fmt_grp fmt_subcs = Xoctg_fmt_grp.New__subc(), fmt_pages = Xoctg_fmt_grp.New__page(), fmt_files = Xoctg_fmt_grp.New__file();
public Xoctg_fmt_grp Fmt(byte tid) { // TEST:
public int Grp_max() {return grp_max;} private int grp_max = Grp_max_dflt;
public Xoctg_fmt_grp Fmt(byte tid) {
switch (tid) {
case Xoa_ctg_mgr.Tid_subc: return fmt_subcs;
case Xoa_ctg_mgr.Tid_page: return fmt_pages;
case Xoa_ctg_mgr.Tid_file: return fmt_files;
case Xoa_ctg_mgr.Tid__subc: return fmt_subcs;
case Xoa_ctg_mgr.Tid__page: return fmt_pages;
case Xoa_ctg_mgr.Tid__file: return fmt_files;
default: throw Err_.new_unhandled(tid);
}
}
public void Free_mem_all() {cache.Clear();}
public Xoctg_catpage_ctg Get_or_load_or_null(Xow_wiki wiki, Xoa_ttl cat_ttl) {
// load categories from cat dbs; exit if not found
Xoctg_catpage_ctg ctg = (Xoctg_catpage_ctg)cache.Get_by(cat_ttl.Full_db());
if (ctg == null) {
if (gplx.core.envs.Env_.Mode_testing()) return null; // needed for dpl test
ctg = loader.Load_by_ttl_or_null(wiki, cat_ttl);
if (ctg == null) return null; // not in cache or db; exit
cache.Add(cat_ttl.Full_db(), ctg);
}
return ctg;
}
public void Write_catpage(Bry_bfr bfr, Xow_wiki wiki, Xoa_page page, Xoh_wtr_ctx hctx) {
try {
// load categories from cat dbs; exit if not found
tmp_catpage_url.Parse(wiki.App().Usr_dlg(), page.Url());
Xoctg_catpage_ctg dom_ctg = loader.Load_by_ttl_or_null(wiki, page.Ttl());
if (dom_ctg == null) return;
Xoctg_catpage_ctg ctg = Get_or_load_or_null(wiki, page.Ttl());
if (ctg == null) return;
// filter subs; need for large categories like de.w:Category:Mann
Xoctg_catpage_url catpage_url = Xoctg_catpage_url_parser.Parse(page.Url());
Xoctg_catpage_filter.Filter(grp_max, catpage_url, ctg);
// write html
Xol_lang_itm lang = page.Lang();
fmt_subcs.Write_catpage_grp(bfr, wiki, lang, dom_ctg);
fmt_pages.Write_catpage_grp(bfr, wiki, lang, dom_ctg);
fmt_files.Write_catpage_grp(bfr, wiki, lang, dom_ctg);
fmt_subcs.Write_catpage_grp(bfr, wiki, lang, ctg, grp_max);
fmt_pages.Write_catpage_grp(bfr, wiki, lang, ctg, grp_max);
fmt_files.Write_catpage_grp(bfr, wiki, lang, ctg, grp_max);
}
catch (Exception e) {
Xoa_app_.Usr_dlg().Warn_many("", "", "failed to generate category: title=~{0} err=~{1}", page.Url_bry_safe(), Err_.Message_gplx_log(e));
}
}
public void Cache__add(byte[] ttl, Xoctg_catpage_ctg ctg) {
cache.Del(ttl);
cache.Add(ttl, ctg);
}
public void Grp_max_(int v) {grp_max = v;} // TEST:
public static int Grp_max_dflt = 200;
}

@ -18,16 +18,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.addons.wikis.ctgs.htmls.catpages; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*;
import org.junit.*; import gplx.xowa.htmls.core.htmls.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.fmts.*;
public class Xoctg_catpage_mgr_tst {
@Before public void init() {fxt.Clear();} private Xoh_ctg_page_fxt fxt = new Xoh_ctg_page_fxt();
public class Xoctg_catpage_mgr__basic__tst {
@Before public void init() {fxt.Clear();} private Xoctg_catpage_mgr_fxt fxt = new Xoctg_catpage_mgr_fxt();
@Test public void Page_itm() {
fxt .Init_itms__pages("A1")
.Test_html_page(Xoa_ctg_mgr.Tid_page, Byte_ascii.Ltr_A, "\n <li><a href=\"/wiki/A1\" title=\"A1\">A1</a></li>");
.Test__html__page(Xoa_ctg_mgr.Tid__page, Byte_ascii.Ltr_A, "\n <li><a href=\"/wiki/A1\" title=\"A1\">A1</a></li>");
}
@Test public void Page_itm_missing() {
fxt .Init_itms__pages("A1");
fxt .Ctg().Grp_by_tid(Xoa_ctg_mgr.Tid_page).Itms()[0].Missing_y_();
fxt .Test_html_page(Xoa_ctg_mgr.Tid_page, Byte_ascii.Ltr_A, "\n <li class=\"xowa-missing-category-entry\"><span title=\"id not found: #0 might be talk/user page\">A1 (missing)</li>");
fxt .Ctg().Grp_by_tid(Xoa_ctg_mgr.Tid__page).Itms__get_at(0).Missing_y_();
fxt .Test__html__page(Xoa_ctg_mgr.Tid__page, Byte_ascii.Ltr_A, "\n <li class=\"xowa-missing-category-entry\"><span title=\"id not found: #0 might be talk/user page\">A1 (missing)</li>");
}
@Test public void Visited_doesnt_work_for_space() {// PURPOSE: xowa-visited not inserted for pages with space
byte[] page_bry = Bry_.new_a7("A 1");
@ -35,7 +35,7 @@ public class Xoctg_catpage_mgr_tst {
Xoa_ttl ttl = Xoa_ttl.Parse(fxt.Wiki(), page_bry);
fxt.Wiki().Appe().Usere().History_mgr().Add(url, ttl, page_bry);
fxt .Init_itms__pages("A_1").Init_grp__pages(0, 1)
.Test_html_all(Xoa_ctg_mgr.Tid_page, String_.Concat_lines_nl_skip_last
.Test__html__all(Xoa_ctg_mgr.Tid__page, String_.Concat_lines_nl_skip_last
( ""
, "<div id=\"mw-pages\">"
, " <h2>Pages in category \"Ctg_1\"</h2>"
@ -57,7 +57,7 @@ public class Xoctg_catpage_mgr_tst {
}
@Test public void Page_all() {
fxt .Init_itms__pages("A1").Init_grp__pages(0, 1)
.Test_html_all(Xoa_ctg_mgr.Tid_page, String_.Concat_lines_nl_skip_last
.Test__html__all(Xoa_ctg_mgr.Tid__page, String_.Concat_lines_nl_skip_last
( ""
, "<div id=\"mw-pages\">"
, " <h2>Pages in category \"Ctg_1\"</h2>"
@ -79,7 +79,7 @@ public class Xoctg_catpage_mgr_tst {
}
@Test public void File_all() {
fxt .Init_itms__files("File:A1.png").Init_grp__files(0, 1)
.Test_html_all(Xoa_ctg_mgr.Tid_file, String_.Concat_lines_nl_skip_last
.Test__html__all(Xoa_ctg_mgr.Tid__file, String_.Concat_lines_nl_skip_last
( ""
, "<div id=\"mw-category-media\">"
, " <h2>Media in category \"Ctg_1\"</h2>"
@ -117,7 +117,7 @@ public class Xoctg_catpage_mgr_tst {
}
@Test public void Subc_all() {
fxt .Init_itms__subcs("Category:Subc_1").Init_grp__files(0, 1)
.Test_html_all(Xoa_ctg_mgr.Tid_subc, String_.Concat_lines_nl_skip_last
.Test__html__all(Xoa_ctg_mgr.Tid__subc, String_.Concat_lines_nl_skip_last
( ""
, "<div id=\"mw-subcategories\">"
, " <h2>Subcategories</h2>"
@ -153,7 +153,7 @@ public class Xoctg_catpage_mgr_tst {
}
@Test public void Page_all_cols() {
fxt .Init_itms__pages("A1", "A2", "A3", "B1", "C1").Init_grp__pages(0, 5)
.Test_html_all(Xoa_ctg_mgr.Tid_page, String_.Concat_lines_nl_skip_last
.Test__html__all(Xoa_ctg_mgr.Tid__page, String_.Concat_lines_nl_skip_last
( ""
, "<div id=\"mw-pages\">"
, " <h2>Pages in category \"Ctg_1\"</h2>"
@ -192,7 +192,7 @@ public class Xoctg_catpage_mgr_tst {
}
@Test public void Title__escape_quotes() {// PURPOSE: quotes in title should be escaped; DATE:2015-12-28
fxt .Init_itms__pages("A\"1").Init_grp__pages(0, 1)
.Test_html_all(Xoa_ctg_mgr.Tid_page, String_.Concat_lines_nl_skip_last
.Test__html__all(Xoa_ctg_mgr.Tid__page, String_.Concat_lines_nl_skip_last
( ""
, "<div id=\"mw-pages\">"
, " <h2>Pages in category \"Ctg_1\"</h2>"
@ -212,22 +212,6 @@ public class Xoctg_catpage_mgr_tst {
, "</div>"
));
}
@Test public void Bld_rslts_lnk() {
fxt .Init_itms__pages("A1").Init_grp__pages(1, 1)
.Test_bld_rslts_lnk(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, " (<a href=\"/wiki/Category:Ctg_1?pageuntil=A1#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">previous 0</a>)"
, " (<a href=\"/wiki/Category:Ctg_1?pagefrom=A1#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">next 0</a>)"
));
}
@Test public void Bld_rslts_lnk__encoded() { // escape quotes and spaces; DATE:2016-01-11
fxt .Init_itms__pages("A\" b").Init_grp__pages(1, 1)
.Test_bld_rslts_lnk(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, " (<a href=\"/wiki/Category:Ctg_1?pageuntil=A%22+b#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">previous 0</a>)"
, " (<a href=\"/wiki/Category:Ctg_1?pagefrom=A%22+b#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">next 0</a>)"
));
}
@Test public void Calc_col_len() {
fxt.Test__calc_col_len(10, 0, 4); // for 10 items, col 0 has 4 items
fxt.Test__calc_col_len(10, 1, 3); // for 10 items, col 1 has 3 items
@ -240,31 +224,32 @@ public class Xoctg_catpage_mgr_tst {
fxt.Test__calc_col_len(12, 2, 4);
}
}
class Xoh_ctg_page_fxt {
public Xoh_ctg_page_fxt Clear() {
class Xoctg_catpage_mgr_fxt {
private int grp_max;
public Xoctg_catpage_mgr_fxt Clear() {
if (app == null) {
app = Xoa_app_fxt.Make__app__edit();
wiki = Xoa_app_fxt.Make__wiki__edit(app);
ctg_html = wiki.Html_mgr().Ns_ctg();
ctg_html = wiki.Html_mgr().Catpage_mgr();
}
ctg = new Xoctg_catpage_ctg(Bry_.new_a7("Ctg_1"));
grp_max = Xoctg_catpage_mgr.Grp_max_dflt;
return this;
} private Xoae_app app; private Xoctg_catpage_mgr ctg_html;
public void Test__calc_col_len(int grp_len, int col_idx, int expd) {Tfds.Eq(expd, Xoctg_fmt_itm_base.Calc_col_len(grp_len, col_idx, 3));}
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
public Xoctg_catpage_ctg Ctg() {return ctg;} private Xoctg_catpage_ctg ctg;
public void Test_bld_rslts_lnk(boolean next, String ctg_str, String expd) {
Xoctg_fmt_grp.Grp__max = 0;
byte[] actl = ctg_html.Fmt(Xoa_ctg_mgr.Tid_page).Bld_bwd_fwd(wiki, Xoa_ttl.Parse(wiki, Bry_.new_a7(ctg_str)), ctg.Grp_by_tid(Xoa_ctg_mgr.Tid_page));
public void Test__navlink(boolean next, String ctg_str, String expd) {
byte[] actl = ctg_html.Fmt(Xoa_ctg_mgr.Tid__page).Bld_bwd_fwd(wiki, Xoa_ttl.Parse(wiki, Bry_.new_a7(ctg_str)), ctg.Grp_by_tid(Xoa_ctg_mgr.Tid__page), grp_max);
Tfds.Eq_str_lines(expd, String_.new_u8(actl));
Xoctg_fmt_grp.Grp__max = 200;
}
public Xoh_ctg_page_fxt Init_grp__pages(int bgn, int count) {ctg.Pages().Init(bgn, count); return this;}
public Xoh_ctg_page_fxt Init_grp__files(int bgn, int count) {ctg.Files().Init(bgn, count); return this;}
public Xoh_ctg_page_fxt Init_itms__pages(String... titles) {return Init_itms(Xoa_ctg_mgr.Tid_page, titles);}
public Xoh_ctg_page_fxt Init_itms__files(String... titles) {return Init_itms(Xoa_ctg_mgr.Tid_file, titles);}
public Xoh_ctg_page_fxt Init_itms__subcs(String... titles) {return Init_itms(Xoa_ctg_mgr.Tid_subc, titles);}
private Xoh_ctg_page_fxt Init_itms(byte tid, String[] ttls) {
public Xoctg_catpage_mgr_fxt Init_grp_max(int v) {this.grp_max = v; return this;}
public Xoctg_catpage_mgr_fxt Init_grp__pages(int bgn, int count) {ctg.Pages().Rng_(bgn, count); return this;}
public Xoctg_catpage_mgr_fxt Init_grp__files(int bgn, int count) {ctg.Files().Rng_(bgn, count); return this;}
public Xoctg_catpage_mgr_fxt Init_itms__pages(String... titles) {return Init_itms(Xoa_ctg_mgr.Tid__page, titles);}
public Xoctg_catpage_mgr_fxt Init_itms__files(String... titles) {return Init_itms(Xoa_ctg_mgr.Tid__file, titles);}
public Xoctg_catpage_mgr_fxt Init_itms__subcs(String... titles) {return Init_itms(Xoa_ctg_mgr.Tid__subc, titles);}
private Xoctg_catpage_mgr_fxt Init_itms(byte tid, String[] ttls) {
int len = ttls.length;
Xoctg_catpage_grp grp = ctg.Grp_by_tid(tid);
for (int i = 0; i < len; ++i) {
@ -274,7 +259,7 @@ class Xoh_ctg_page_fxt {
grp.Itms__make();
return this;
}
public void Test_html_page(byte tid, byte grp_char_0, String expd) {
public void Test__html__page(byte tid, byte grp_char_0, String expd) {
Xoctg_fmt_grp list_mgr = ctg_html.Fmt(tid);
Xoctg_fmt_itm_base itm_fmt = list_mgr.Itm_fmt();
Xoctg_catpage_grp list = ctg.Grp_by_tid(tid);
@ -285,7 +270,7 @@ class Xoh_ctg_page_fxt {
itm_fmt.Bfr_arg__add(bfr);
Tfds.Eq_str_lines(expd, bfr.To_str_and_rls());
}
public void Test_html_grp(byte tid, String expd) {
public void Test__html_grp(byte tid, String expd) {
Xoctg_fmt_grp list_mgr = ctg_html.Fmt(tid);
Xoctg_fmt_ltr fmtr_grp = new Xoctg_fmt_ltr(list_mgr.Itm_fmt());
fmtr_grp.Init_from_grp(wiki, ctg.Grp_by_tid(tid));
@ -293,9 +278,9 @@ class Xoh_ctg_page_fxt {
fmtr_grp.Bfr_arg__add(bfr);
Tfds.Eq_str_lines(expd, bfr.To_str_and_rls());
}
public void Test_html_all(byte tid, String expd) {
public void Test__html__all(byte tid, String expd) {
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512();
ctg_html.Fmt(tid).Write_catpage_grp(bfr, wiki, wiki.Lang(), ctg);
ctg_html.Fmt(tid).Write_catpage_grp(bfr, wiki, wiki.Lang(), ctg, grp_max);
Tfds.Eq_str_lines(expd, bfr.To_str_and_rls());
}
}

@ -0,0 +1,63 @@
/*
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.addons.wikis.ctgs.htmls.catpages; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*;
import org.junit.*; import gplx.xowa.htmls.core.htmls.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.fmts.*;
public class Xoctg_catpage_mgr__navlink__tst {
@Before public void init() {fxt.Clear();} private Xoctg_catpage_mgr_fxt fxt = new Xoctg_catpage_mgr_fxt();
@Test public void Navlink__basic() {
fxt .Init_itms__pages("A1", "A2", "A3").Init_grp_max(1).Init_grp__pages(1, 2)
.Test__navlink(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, "(<a href=\"/wiki/Category:Ctg_1?pageuntil=A2#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">previous 1</a>)"
, "(<a href=\"/wiki/Category:Ctg_1?pagefrom=A3#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">next 1</a>)"
));
}
@Test public void Navlink__encoded() { // escape quotes and spaces; DATE:2016-01-11
fxt .Init_itms__pages("A\" 1", "A\" 2", "A\" 3").Init_grp_max(1).Init_grp__pages(1, 2)
.Test__navlink(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, "(<a href=\"/wiki/Category:Ctg_1?pageuntil=A%22+2#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">previous 1</a>)"
, "(<a href=\"/wiki/Category:Ctg_1?pagefrom=A%22+3#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">next 1</a>)"
));
}
@Test public void Navlink__bos() {
fxt .Init_itms__pages("A1", "A2", "A3").Init_grp_max(1).Init_grp__pages(0, 1)
.Test__navlink(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, "(previous 1)"
, "(<a href=\"/wiki/Category:Ctg_1?pagefrom=A2#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">next 1</a>)"
));
}
@Test public void Navlink__eos() {
fxt .Init_itms__pages("A1", "A2", "A3").Init_grp_max(2).Init_grp__pages(2, 3)
.Test__navlink(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, "(<a href=\"/wiki/Category:Ctg_1?pageuntil=A3#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">previous 2</a>)"
, "(next 2)"
));
}
@Test public void Navlink__eos__2() { // PURPOSE.fix: do not suppress next page on penultimate page; DATE:2016-09-25
fxt .Init_itms__pages("A1", "A2", "A3", "A4").Init_grp_max(2).Init_grp__pages(2, 3)
.Test__navlink(Bool_.Y, "Category:Ctg_1", String_.Concat_lines_nl
( ""
, "(<a href=\"/wiki/Category:Ctg_1?pageuntil=A3#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">previous 2</a>)"
, "(<a href=\"/wiki/Category:Ctg_1?pagefrom=A4#mw-pages\" class=\"xowa_nav\" title=\"Category:Ctg_1\">next 2</a>)"
));
}
}

@ -1,83 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.wikis.ctgs.htmls.catpages; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*;
import gplx.core.primitives.*; import gplx.core.net.*; import gplx.core.net.qargs.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.fmts.*;
public class Xoctg_catpage_url {
public byte[][] Grp_idxs() {return grp_idxs;} private byte[][] grp_idxs = new byte[3][];
public byte[] Grp_fwds() {return grp_fwds;} private byte[] grp_fwds = new byte[3];
private void Clear() {
for (int i = 0; i < 3; i++) {
grp_fwds[i] = Bool_.__byte;
grp_idxs[i] = null;
}
}
public Xoctg_catpage_url Parse(Gfo_usr_dlg usr_dlg, Xoa_url url) {
this.Clear();
Gfo_qarg_itm[] args = url.Qargs_ary();
int len = args.length;
for (int i = 0; i < len; i++) {
Gfo_qarg_itm arg = args[i];
byte[] arg_key = arg.Key_bry();
Object tid_obj = Arg_keys.Get_by_bry(arg_key);
if (tid_obj == null) {usr_dlg.Warn_many("", "", "unknown arg_key: ~{0}", String_.new_u8(arg_key)); continue;} // ignore invalid args
byte[] arg_val = arg.Val_bry();
byte tid = ((Byte_obj_val)tid_obj).Val();
switch (tid) {
case Tid_all_bgn: Set_grp(arg_val, Bool_.Y_byte, Xoa_ctg_mgr.Tid_subc, Xoa_ctg_mgr.Tid_file, Xoa_ctg_mgr.Tid_page); break; // if "from", default all grps to val; DATE:2014-02-05
case Tid_all_end: Set_grp(arg_val, Bool_.N_byte, Xoa_ctg_mgr.Tid_subc, Xoa_ctg_mgr.Tid_file, Xoa_ctg_mgr.Tid_page); break;
case Tid_subc_bgn: Set_grp(arg_val, Bool_.Y_byte, Xoa_ctg_mgr.Tid_subc); break;
case Tid_subc_end: Set_grp(arg_val, Bool_.N_byte, Xoa_ctg_mgr.Tid_subc); break;
case Tid_file_bgn: Set_grp(arg_val, Bool_.Y_byte, Xoa_ctg_mgr.Tid_file); break;
case Tid_file_end: Set_grp(arg_val, Bool_.N_byte, Xoa_ctg_mgr.Tid_file); break;
case Tid_page_bgn: Set_grp(arg_val, Bool_.Y_byte, Xoa_ctg_mgr.Tid_page); break;
case Tid_page_end: Set_grp(arg_val, Bool_.N_byte, Xoa_ctg_mgr.Tid_page); break;
}
}
return this;
}
private void Set_grp(byte[] val, byte fwd, byte... tids) {
int tids_len = tids.length;
for (int i = 0; i < tids_len; i++) {
byte tid = tids[i];
grp_fwds[tid] = fwd;
grp_idxs[tid] = val;
}
}
public static final byte Tid_all_bgn = 0, Tid_subc_bgn = 1, Tid_subc_end = 2, Tid_file_bgn = 3, Tid_file_end = 4, Tid_page_bgn = 5, Tid_page_end = 6, Tid_all_end = 8;
public static final byte[]
Url_arg_from = Bry_.new_a7("from")
, Url_arg_until = Bry_.new_a7("until")
, Url_arg_subc_bgn = Bry_.new_a7("subcatfrom")
, Url_arg_subc_end = Bry_.new_a7("subcatuntil")
, Url_arg_page_bgn = Bry_.new_a7("pagefrom")
, Url_arg_page_end = Bry_.new_a7("pageuntil")
, Url_arg_file_bgn = Bry_.new_a7("filefrom")
, Url_arg_file_end = Bry_.new_a7("fileuntil")
;
public static final Hash_adp_bry Arg_keys = Hash_adp_bry.ci_a7()
.Add_bry_byte(Url_arg_from , Tid_all_bgn)
.Add_bry_byte(Url_arg_until , Tid_all_end)
.Add_bry_byte(Url_arg_subc_bgn , Tid_subc_bgn)
.Add_bry_byte(Url_arg_subc_end , Tid_subc_end)
.Add_bry_byte(Url_arg_file_bgn , Tid_file_bgn)
.Add_bry_byte(Url_arg_file_end , Tid_file_end)
.Add_bry_byte(Url_arg_page_bgn , Tid_page_bgn)
.Add_bry_byte(Url_arg_page_end , Tid_page_end)
;
}

@ -1,72 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.wikis.ctgs.htmls.catpages; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*;
import org.junit.*; import gplx.xowa.apps.urls.*;
public class Xoctg_catpage_url_tst {
@Before public void init() {fxt.Clear();} private Xoctg_catpage_url_fxt fxt = new Xoctg_catpage_url_fxt();
@Test public void Basic() {
fxt.Test_parse("A?subcatfrom=B&filefrom=C&pagefrom=D", fxt.url().Grp_idxs_("B", "C", "D").Grp_fwds_(Bool_.Y_byte, Bool_.Y_byte, Bool_.Y_byte));
fxt.Test_parse("A?subcatuntil=B&fileuntil=C&pageuntil=D", fxt.url().Grp_idxs_("B", "C", "D").Grp_fwds_(Bool_.N_byte, Bool_.N_byte, Bool_.N_byte));
fxt.Test_parse("A?from=B", fxt.url().Grp_idxs_("B", "B", "B").Grp_fwds_(Bool_.Y_byte, Bool_.Y_byte, Bool_.Y_byte));
fxt.Test_parse("A?until=B", fxt.url().Grp_idxs_("B", "B", "B").Grp_fwds_(Bool_.N_byte, Bool_.N_byte, Bool_.N_byte));
}
}
class Xoctg_catpage_url_fxt {
public Xoctg_catpage_url_chkr url() {return expd.Clear();} private Xoctg_catpage_url_chkr expd;
public void Clear() {
if (parser == null) {
Xoa_app app = Xoa_app_fxt.Make__app__edit();
parser = app.User().Wikii().Utl__url_parser();
page_url = Xoa_url.blank();
ctg_url = new Xoctg_catpage_url();
expd = new Xoctg_catpage_url_chkr();
}
} private Xow_url_parser parser; Xoa_url page_url; Xoctg_catpage_url ctg_url;
public void Test_parse(String url_str, Xoctg_catpage_url_chkr expd) {
page_url = parser.Parse(Bry_.new_u8(url_str));
ctg_url.Parse(Gfo_usr_dlg_.Test(), page_url);
expd.Chk(ctg_url);
expd.Clear();
}
}
class Xoctg_catpage_url_chkr {
public Xoctg_catpage_url_chkr Grp_idxs_(String subc, String file, String page) {
grp_idxs[Xoa_ctg_mgr.Tid_subc] = Bry_.new_a7(subc);
grp_idxs[Xoa_ctg_mgr.Tid_file] = Bry_.new_a7(file);
grp_idxs[Xoa_ctg_mgr.Tid_page] = Bry_.new_a7(page);
return this;
} byte[][] grp_idxs = new byte[Xoa_ctg_mgr.Tid__max][];
public Xoctg_catpage_url_chkr Grp_fwds_(byte subc, byte file, byte page) {
grp_fwds[Xoa_ctg_mgr.Tid_subc] = subc;
grp_fwds[Xoa_ctg_mgr.Tid_file] = file;
grp_fwds[Xoa_ctg_mgr.Tid_page] = page;
return this;
} byte[] grp_fwds = new byte[Xoa_ctg_mgr.Tid__max];
public void Chk(Xoctg_catpage_url actl) {
Tfds.Eq_ary_str(String_.Ary(grp_idxs), String_.Ary(actl.Grp_idxs()));
Tfds.Eq_ary(grp_fwds, actl.Grp_fwds());
}
public Xoctg_catpage_url_chkr Clear() {
int len = Xoa_ctg_mgr.Tid__max;
for (int i = 0; i < len; i++) {
grp_idxs[i] = null;
grp_fwds[i] = Bool_.__byte;
}
return this;
}
}

@ -19,20 +19,20 @@ package gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms; import gplx.*; import g
public class Xoctg_catpage_ctg {
public Xoctg_catpage_ctg(byte[] name) {this.name = name;}
public byte[] Name() {return name;} private final byte[] name;
public Xoctg_catpage_grp Subcs() {return subcs;} private final Xoctg_catpage_grp subcs = new Xoctg_catpage_grp(Xoa_ctg_mgr.Tid_subc);
public Xoctg_catpage_grp Pages() {return pages;} private final Xoctg_catpage_grp pages = new Xoctg_catpage_grp(Xoa_ctg_mgr.Tid_page);
public Xoctg_catpage_grp Files() {return files;} private final Xoctg_catpage_grp files = new Xoctg_catpage_grp(Xoa_ctg_mgr.Tid_file);
public int Total() {return subcs.Total() + pages.Total() + files.Total();}
public Xoctg_catpage_grp Subcs() {return subcs;} private final Xoctg_catpage_grp subcs = new Xoctg_catpage_grp(Xoa_ctg_mgr.Tid__subc);
public Xoctg_catpage_grp Pages() {return pages;} private final Xoctg_catpage_grp pages = new Xoctg_catpage_grp(Xoa_ctg_mgr.Tid__page);
public Xoctg_catpage_grp Files() {return files;} private final Xoctg_catpage_grp files = new Xoctg_catpage_grp(Xoa_ctg_mgr.Tid__file);
public int Total() {return subcs.Itms__len() + pages.Itms__len() + files.Itms__len();}
public Xoctg_catpage_grp Grp_by_tid(byte tid) {
switch (tid) {
case Xoa_ctg_mgr.Tid_subc: return subcs;
case Xoa_ctg_mgr.Tid_page: return pages;
case Xoa_ctg_mgr.Tid_file: return files;
case Xoa_ctg_mgr.Tid__subc: return subcs;
case Xoa_ctg_mgr.Tid__page: return pages;
case Xoa_ctg_mgr.Tid__file: return files;
default: throw Err_.new_unhandled(tid);
}
}
public void Make_itms() {
for (byte i = 0; i < Xoa_ctg_mgr.Tid__max; ++i) {
for (byte i = 0; i < Xoa_ctg_mgr.Tid___max; ++i) {
Xoctg_catpage_grp grp = Grp_by_tid(i);
grp.Itms__make();
}

@ -17,28 +17,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
public class Xoctg_catpage_grp {
private final List_adp tmp_list = List_adp_.New();
public Xoctg_catpage_grp(byte tid) {this.tid = tid;}
public byte Tid() {return tid;} private byte tid; // subc|page|file
public int Bgn() {return bgn;} private int bgn;
public int End() {return end;} private int end;
public int Len() {return end - bgn;}
public int Total() {return total;} private int total;
public byte Tid() {return tid;} private byte tid; // subc|page|file
public int Bgn() {return bgn;} private int bgn; // idx of 1st item; EX: 200
public int End() {return end;} private int end; // idx of nth item + 1; EX: 399
public int Count_by_page() {return end - bgn;} // count of items on page; EX: 200
public int Itms__len() {return itms_len;} private int itms_len; // count of items in entire category; EX: 456
public Xoctg_catpage_itm[] Itms() {return itms;} private Xoctg_catpage_itm[] itms = Xoctg_catpage_itm.Ary_empty;
public byte[] Itms__nth_sortkey() {return itms__nth_sortkey;}
public Xoctg_catpage_itm Itms__get_at_0th() {return Itms__get_at(0);}
public Xoctg_catpage_itm Itms__get_at_nth() {return Itms__get_at(itms.length - 1);}
private Xoctg_catpage_itm Itms__get_at(int i) {
if (i < 0 || i >= itms.length) throw Err_.new_wo_type("ctg.view: i is out of bounds", "i", i, "len", itms.length, "tid", tid);
public Xoctg_catpage_itm Itms__get_at(int i) {
if (i < 0 || i >= itms.length) throw Err_.new_wo_type("catpage: i is out of bounds", "i", i, "len", itms.length, "tid", tid);
Xoctg_catpage_itm rv = itms[i]; if (rv == null) throw Err_.new_wo_type("ctg.view: itm is null", "i", i, "len", itms.length, "tid", tid);
return rv;
}
public void Itms__add(Xoctg_catpage_itm sub) {tmp_list.Add(sub);}
public void Itms__make() {
itms = (Xoctg_catpage_itm[])tmp_list.To_ary(Xoctg_catpage_itm.class);
total = end = itms.length;
tmp_list.Sort_by(Xoctg_catpage_itm_sorter__sort_key.Sorter);
itms = (Xoctg_catpage_itm[])tmp_list.To_ary_and_clear(Xoctg_catpage_itm.class);
bgn = 0;
end = itms_len = itms.length;
}
public void Rng_(int bgn, int end) {
this.bgn = bgn; this.end = end;
}
public Xoctg_catpage_grp Itms__nth_sortkey_(byte[] v) {itms__nth_sortkey = v; return this;} private byte[] itms__nth_sortkey;
public void Init(int bgn, int end) {this.bgn = bgn; this.end = end;} // TEST:
public List_adp Itms_list() {return tmp_list;} private final List_adp tmp_list = List_adp_.New(); // TEST
}

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
public class Xoctg_catpage_itm implements gplx.CompareAble {
public class Xoctg_catpage_itm {
public Xoctg_catpage_itm(int page_id, Xoa_ttl page_ttl, byte[] sort_key) {
this.page_id = page_id;
this.page_ttl = page_ttl;
@ -28,6 +28,5 @@ public class Xoctg_catpage_itm implements gplx.CompareAble {
public boolean Missing() {return missing;} private boolean missing; // not used; remove?;
public void Missing_y_() {missing = true;}
public int compareTo(Object obj) {Xoctg_catpage_itm comp = (Xoctg_catpage_itm)obj; return Int_.Compare(page_id, comp.Page_id());}
public static final Xoctg_catpage_itm[] Ary_empty = new Xoctg_catpage_itm[0];
}

@ -15,13 +15,16 @@ 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.addons.wikis.ctgs.htmls.catpages.fmts; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*;
class Xoctg_catpage_itm_sorter implements gplx.core.lists.ComparerAble {
package gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
public class Xoctg_catpage_itm_sorter__sort_key implements gplx.core.lists.ComparerAble, gplx.core.lists.binary_searches.Binary_comparer {
public int compare(Object lhsObj, Object rhsObj) {
Xoctg_catpage_itm lhs = (Xoctg_catpage_itm)lhsObj;
Xoctg_catpage_itm rhs = (Xoctg_catpage_itm)rhsObj;
return Bry_.Compare(lhs.Sort_key(), rhs.Sort_key());
}
public static final Xoctg_catpage_itm_sorter Sorter = new Xoctg_catpage_itm_sorter();
public int Compare_val_to_obj(Object val, Object obj) {
Xoctg_catpage_itm itm = (Xoctg_catpage_itm)obj;
return Bry_.Compare((byte[])val, itm.Sort_key());
}
public static final Xoctg_catpage_itm_sorter__sort_key Sorter = new Xoctg_catpage_itm_sorter__sort_key();
}

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.addons.wikis.ctgs.htmls.catpages.fmts; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*; import gplx.xowa.htmls.core.htmls.*; import gplx.langs.htmls.encoders.*;
import gplx.xowa.wikis.nss.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.urls.*;
public class Xoctg_fmt_grp { // subc|page|file
private final byte tid;
private final byte[] div_id, url_arg_bgn, url_arg_end;
@ -32,45 +32,47 @@ public class Xoctg_fmt_grp { // subc|page|file
this.url_arg_bgn = url_arg_bgn; this.url_arg_end = url_arg_end; this.div_id = div_id;
}
public Xoctg_fmt_itm_base Itm_fmt() {return itm_fmt;} private final Xoctg_fmt_itm_base itm_fmt;
public void Write_catpage_grp(Bry_bfr bfr, Xow_wiki wiki, Xol_lang_itm lang, Xoctg_catpage_ctg dom_ctg) { // TEST:
public void Write_catpage_grp(Bry_bfr bfr, Xow_wiki wiki, Xol_lang_itm lang, Xoctg_catpage_ctg dom_ctg, int grp_max) { // TEST:
Xoctg_catpage_grp dom_grp = dom_ctg.Grp_by_tid(tid);
if (dom_grp.Itms().length == 0) return; // no items in grp; EX: 0 items in File
if (dom_grp.Itms__len() == 0) return; // no items in grp; EX: 0 items in File
// get msgs
Xow_msg_mgr msg_mgr = wiki.Msg_mgr();
byte[] msg_label_bry = msg_mgr.Val_by_id_args(msg_label_id, dom_ctg.Name());
byte[] msg_stats_bry = msg_mgr.Val_by_id_args(msg_stats_id, dom_grp.Len(), dom_grp.Total());
byte[] msg_stats_bry = msg_mgr.Val_by_id_args(msg_stats_id, dom_grp.Count_by_page(), dom_grp.Itms__len());
// get nav html; next / previous 200
Xoa_ttl ctg_ttl = wiki.Ttl_parse(Xow_ns_.Tid__category, dom_ctg.Name());
byte[] nav_html = this.Bld_bwd_fwd(wiki, ctg_ttl, dom_grp);
byte[] nav_html = this.Bld_bwd_fwd(wiki, ctg_ttl, dom_grp, grp_max);
// sort; init grp; write
Array_.Sort(dom_grp.Itms(), Xoctg_catpage_itm_sorter.Sorter); // NOTE: must assert sorted for v1; PAGE:s.w:Category:Computer_science; DATE:2015-11-22
// init grp; write
itms_fmt.Init_from_grp(wiki, dom_grp);
Fmt__ctg.Bld_many(bfr, div_id, msg_label_bry, msg_stats_bry, nav_html, lang.Key_bry(), lang.Dir_ltr_bry(), itms_fmt);
}
public byte[] Bld_bwd_fwd(Xow_wiki wiki, Xoa_ttl ttl, Xoctg_catpage_grp view_grp) { // TEST:
if (view_grp.Total() < Grp__max) return Bry_.Empty;
public byte[] Bld_bwd_fwd(Xow_wiki wiki, Xoa_ttl ttl, Xoctg_catpage_grp view_grp, int grp_max) { // TEST:
if (view_grp.Itms__len() < grp_max) return Bry_.Empty; // < 200; never show;
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_k004();
Html_nav_bry(bfr, wiki, ttl, view_grp, Bool_.N);
Html_nav_bry(bfr, wiki, ttl, view_grp, Bool_.Y);
Html_nav_bry(bfr, wiki, ttl, view_grp, grp_max, Bool_.N);
Html_nav_bry(bfr, wiki, ttl, view_grp, grp_max, Bool_.Y);
return bfr.To_bry_and_rls();
}
private void Html_nav_bry(Bry_bfr bfr, Xow_wiki wiki, Xoa_ttl ttl, Xoctg_catpage_grp view_grp, boolean type_is_bgn) {
private void Html_nav_bry(Bry_bfr bfr, Xow_wiki wiki, Xoa_ttl ttl, Xoctg_catpage_grp grp, int grp_max, boolean type_is_next) {
Bry_bfr href_bfr = wiki.Utl__bfr_mkr().Get_b512();
// get nav_href; EX:href="/wiki/Category:Ctg_1?pageuntil=A1#mw-pages"
wiki.Html__href_wtr().Build_to_bfr(href_bfr, wiki.App(), Xoh_wtr_ctx.Basic, wiki.Domain_bry(), ttl);
byte[] arg_idx_lbl = null; byte[] arg_sortkey = null;
if (type_is_bgn) {
if (type_is_next) {
arg_idx_lbl = url_arg_bgn;
arg_sortkey = view_grp.Itms__nth_sortkey();
if (arg_sortkey == null) arg_sortkey = view_grp.Itms__get_at_nth().Sort_key();
// get next category after last one on page; needed for "Next 200 (href=Cat_201)"
int nxt_idx = grp.End();
if (nxt_idx == grp.Itms__len()) --nxt_idx; // if last item, then grp.End() does not exist; just use last one
arg_sortkey = grp.Itms__get_at(nxt_idx).Sort_key();
}
else {
arg_idx_lbl = url_arg_end;
arg_sortkey = view_grp.Itms__get_at_0th().Sort_key();
arg_sortkey = grp.Itms__get_at(grp.Bgn()).Sort_key(); // use 1st item as sortkey for "until" args
}
href_bfr.Add_byte(Byte_ascii.Question).Add(arg_idx_lbl).Add_byte(Byte_ascii.Eq); // filefrom=
Gfo_url_encoder_.Http_url.Encode(href_bfr, arg_sortkey); // Abc
@ -78,19 +80,20 @@ public class Xoctg_fmt_grp { // subc|page|file
byte[] nav_href = href_bfr.To_bry_and_rls();
// get nav_text
int nav_text_id = type_is_bgn ? Xol_msg_itm_.Id_next_results : Xol_msg_itm_.Id_prev_results;
byte[] nav_text = wiki.Msg_mgr().Val_by_id_args(nav_text_id, Grp__max); // next 200 / previous 200
int nav_text_id = type_is_next ? Xol_msg_itm_.Id_next_results : Xol_msg_itm_.Id_prev_results;
byte[] nav_text = wiki.Msg_mgr().Val_by_id_args(nav_text_id, grp_max); // next 200 / previous 200
// fmt
Fmt__nav.Bld_many(bfr, nav_href, ttl.Full_url(), nav_text);
// print text if 1st / zth page; else, print html
if ( ( type_is_next && grp.Bgn() + grp_max > grp.Itms__len())
|| (!type_is_next && grp.Bgn() - grp_max < 0)
)
Fmt__nav__text.Bld_many(bfr, nav_text);
else
Fmt__nav__href.Bld_many(bfr, nav_href, ttl.Full_url(), nav_text);
}
public static int Grp__max = 200;
private static final Bry_fmt
Fmt__nav = Bry_fmt.Auto_nl_skip_last
( ""
, " (<a href=\"~{nav_href}\" class=\"xowa_nav\" title=\"~{nav_title}\">~{nav_text}</a>)"
)
Fmt__nav__href = Bry_fmt.New("\n(<a href=\"~{nav_href}\" class=\"xowa_nav\" title=\"~{nav_title}\">~{nav_text}</a>)")
, Fmt__nav__text = Bry_fmt.New("\n(~{nav_text})")
, Fmt__ctg = Bry_fmt.Auto_nl_skip_last
( ""
, "<div id=\"~{div_id}\">"
@ -104,7 +107,7 @@ public class Xoctg_fmt_grp { // subc|page|file
, " </div>~{nav_html}"
, "</div>"
);
public static Xoctg_fmt_grp New__subc() {return new Xoctg_fmt_grp(Xoa_ctg_mgr.Tid_subc, new Xoctg_fmt_itm_subc(), Xol_msg_itm_.Id_ctg_subc_header, Xol_msg_itm_.Id_ctg_subc_count, Xoctg_catpage_url.Url_arg_subc_bgn, Xoctg_catpage_url.Url_arg_subc_end, Bry_.new_a7("mw-subcategories"));}
public static Xoctg_fmt_grp New__page() {return new Xoctg_fmt_grp(Xoa_ctg_mgr.Tid_page, new Xoctg_fmt_itm_page(), Xol_msg_itm_.Id_ctg_page_header, Xol_msg_itm_.Id_ctg_page_count, Xoctg_catpage_url.Url_arg_page_bgn, Xoctg_catpage_url.Url_arg_page_end, Bry_.new_a7("mw-pages"));}
public static Xoctg_fmt_grp New__file() {return new Xoctg_fmt_grp(Xoa_ctg_mgr.Tid_file, new Xoctg_fmt_itm_file(), Xol_msg_itm_.Id_ctg_file_header, Xol_msg_itm_.Id_ctg_file_count, Xoctg_catpage_url.Url_arg_file_bgn, Xoctg_catpage_url.Url_arg_file_end, Bry_.new_a7("mw-category-media"));}
public static Xoctg_fmt_grp New__subc() {return new Xoctg_fmt_grp(Xoa_ctg_mgr.Tid__subc, new Xoctg_fmt_itm_subc(), Xol_msg_itm_.Id_ctg_subc_header, Xol_msg_itm_.Id_ctg_subc_count, Xoctg_catpage_url_parser.Bry__arg_subc_bgn, Xoctg_catpage_url_parser.Bry__arg_subc_end, Bry_.new_a7("mw-subcategories"));}
public static Xoctg_fmt_grp New__page() {return new Xoctg_fmt_grp(Xoa_ctg_mgr.Tid__page, new Xoctg_fmt_itm_page(), Xol_msg_itm_.Id_ctg_page_header, Xol_msg_itm_.Id_ctg_page_count, Xoctg_catpage_url_parser.Bry__arg_page_bgn, Xoctg_catpage_url_parser.Bry__arg_page_end, Bry_.new_a7("mw-pages"));}
public static Xoctg_fmt_grp New__file() {return new Xoctg_fmt_grp(Xoa_ctg_mgr.Tid__file, new Xoctg_fmt_itm_file(), Xol_msg_itm_.Id_ctg_file_header, Xol_msg_itm_.Id_ctg_file_count, Xoctg_catpage_url_parser.Bry__arg_file_bgn, Xoctg_catpage_url_parser.Bry__arg_file_end, Bry_.new_a7("mw-category-media"));}
}

@ -29,7 +29,7 @@ public abstract class Xoctg_fmt_itm_base implements gplx.core.brys.Bfr_arg {
public int Loop_end_idx() {return loop_end_idx;} private int loop_end_idx;
public boolean Loop_ends_at_col() {return loop_ends_at_col;} private boolean loop_ends_at_col;
public void Col_end_(int col_bgn, int col_idx) {
this.col_end = col_bgn + Calc_col_len(grp.Len(), col_idx, Cols_max);
this.col_end = col_bgn + Calc_col_len(grp.Count_by_page(), col_idx, Cols_max);
}
public void Init_from_ltr(Xow_wiki wiki, Xoctg_catpage_grp grp) {this.wiki = wiki; this.grp = grp;}
public void Set_ltr_and_bgn(byte[] ltr_cur, int loop_bgn) {this.ltr_cur = ltr_cur; this.loop_bgn = loop_bgn;}
@ -37,10 +37,10 @@ public abstract class Xoctg_fmt_itm_base implements gplx.core.brys.Bfr_arg {
// init vars
Xoh_href_parser href_parser = wiki.App().Html__href_parser();
Xou_history_mgr history_mgr = wiki.App().User().History_mgr();
int len = grp.Len();
int grp_end = grp.End();
// loop over itms;
for (int i = loop_bgn; i < len; i++) {
for (int i = loop_bgn; i < grp_end; i++) {
// reached end of col; exit
if (i == col_end) {
loop_end_idx = i;
@ -49,7 +49,7 @@ public abstract class Xoctg_fmt_itm_base implements gplx.core.brys.Bfr_arg {
}
// get sortkey
Xoctg_catpage_itm itm = grp.Itms()[i];
Xoctg_catpage_itm itm = grp.Itms__get_at(i);
byte[] itm_sortkey = itm.Sort_key();
// reached end of ltr; exit
@ -61,7 +61,7 @@ public abstract class Xoctg_fmt_itm_base implements gplx.core.brys.Bfr_arg {
Bld_html(bfr, wiki, history_mgr, href_parser, itm, itm.Page_ttl());
}
loop_end_idx = len;
loop_end_idx = grp_end;
loop_ends_at_col = true;
}
@gplx.Virtual public void Bld_html(Bry_bfr bfr, Xow_wiki wiki, Xou_history_mgr history_mgr, Xoh_href_parser href_parser, Xoctg_catpage_itm itm, Xoa_ttl ttl) {

@ -32,16 +32,17 @@ public class Xoctg_fmt_ltr implements gplx.core.brys.Bfr_arg { // "A", "B", "C c
itm_fmt.Init_from_ltr(wiki, grp);
}
public void Bfr_arg__add(Bry_bfr bfr) {
int itms_len = grp.Len(); if (itms_len == 0) return; // no items; exit
int itm_idx = grp.Bgn(); // itm idx; EX: idx=201 in len=500
int itm_end = grp.End();
int itms_len = itm_end - itm_idx; if (itms_len == 0) return; // no items; exit
int col_idx = 0; // col idx; EX: 3 cols; idx = 0, 1, 2
boolean start_new_col = true;
byte[] ltr_prv = Bry_.Empty;
// loop itms until no more itms
while (itm_idx < itms_len) {
Xoctg_catpage_itm itm = grp.Itms()[itm_idx];
while (itm_idx < itm_end) {
Xoctg_catpage_itm itm = grp.Itms__get_at(itm_idx);
// get ltr_head; EX: "C" or "C cont."
byte[] itm_sortkey = itm.Sort_key();

@ -0,0 +1,23 @@
/*
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.addons.wikis.ctgs.htmls.catpages.urls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
public class Xoctg_catpage_url {
public Xoctg_catpage_url(byte[][] keys, boolean[] fwds) {this.keys = keys; this.fwds = fwds;}
public byte[][] Grp_keys() {return keys;} private final byte[][] keys;
public boolean[] Grp_fwds() {return fwds;} private final boolean[] fwds;
}

@ -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 <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.addons.wikis.ctgs.htmls.catpages.urls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import org.junit.*; import gplx.core.tests.*; import gplx.xowa.apps.urls.*;
public class Xoctg_catpage_url__tst {
@Before public void init() {fxt.Clear();} private Xoctg_catpage_url__fxt fxt = new Xoctg_catpage_url__fxt();
@Test public void Specific() {
fxt.Exec__parse("A?subcatfrom=B&filefrom=C&pagefrom=D" ).Test__keys("B", "C", "D").Test__fwds(Bool_.Y, Bool_.Y, Bool_.Y);
fxt.Exec__parse("A?subcatuntil=B&fileuntil=C&pageuntil=D" ).Test__keys("B", "C", "D").Test__fwds(Bool_.N, Bool_.N, Bool_.N);
}
@Test public void General() {
fxt.Exec__parse("A?from=B" ).Test__keys("B", "B", "B").Test__fwds(Bool_.Y, Bool_.Y, Bool_.Y);
fxt.Exec__parse("A?until=B" ).Test__keys("B", "B", "B").Test__fwds(Bool_.N, Bool_.N, Bool_.N);
}
@Test public void Url_encoded() {
fxt.Exec__parse("A?from=B+C").Test__keys("B C", "B C", "B C").Test__fwds(Bool_.Y, Bool_.Y, Bool_.Y);
}
}
class Xoctg_catpage_url__fxt {
private Xow_url_parser xo_url_parser; private Xoctg_catpage_url ctg_url;
public void Clear() {
Xoa_app app = Xoa_app_fxt.Make__app__edit();
this.xo_url_parser = app.User().Wikii().Utl__url_parser();
}
public Xoctg_catpage_url__fxt Exec__parse(String url_str) {
Xoa_url page_url = xo_url_parser.Parse(Bry_.new_u8(url_str));
this.ctg_url = Xoctg_catpage_url_parser.Parse(page_url);
return this;
}
public Xoctg_catpage_url__fxt Test__keys(String... expd) {Gftest.Eq__ary(Bry_.Ary(expd), ctg_url.Grp_keys(), "keys"); return this;}
public Xoctg_catpage_url__fxt Test__fwds(boolean... expd) {Gftest.Eq__ary(expd, ctg_url.Grp_fwds(), "fwds"); return this;}
}

@ -0,0 +1,90 @@
/*
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.addons.wikis.ctgs.htmls.catpages.urls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import gplx.core.net.*; import gplx.core.net.qargs.*;
import gplx.langs.htmls.encoders.*;
public class Xoctg_catpage_url_parser {
public static Xoctg_catpage_url Parse(Xoa_url url) {
Gfo_qarg_itm[] args = url.Qargs_ary();
if (args == null) return null;
// init caturl structs
byte[][] keys = new byte[Xoa_ctg_mgr.Tid___max][];
boolean[] fwds = new boolean[Xoa_ctg_mgr.Tid___max];
Bry_bfr tmp_bfr = Bry_bfr_.New();
// loop qargs; EX: "?subcatfrom=B&filefrom=C&pagefrom=D"
int len = args.length;
for (int i = 0; i < len; ++i) {
Gfo_qarg_itm arg = args[i];
// get tid from arg; EX: "pagefrom" -> Tid__page_bgn
byte[] key = arg.Key_bry();
byte tid = Key_hash.Get_as_byte_or(key, Byte_ascii.Max_7_bit);
if (tid == Byte_ascii.Max_7_bit) { // if invalid, warn and skip
Gfo_usr_dlg_.Instance.Warn_many("", "", "catpage:unknown url arg: raw~={0} key=~{1}", url.To_bry(true, true), key);
continue;
}
// set val
byte[] val = arg.Val_bry();
Gfo_url_encoder_.Http_url.Decode(tmp_bfr, Bool_.N, val, 0, val.length);
val = tmp_bfr.To_bry_and_clear();
// set struct
switch (tid) {
case Tid__each_bgn: Set_grp(keys, fwds, val, Bool_.Y, Xoa_ctg_mgr.Tid__subc, Xoa_ctg_mgr.Tid__file, Xoa_ctg_mgr.Tid__page); break; // if "from", default all grps to val; DATE:2014-02-05
case Tid__each_end: Set_grp(keys, fwds, val, Bool_.N, Xoa_ctg_mgr.Tid__subc, Xoa_ctg_mgr.Tid__file, Xoa_ctg_mgr.Tid__page); break;
case Tid__subc_bgn: Set_grp(keys, fwds, val, Bool_.Y, Xoa_ctg_mgr.Tid__subc); break;
case Tid__subc_end: Set_grp(keys, fwds, val, Bool_.N, Xoa_ctg_mgr.Tid__subc); break;
case Tid__file_bgn: Set_grp(keys, fwds, val, Bool_.Y, Xoa_ctg_mgr.Tid__file); break;
case Tid__file_end: Set_grp(keys, fwds, val, Bool_.N, Xoa_ctg_mgr.Tid__file); break;
case Tid__page_bgn: Set_grp(keys, fwds, val, Bool_.Y, Xoa_ctg_mgr.Tid__page); break;
case Tid__page_end: Set_grp(keys, fwds, val, Bool_.N, Xoa_ctg_mgr.Tid__page); break;
}
}
return new Xoctg_catpage_url(keys, fwds);
}
private static void Set_grp(byte[][] keys, boolean[] fwds, byte[] key, boolean fwd, byte... tids) {
int len = tids.length;
for (int i = 0; i < len; ++i) {
byte tid = tids[i];
keys[tid] = key;
fwds[tid] = fwd;
}
}
private static final byte
Tid__each_bgn = 0, Tid__each_end = 1
, Tid__subc_bgn = 2, Tid__subc_end = 3
, Tid__file_bgn = 4, Tid__file_end = 5
, Tid__page_bgn = 6, Tid__page_end = 7
;
public static final byte[]
Bry__arg_each_bgn = Bry_.new_a7("from") , Bry__arg_each_end = Bry_.new_a7("until")
, Bry__arg_subc_bgn = Bry_.new_a7("subcatfrom") , Bry__arg_subc_end = Bry_.new_a7("subcatuntil")
, Bry__arg_page_bgn = Bry_.new_a7("pagefrom") , Bry__arg_page_end = Bry_.new_a7("pageuntil")
, Bry__arg_file_bgn = Bry_.new_a7("filefrom") , Bry__arg_file_end = Bry_.new_a7("fileuntil")
;
private static final Hash_adp_bry Key_hash = Hash_adp_bry.ci_a7()
.Add_bry_byte(Bry__arg_each_bgn , Tid__each_bgn) .Add_bry_byte(Bry__arg_each_end , Tid__each_end)
.Add_bry_byte(Bry__arg_subc_bgn , Tid__subc_bgn) .Add_bry_byte(Bry__arg_subc_end , Tid__subc_end)
.Add_bry_byte(Bry__arg_page_bgn , Tid__page_bgn) .Add_bry_byte(Bry__arg_page_end , Tid__page_end)
.Add_bry_byte(Bry__arg_file_bgn , Tid__file_bgn) .Add_bry_byte(Bry__arg_file_end , Tid__file_end)
;
}

@ -0,0 +1,62 @@
/*
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.addons.wikis.ctgs.htmls.catpages.utls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import gplx.core.lists.binary_searches.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.urls.*;
public class Xoctg_catpage_filter {
public static void Filter(int limit, Xoctg_catpage_url cat_url, Xoctg_catpage_ctg ctg) {
int len = Xoa_ctg_mgr.Tid___max;
for (byte i = 0; i < len; ++i) {
Filter_by_grp(limit, cat_url, ctg.Grp_by_tid(i));
}
}
private static void Filter_by_grp(int grp_len, Xoctg_catpage_url cat_url, Xoctg_catpage_grp grp) {
byte grp_tid = grp.Tid();
byte[] grp_key = cat_url.Grp_keys()[grp_tid];
// dflt to bos; EX: grp_bgn=0 grp_end=200
int grp_bgn = 0;
int grp_end = grp_bgn + grp_len;
// key specified; calc new grp_bgn, grp_end
if (grp_key != null) {
// get idx of key
int key_idx = Binary_search_.Search(grp.Itms(), Xoctg_catpage_itm_sorter__sort_key.Sorter, grp_key);
// if fwd, set grp_bgn to key_idx, and add grp_len
if (cat_url.Grp_fwds()[grp_tid]) {
grp_bgn = key_idx;
grp_end = grp_bgn + grp_len;
}
// if bwd, set grp_end to key_idx, and subtract grp_len
else {
grp_end = key_idx;
grp_bgn = grp_end - grp_len;
// assert new grp_bgn is not negative
if (grp_bgn < 0) grp_bgn = 0;
}
}
// assert new grp_end is not > grp_max; note that this needs to be specified for when grp_key is null and not null
int grp_max = grp.Itms__len();
if (grp_end > grp_max)
grp_end = grp_max;
grp.Rng_(grp_bgn, grp_end);
}
}

@ -0,0 +1,107 @@
/*
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.addons.wikis.ctgs.htmls.catpages.utls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.xowa.apps.urls.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.urls.*;
public class Xoctg_catpage_filter__tst {
private final Xoctg_catpage_filter__fxt fxt = new Xoctg_catpage_filter__fxt();
private Xoctg_catpage_ctg ctg;
@Before public void init() {
this.ctg = fxt.Make__ctg(25, 25, 25);
}
@Test public void Initial() {
fxt.Exec__filter(5, "A", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 0, 5);
}
@Test public void Fwd__page__05() {
fxt.Exec__filter(5, "A?pagefrom=05", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 5, 10);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 0, 5);
}
@Test public void Fwd__page__10() {
fxt.Exec__filter(5, "A?pagefrom=10", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 10, 15);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 0, 5);
}
@Test public void Fwd__page__23() {
fxt.Exec__filter(5, "A?pagefrom=23", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 23, 25);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 0, 5);
}
@Test public void Fwd__full__06() {
fxt.Exec__filter(5, "A?from=06", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 6, 11);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 6, 11);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 6, 11);
}
@Test public void Bwd__page__20() {
fxt.Exec__filter(5, "A?pageuntil=20", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 15, 20);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 0, 5);
}
@Test public void Bwd__page__2() {
fxt.Exec__filter(5, "A?pageuntil=01", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 0, 1);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 0, 5);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 0, 5);
}
@Test public void Bwd__full__11() {
fxt.Exec__filter(5, "A?until=11", ctg);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__page, 6, 11);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__subc, 6, 11);
fxt.Test__cat_grp(ctg, Xoa_ctg_mgr.Tid__file, 6, 11);
}
}
class Xoctg_catpage_filter__fxt {
private Xow_url_parser url_parser;
public Xoctg_catpage_filter__fxt() {
Xoa_app app = Xoa_app_fxt.Make__app__edit();
this.url_parser = app.User().Wikii().Utl__url_parser();
}
public Xoctg_catpage_ctg Make__ctg(int subc, int page, int file) {
Xoctg_catpage_ctg ctg = new Xoctg_catpage_ctg(Bry_.new_a7("A"));
Make__ctg_grp(ctg, Xoa_ctg_mgr.Tid__subc, subc);
Make__ctg_grp(ctg, Xoa_ctg_mgr.Tid__page, page);
Make__ctg_grp(ctg, Xoa_ctg_mgr.Tid__file, file);
return ctg;
}
private void Make__ctg_grp(Xoctg_catpage_ctg ctg, byte tid, int count) {
Xoctg_catpage_grp grp = ctg.Grp_by_tid(tid);
for (int i = 0; i < count; ++i) {
Xoctg_catpage_itm itm = new Xoctg_catpage_itm(i * tid, Xoa_ttl.Null, Bry_.new_a7(Int_.To_str_pad_bgn_zero(i, 2)));
grp.Itms__add(itm);
}
grp.Itms__make();
}
public void Exec__filter(int limit, String cat_url_str, Xoctg_catpage_ctg ctg) {
Xoctg_catpage_url cat_url = Xoctg_catpage_url_parser.Parse(url_parser.Parse(Bry_.new_a7(cat_url_str)));
Xoctg_catpage_filter.Filter(limit, cat_url, ctg);
}
public void Test__cat_grp(Xoctg_catpage_ctg ctg, byte tid, int expd_bgn, int expd_end) {
Xoctg_catpage_grp grp = ctg.Grp_by_tid(tid);
Gftest.Eq__int(expd_bgn, grp.Bgn(), "bgn failed; tid={0}", tid);
Gftest.Eq__int(expd_end, grp.End(), "end failed; tid={0}", tid);
}
}

@ -15,10 +15,11 @@ 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.addons.wikis.ctgs.htmls.catpages; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*;
package gplx.xowa.addons.wikis.ctgs.htmls.catpages.utls; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.ctgs.*; import gplx.xowa.addons.wikis.ctgs.htmls.*; import gplx.xowa.addons.wikis.ctgs.htmls.catpages.*;
import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.addons.wikis.ctgs.dbs.*;
import gplx.xowa.addons.wikis.ctgs.htmls.catpages.doms.*;
class Xoctg_catpage_loader {
public class Xoctg_catpage_loader {
private static final Object thread_lock = new Object();
public Xoctg_catpage_ctg Load_by_ttl_or_null(Xow_wiki wiki, Xoa_ttl cat_ttl) {
// get cat_id for cat_ttl from page_tbl
Xow_db_mgr db_mgr = wiki.Data__core_mgr();
@ -34,7 +35,7 @@ class Xoctg_catpage_loader {
int cat_id = page_itm.Id();
Xowd_category_itm cat_core_itm = cat_core_tbl.Select(cat_id);
if (cat_core_itm == Xowd_category_itm.Null) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "category does not exist in cat_core table; ttl=~{0}", cat_ttl.Full_db());
Gfo_usr_dlg_.Instance.Log_many("", "", "category does not exist in cat_core table; ttl=~{0}", cat_ttl.Full_db()); // NOTE: this is not rare as Category pages can be created as deliberately empty, or as redirects; fr.w:Catégorie:Utilisateur_hess-4; DATE:2016-09-12
return null;
}
@ -72,21 +73,23 @@ class Xoctg_catpage_loader {
// prep sql
Db_attach_mgr attach_mgr = new Db_attach_mgr(cat_link_conn, new Db_attach_itm("page_db", page_conn), new Db_attach_itm("cat_core_db", cat_core_conn));
sql = attach_mgr.Resolve_sql(sql);
attach_mgr.Attach();
// run sql and create itms based on cat_link
Db_rdr rdr = Db_rdr_.Empty;
try {
rdr = cat_link_conn.Stmt_sql(sql).Exec_select__rls_auto();
while (rdr.Move_next()) {
Xoa_ttl page_ttl = wiki.Ttl_parse(rdr.Read_int("page_namespace"), rdr.Read_bry_by_str("page_title"));
Xoctg_catpage_itm itm = new Xoctg_catpage_itm(rdr.Read_int("cl_from"), page_ttl, Bry_.new_u8(rdr.Read_str("cl_sortkey")));
rv.Grp_by_tid(rdr.Read_byte("cl_type_id")).Itms__add(itm);
synchronized (thread_lock) { // LOCK:used by multiple wrks; DATE:2016-09-12
try {
attach_mgr.Attach();
rdr = cat_link_conn.Stmt_sql(sql).Exec_select__rls_auto();
while (rdr.Move_next()) {
Xoa_ttl page_ttl = wiki.Ttl_parse(rdr.Read_int("page_namespace"), rdr.Read_bry_by_str("page_title"));
Xoctg_catpage_itm itm = new Xoctg_catpage_itm(rdr.Read_int("cl_from"), page_ttl, Bry_.new_u8(rdr.Read_str("cl_sortkey")));
rv.Grp_by_tid(rdr.Read_byte("cl_type_id")).Itms__add(itm);
}
}
finally {
rdr.Rls();
attach_mgr.Detach();
}
}
finally {
rdr.Rls();
attach_mgr.Detach();
}
}
private static String Sql_for_v3(int cat_id) {

@ -23,7 +23,7 @@ class Xoctg_pagebox_hash {
public int Len() {return hash_by_ttl.Len();}
public Xoctg_pagebox_itm Get_at(int i) {return (Xoctg_pagebox_itm)hash_by_ttl.Get_at(i);}
public Xoctg_pagebox_itm Get_by_ttl(byte[] full_db) {return (Xoctg_pagebox_itm)hash_by_ttl.Get_by(full_db);}
public Xoctg_pagebox_itm Get_by_id(int page_id) {return (Xoctg_pagebox_itm)hash_by_id.Get_by(page_id);}
public Xoctg_pagebox_itm Get_by_id(int page_id) {return (Xoctg_pagebox_itm)hash_by_id.Get_by_or_fail(page_id);}
public Xoctg_pagebox_itm[] To_ary_and_clear() {
hash_by_id.Clear();
return (Xoctg_pagebox_itm[])hash_by_ttl.To_ary_and_clear(Xoctg_pagebox_itm.class);

@ -16,9 +16,9 @@ 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.addons.wikis.pages.syncs.core.loaders; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.wikis.*; import gplx.xowa.addons.wikis.pages.*; import gplx.xowa.addons.wikis.pages.syncs.*; import gplx.xowa.addons.wikis.pages.syncs.core.*;
import gplx.core.brys.*;
import gplx.core.brys.*; import gplx.core.btries.*;
import gplx.langs.htmls.*; import gplx.xowa.htmls.*; import gplx.langs.htmls.docs.*; import gplx.xowa.htmls.core.wkrs.*; import gplx.xowa.htmls.core.wkrs.imgs.atrs.*;
import gplx.xowa.files.*; import gplx.xowa.files.repos.*;
import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.files.imgs.*;
import gplx.xowa.wikis.domains.*;
import gplx.xowa.addons.wikis.pages.syncs.core.parsers.*;
public class Xosync_page_loader {
@ -36,6 +36,7 @@ public class Xosync_page_loader {
// loop for all <img>
int pos = 0;
Btrie_rv trv = new Btrie_rv();
while (true) {
// get next "<img>"
Gfh_tag img_tag = tag_rdr.Tag__find_fwd_head(pos, src_len, Gfh_tag_.Id__img);
@ -52,22 +53,16 @@ public class Xosync_page_loader {
// do simple replace for @src
Gfh_atr img_src_atr = img_tag.Atrs__get_by_or_fail(Gfh_atr_.Bry__src);
byte[] img_src_val = img_src_atr.Val();
img_src_val = Bry_.Replace(img_src_val, Xosync_img_src_parser.Bry__xowa_src_bgn, wiki.App().Fsys_mgr().File_dir().To_http_file_bry());
// parse other atrs for fsdb
img_src_parser.Parse(err_wkr, hctx, wiki.Domain_bry(), img_src_atr.Val_bgn(), img_src_atr.Val_end());
if (img_src_parser.File_ttl_bry() != null) { // NOTE: need to skip images that don't follow MW image format ("commons.wikimedia.org/thumb/7/70/A.png"); for example, math images
Xof_fsdb_itm img = hpg.Img_mgr().Make_img(false);
byte[] file_ttl_bry = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url.Decode(img_src_parser.File_ttl_bry());
img.Init_by_wm_parse(hctx.Wiki__domain_itm().Abrv_xo(), img_src_parser.Repo_is_commons(), img_src_parser.File_is_orig(), file_ttl_bry, img_src_parser.File_w(), img_src_parser.File_time(), img_src_parser.File_page());
hctx.File__url_bldr().Init_by_root(img_src_parser.Repo_is_commons() ? hctx.Fsys__file__comm() : hctx.Fsys__file__wiki(), Bool_.N, Byte_ascii.Slash, Bool_.N, Bool_.N, 4);
hctx.File__url_bldr().Init_by_itm(img_src_parser.File_is_orig() ? Xof_repo_itm_.Mode_orig : Xof_repo_itm_.Mode_thumb, file_ttl_bry, Xof_file_wkr_.Md5(file_ttl_bry), Xof_ext_.new_by_ttl_(file_ttl_bry), img_src_parser.File_w(), img_src_parser.File_time(), img_src_parser.File_page());
img.Orig_repo_name_(img_src_parser.Repo_is_commons() ? Xow_domain_itm_.Bry__commons : wiki.Domain_bry());
Io_url html_view_url = hctx.File__url_bldr().Xto_url_by_http();
img.Init_at_gallery_end(img_tag.Atrs__get_as_int(Gfh_atr_.Bry__width), img_tag.Atrs__get_as_int(Gfh_atr_.Bry__height), html_view_url, html_view_url);
Xosync_hdoc_parser.Write_img_tag(tmp_bfr, img_tag, img_src_val, img.Html_uid());
byte path_tid = Xosync_img_src_parser.Src_xo_trie.Match_byte_or(trv, img_src_val, Xosync_img_src_parser.Path__unknown);
switch (path_tid) {
case Xosync_img_src_parser.Path__file:
Add_img(wiki, hpg, img_tag, img_src_atr, img_src_val, path_tid, Xosync_img_src_parser.Bry__xowa_file, wiki.App().Fsys_mgr().File_dir().To_http_file_bry());
break;
case Xosync_img_src_parser.Path__math:
Add_img(wiki, hpg, img_tag, img_src_atr, img_src_val, path_tid, Xosync_img_src_parser.Bry__xowa_math, wiki.App().Fsys_mgr().File_dir().GenSubDir_nest("math").To_http_file_bry());
break;
}
pos = img_tag.Src_end();
}
@ -76,4 +71,41 @@ public class Xosync_page_loader {
hpg.Db().Html().Html_bry_(src);
return src;
}
private Xof_fsdb_itm Add_img(Xow_wiki wiki, Xoh_page hpg, Gfh_tag img_tag, Gfh_atr img_src_atr, byte[] img_src_val, byte path_tid, byte[] src_find, byte[] src_repl) {
// replace "xowa:/file" with "file:////xowa/file/"
img_src_val = Bry_.Replace(img_src_val, src_find, src_repl);
// parse src
img_src_parser.Parse(err_wkr, hctx, wiki.Domain_bry(), img_src_atr.Val_bgn(), img_src_atr.Val_end());
if (img_src_parser.File_ttl_bry() == null) return null; // skip images that don't follow format of "commons.wikimedia.org/thumb/7/70/A.png"; for example, enlarge buttons
// create img
Xof_fsdb_itm img = hpg.Img_mgr().Make_img(false);
// use repo_tid to get fsys_root, orig_repo_name
byte repo_tid = img_src_parser.Repo_tid();
byte[] orig_repo_name = null, fsys_root = null;
switch (repo_tid) {
case Xof_repo_tid_.Tid__remote: fsys_root = hctx.Fsys__file__comm(); orig_repo_name = Xow_domain_itm_.Bry__commons; break;
case Xof_repo_tid_.Tid__local: fsys_root = hctx.Fsys__file__wiki(); orig_repo_name = wiki.Domain_bry(); break;
case Xof_repo_tid_.Tid__math: fsys_root = hctx.Fsys__file__math(); orig_repo_name = Xof_repo_tid_.Bry__math; break;
}
// set vals
img.Orig_repo_name_(orig_repo_name);
byte[] file_ttl_bry = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url.Decode(img_src_parser.File_ttl_bry());
Xof_ext file_ext = Xosync_img_src_parser.Ext_by_ttl(file_ttl_bry, repo_tid);
img.Init_by_wm_parse(hctx.Wiki__domain_itm().Abrv_xo(), img_src_parser.Repo_is_commons(), img_src_parser.File_is_orig(), file_ttl_bry, file_ext, img_src_parser.File_w(), img_src_parser.File_time(), img_src_parser.File_page());
// recalc src based on "file:////xowa/file/"
hctx.File__url_bldr().Init_by_repo(repo_tid, fsys_root, Bool_.N, Byte_ascii.Slash, Bool_.N, Bool_.N, 4);
hctx.File__url_bldr().Init_by_itm(img_src_parser.File_is_orig() ? Xof_img_mode_.Tid__orig : Xof_img_mode_.Tid__thumb, file_ttl_bry, Xof_file_wkr_.Md5(file_ttl_bry), Xof_ext_.new_by_ttl_(file_ttl_bry), img_src_parser.File_w(), img_src_parser.File_time(), img_src_parser.File_page());
Io_url html_view_url = hctx.File__url_bldr().Xto_url_by_http();
// if (path_tid == Xosync_img_src_parser.Path__file)
img.Init_at_gallery_end(img_tag.Atrs__get_as_int_or(Gfh_atr_.Bry__width,0), img_tag.Atrs__get_as_int_or(Gfh_atr_.Bry__height, 0), html_view_url, html_view_url);
Xosync_hdoc_parser.Write_img_tag(tmp_bfr, img_tag, img_src_val, img.Html_uid());
return img;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save