1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2014-06-30 00:04:32 -04:00
parent 85594d3cdd
commit bae88e739c
2482 changed files with 198730 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.ios.*;
public abstract class Xof_img_wkr_api_size_base {
public boolean Api_query_size(Xof_img_wkr_api_size_base_rslts rv, Xow_wiki wiki, byte[] ttl, int width, int height) {
Gfo_usr_dlg usr_dlg = wiki.App().Usr_dlg();
Xow_repo_mgr repo_mgr = wiki.File_mgr().Repo_mgr();
int len = repo_mgr.Repos_len();
for (int i = 0; i < len; i++) {
Xof_repo_pair repo_pair = repo_mgr.Repos_get_at(i);
if (Api_query_size_exec(rv, wiki, ttl, width, height, usr_dlg, repo_pair.Wiki_key())) return true;
}
usr_dlg.Warn_many(Xof_img_wkr_api_size_base_wmf.GRP_KEY, "download_failed", "download_failed: ~{0}", String_.new_utf8_(ttl));
return false;
}
public abstract boolean Api_query_size_exec(Xof_img_wkr_api_size_base_rslts rv, Xow_wiki wiki, byte[] ttl, int width, int height, Gfo_usr_dlg usr_dlg, byte[] repo_wiki_key);
}

View File

@@ -0,0 +1,41 @@
/*
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; import gplx.*;
public class Xof_img_wkr_api_size_base_fxt {
Xoa_app app; Xow_wiki wiki; Xof_img_wkr_api_size_base_rslts rv = new Xof_img_wkr_api_size_base_rslts();
public void Clear() {
this.app = Xoa_app_fxt.app_();
this.wiki = Xoa_app_fxt.wiki_tst_(app);
}
public void Bld_api_url_tst(String ttl_str, int w, int h, String expd) {
String actl = Xof_img_wkr_api_size_base_wmf.Bld_api_url(wiki.Domain_bry(), Bry_.new_utf8_(ttl_str), w, h);
Tfds.Eq(expd, actl);
}
public void Parse_size_tst(String xml_str, int expd_w, int expd_h) {
byte[] xml_bry = Bry_.new_utf8_(xml_str);
Xof_img_wkr_api_size_base_wmf.Parse_xml(rv, app.Usr_dlg(), xml_bry);
Tfds.Eq(expd_w, rv.Orig_w());
Tfds.Eq(expd_h, rv.Orig_h());
}
public void Parse_reg_tst(String xml_str, String expd_wiki, String expd_page) {
byte[] xml_bry = Bry_.new_utf8_(xml_str);
Xof_img_wkr_api_size_base_wmf.Parse_xml(rv, app.Usr_dlg(), xml_bry);
Tfds.Eq(expd_wiki, String_.new_utf8_(rv.Reg_wiki()));
Tfds.Eq(expd_page, String_.new_utf8_(rv.Reg_page()));
}
}

View File

@@ -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; import gplx.*;
public class Xof_img_wkr_api_size_base_mok extends Xof_img_wkr_api_size_base {
public Xof_img_wkr_api_size_base_mok Ini(String wiki_str, String ttl_str, String redirect_str, int orig_w, int orig_h, boolean pass) {
this.wiki_str = wiki_str; this.ttl_str = ttl_str; this.redirect_str = redirect_str; this.orig_w = orig_w; this.orig_h = orig_h; this.fail = !pass;
return this;
} String wiki_str = ""; String ttl_str = ""; String redirect_str = ""; int orig_w; int orig_h; boolean fail = false;
public void Clear() {wiki_str = ttl_str = redirect_str = ""; orig_w = orig_h = 0;}
@Override public boolean Api_query_size_exec(Xof_img_wkr_api_size_base_rslts rv, Xow_wiki wiki, byte[] ttl, int width, int height, Gfo_usr_dlg usr_dlg, byte[] repo_wiki_key) {
if (!Bry_.Eq(ttl, Bry_.new_utf8_(ttl_str))) return false;
if (!String_.Eq(wiki_str, String_.new_ascii_(repo_wiki_key))) return false;
if (fail) return false;
rv.Orig_w_(orig_w);
rv.Orig_h_(orig_h);
rv.Reg_wiki_(repo_wiki_key);
rv.Reg_page_(String_.Eq(redirect_str, "") ? ttl : Bry_.new_utf8_(redirect_str));
return true;
}
public static final Xof_img_wkr_api_size_base_mok _ = new Xof_img_wkr_api_size_base_mok(); Xof_img_wkr_api_size_base_mok() {}
}

View File

@@ -0,0 +1,28 @@
/*
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; import gplx.*;
public class Xof_img_wkr_api_size_base_rslts {
public int Orig_w() {return orig_w;} public Xof_img_wkr_api_size_base_rslts Orig_w_(int v) {orig_w = v; return this;} private int orig_w;
public int Orig_h() {return orig_h;} public Xof_img_wkr_api_size_base_rslts Orig_h_(int v) {orig_h = v; return this;} private int orig_h;
public byte[] Reg_wiki() {return reg_wiki;} public Xof_img_wkr_api_size_base_rslts Reg_wiki_(byte[] v) {reg_wiki = v; return this;} private byte[] reg_wiki;
public byte[] Reg_page() {return reg_page;} public Xof_img_wkr_api_size_base_rslts Reg_page_(byte[] v) {reg_page = v; return this;} private byte[] reg_page;
public void Clear() {
orig_w = orig_h = 0;
reg_wiki = reg_page = null;
}
}

View File

@@ -0,0 +1,38 @@
/*
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; import gplx.*;
import org.junit.*;
public class Xof_img_wkr_api_size_base_tst {
Xof_img_wkr_api_size_base_fxt fxt = new Xof_img_wkr_api_size_base_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Bld_api_url() {
fxt.Bld_api_url_tst("A.png" , 220, 110, "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&redirects&titles=File:A.png&iiurlwidth=220&iiurlheight=110");
fxt.Bld_api_url_tst("A.png" , 220, 0, "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&redirects&titles=File:A.png&iiurlwidth=220");
fxt.Bld_api_url_tst("A.png" , 0, 110, "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&redirects&titles=File:A.png"); // assert that null width does not write height
fxt.Bld_api_url_tst("A b.png" , 220, 0, "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&redirects&titles=File:A_b.png&iiurlwidth=220");
fxt.Bld_api_url_tst("A&b.png" , 220, 0, "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&redirects&titles=File:A%26b.png&iiurlwidth=220");
}
@Test public void Parse_size() {
String raw = "<api><query><pages><page ns=\"6\" title=\"File:A.png\" missing=\"\" imagerepository=\"shared\"><imageinfo><ii size=\"1234\" width=\"220\" height=\"110\" /></imageinfo></page></pages></query></api>";
fxt.Parse_size_tst(raw, 220, 110);
}
@Test public void Parse_reg() {
String raw = "<api><query><pages><page ns=\"6\" title=\"File:A.png\" missing=\"\" imagerepository=\"shared\"><imageinfo><ii descriptionurl=\"http://commons.wikimedia.org/wiki/File:Berkheyde-Haarlem.png\" /></imageinfo></page></pages></query></api>";
fxt.Parse_reg_tst(raw, "commons.wikimedia.org", "Berkheyde-Haarlem.png");
}
}

View File

@@ -0,0 +1,87 @@
/*
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; import gplx.*;
public class Xof_img_wkr_api_size_base_wmf extends Xof_img_wkr_api_size_base {
@Override public boolean Api_query_size_exec(Xof_img_wkr_api_size_base_rslts rv, Xow_wiki wiki, byte[] ttl, int width, int height, Gfo_usr_dlg usr_dlg, byte[] repo_wiki_key) {
String src = Bld_api_url(repo_wiki_key, ttl, width, height);
// xrg.Prog_fmt_hdr_(); // NOTE: do not uncomment; api will reuse whatever's in place
byte[] xml = wiki.App().File_mgr().Download_mgr().Download_wkr().Download_xrg().Exec_as_bry(src);
return xml == null ? false : Parse_xml(rv, usr_dlg, xml);
}
public static boolean Parse_xml(Xof_img_wkr_api_size_base_rslts rv, Gfo_usr_dlg usr_dlg, byte[] xml) {
rv.Clear();
int xml_len = xml.length;
int pos = 0;
pos = Bry_finder.Find_fwd(xml, Bry_xml_ii , pos, xml_len); if (pos == Bry_.NotFound) return Parse_xml_failed(usr_dlg, xml);
pos += Bry_xml_ii.length;
if (Parse_xml_val(parse_xml_rng, usr_dlg, xml, xml_len, pos, Bry_xml_width))
rv.Orig_w_(Bry_.X_to_int_or(xml, parse_xml_rng.Val_0(), parse_xml_rng.Val_1(), 0));
if (Parse_xml_val(parse_xml_rng, usr_dlg, xml, xml_len, pos, Bry_xml_height))
rv.Orig_h_(Bry_.X_to_int_or(xml, parse_xml_rng.Val_0(), parse_xml_rng.Val_1(), 0));
if (Parse_xml_val(parse_xml_rng, usr_dlg, xml, xml_len, pos, Bry_xml_descriptionurl)) {
byte[] file_url = Bry_.Mid(xml, parse_xml_rng.Val_0(), parse_xml_rng.Val_1());
url_parser.Parse(url, file_url, 0, file_url.length);
rv.Reg_wiki_(url.Site());
byte[] page = Xoa_ttl.Replace_spaces(url.Page());
int colon_pos = Bry_finder.Find_fwd(page, Byte_ascii.Colon, 0, page.length);
if (colon_pos != Bry_.NotFound)
page = Bry_.Mid(page, colon_pos + 1, page.length);
rv.Reg_page_(page);
}
return true;
}
private static Int_2_ref parse_xml_rng = new Int_2_ref(); static Xoa_url parse_xml_url = new Xoa_url();
private static Gfo_url_parser url_parser = new Gfo_url_parser(); static Gfo_url url = new Gfo_url();
private static boolean Parse_xml_val(Int_2_ref rv, Gfo_usr_dlg usr_dlg, byte[] xml, int xml_len, int pos, byte[] key) {
int bgn = 0, end = 0;
bgn = Bry_finder.Find_fwd(xml, key , pos, xml_len); if (bgn == Bry_.NotFound) return false;
bgn += key.length;
end = Bry_finder.Find_fwd(xml, Byte_ascii.Quote , bgn, xml_len); if (end == Bry_.NotFound) return false;
rv.Val_all_(bgn, end);
return true;
}
private static boolean Parse_xml_failed(Gfo_usr_dlg usr_dlg, byte[] xml) {usr_dlg.Log_many(GRP_KEY, "api_failed", "api failed: ~{0}", String_.new_utf8_(xml)); return false;}
public static String Bld_api_url(byte[] wiki_key, byte[] ttl, int width, int height) {
bfr .Add(Xoh_href_parser.Href_http_bry) // "http://"
.Add(wiki_key) // "commons.wikimedia.org"
.Add(Bry_api) // "/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&titles=File:"
.Add(encoder.Encode(ttl)) // "A%20B.png"
;
if (width > 0)
bfr.Add(Bry_width).Add_int_variable(width); // "&iiurlwidth=800"
if (height > 0 && width > 0) // NOTE: height cannot be used alone; width must also exist; "iiurlheight cannot be used without iiurlwidth"
bfr.Add(Bry_height).Add_int_variable(height); // "&iiurlheight=600"
return bfr.XtoStrAndClear();
}
private static Url_encoder encoder = Url_encoder.new_http_url_().Itms_raw_diff(Byte_ascii.Space, Byte_ascii.Underline);
Io_url trg = Io_url_.mem_fil_("mem/temp/api.txt");
private static final Bry_bfr bfr = Bry_bfr.new_();
private static final byte[]
Bry_api = Bry_.new_ascii_("/w/api.php?action=query&format=xml&prop=imageinfo&iiprop=size|url&redirects&titles=File:") // NOTE: using File b/c it should be canonical
, Bry_width = Bry_.new_ascii_("&iiurlwidth=")
, Bry_height = Bry_.new_ascii_("&iiurlheight=")
, Bry_xml_ii = Bry_.new_ascii_("<ii ")
, Bry_xml_width = Bry_.new_ascii_("width=\"")
, Bry_xml_height = Bry_.new_ascii_("height=\"")
, Bry_xml_descriptionurl = Bry_.new_ascii_("descriptionurl=\"")
;
public static final String GRP_KEY = "xowa.file.wmf.api";
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.gfui.*;
public interface Xof_img_wkr_query_img_size {
SizeAdp Exec(Io_url url);
}
class Xof_img_wkr_query_img_size_imageMagick implements Xof_img_wkr_query_img_size {
public Xof_img_wkr_query_img_size_imageMagick(Xoa_app app, ProcessAdp cmd) {this.app = app; this.cmd = cmd;} private Xoa_app app; ProcessAdp cmd;
public SizeAdp Exec(Io_url url) {
cmd.Prog_fmt_(String_.Replace(app.File_mgr().Download_mgr().Download_wkr().Download_xrg().Prog_fmt_hdr(), "~", "~~") + " querying: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
cmd.Run(url);
String size_str = cmd.Rslt_out();
int pos_bgn = String_.FindFwd(size_str, "<{", 0); if (pos_bgn == String_.Find_none) return SizeAdp_.Zero; // NOTE: RE: "FindFwd(,0)"; multiple frames are possible; 1st frame must be used as last frame is not accurate; EX:w.Chess:[[File:ChessCastlingMovie.gif|thumb|250px]]
int pos_end = String_.FindFwd(size_str, "}>", pos_bgn); if (pos_end == String_.Find_none) return SizeAdp_.Zero;
size_str = String_.Mid(size_str, pos_bgn + Marker_bgn_len, pos_end);
return SizeAdp_.parse_or_(size_str, SizeAdp_.Zero);
}
static final String Marker_bgn = "<{", Marker_end = "}>"; static final int Marker_bgn_len = String_.Len(Marker_bgn);
}

View File

@@ -0,0 +1,25 @@
/*
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; import gplx.*;
import gplx.gfui.*;
public class Xof_img_wkr_query_img_size_test implements Xof_img_wkr_query_img_size {
public SizeAdp Exec(Io_url url) {
ImageAdp image = ImageAdp_.txt_fil_(url);
return image.Size();
}
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xof_repo_pair implements GfoInvkAble {
public Xof_repo_pair(int id, Xof_repo_itm src, Xof_repo_itm trg, Xof_meta_mgr trg_meta_mgr, byte[] wiki_key) {
this.id = (byte)id; this.src = src; this.trg = trg; this.trg_meta_mgr = trg_meta_mgr; this.wiki_key = wiki_key;
this.repo_id = this.id;
}
public byte Id() {return id;} private byte id;
public byte Repo_id() {return repo_id;} private byte repo_id;
public Xof_repo_itm Src() {return src;} private Xof_repo_itm src;
public Xof_repo_itm Trg() {return trg;} private Xof_repo_itm trg;
public Xof_meta_mgr Trg_meta_mgr() {return trg_meta_mgr;} private Xof_meta_mgr trg_meta_mgr;
public byte[] Wiki_key() {return wiki_key;} private byte[] wiki_key;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_repo_id_)) repo_id = m.ReadByte("v");
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_repo_id_ = "repo_id_";
}

View File

@@ -0,0 +1,370 @@
/*
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; import gplx.*;
import gplx.gfui.*; import gplx.xowa.files.*;
public class Xof_xfer_mgr {
public Xof_xfer_mgr(Xof_file_mgr file_mgr) {this.file_mgr = file_mgr;} private Xof_file_mgr file_mgr;
public Xof_xfer_rslt Rslt() {return rslt;} private Xof_xfer_rslt rslt = new Xof_xfer_rslt();
public boolean Force_orig() {return force_orig;} public Xof_xfer_mgr Force_orig_(boolean v) {force_orig = v; return this;} private boolean force_orig;
public Xof_xfer_mgr Force_orig_y_() {return Force_orig_(Bool_.Y);} public Xof_xfer_mgr Force_orig_n_() {return Force_orig_(Bool_.N);}
public void Atrs_by_itm(Xof_xfer_itm xfer_itm, Xof_repo_itm src_repo, Xof_repo_itm trg_repo) {
this.xfer_itm = xfer_itm;
this.lnki_w = xfer_itm.Lnki_w(); this.lnki_h = xfer_itm.Lnki_h(); this.lnki_thumbable = xfer_itm.Lnki_thumbable(); this.lnki_thumbtime = xfer_itm.Lnki_thumbtime(); this.lnki_page = xfer_itm.Lnki_page();
this.lnki_type = xfer_itm.Lnki_type();
lnki_upright = xfer_itm.Lnki_upright();
this.ttl = xfer_itm.Lnki_ttl(); this.md5 = xfer_itm.Lnki_md5(); this.ext = xfer_itm.Lnki_ext();
orig_file_len = xfer_itm.Orig_file_len();
this.src_repo = src_repo; src_repo_is_wmf = src_repo.Wmf_fsys();
this.trg_repo = trg_repo;
this.meta_itm = xfer_itm.Meta_itm();
ext_rule = src_repo.Ext_rules().Get_or_null(ext.Ext());
orig_w = 0; orig_h = 0; file_w = 0; file_h = 0;
} private byte lnki_type;
Xof_xfer_itm xfer_itm; double lnki_thumbtime = Xof_doc_thumb.Null; boolean lnki_thumbable; int lnki_w, lnki_h, file_w, file_h; double lnki_upright;
Xof_ext ext; Xoft_rule_itm ext_rule; Xof_repo_itm src_repo, trg_repo; boolean src_repo_is_wmf; byte[] ttl, md5; int orig_w, orig_h, orig_file_len;
int lnki_page = Xof_doc_page.Null;
public Xof_meta_itm Meta_itm() {return meta_itm;} private Xof_meta_itm meta_itm;
public boolean Download_allowed_by_ext() {return orig_file_len < ext_rule.Make_max();}
public Xof_xfer_mgr Check_file_exists_before_xfer_n_() {check_file_exists_before_xfer = false; return this;} private boolean check_file_exists_before_xfer = true;
public boolean Make_file(Xow_wiki wiki) {
rslt.Clear(); this.wiki = wiki;
if ( ext.Id() == Xof_ext_.Id_ogg // file is ogg; could be audio; DATE:2013-08-03
&& !meta_itm.Thumbs_indicates_oga() // check to make sure it hasn't been called before
&& src_repo.Wmf_api() // make sure wmf_api enabled
)
Call_wmf_api();
if (ext.Id_is_thumbable_img()) Make_img();
else if (ext.Id_is_video()&& !meta_itm.Thumbs_indicates_oga()) Make_vid();
else Make_other();
return rslt.Pass();
} private Xow_wiki wiki; Xof_img_wkr_api_size_base_rslts rslts = new Xof_img_wkr_api_size_base_rslts();
boolean Make_img() {
String src_str; Io_url trg_url;
// BLOCK: thumb
if (lnki_thumbable) { // lnki is thumb with known width >>> try to do thumb
if (lnki_w < 1 && lnki_h < 1) { // NOTE: only give default thumb if both w and h are < 1; if h > 0, then skip; EX:Paris;[[File:IMA-Ile-St-Louis.jpg|thumb|x220]]
lnki_w = Xof_img_size.Upright_calc(wiki.File_mgr().Fsdb_mgr().Patch_upright(), lnki_upright, lnki_w, lnki_w, lnki_h, lnki_type);
if (lnki_w < 1)
lnki_w = wiki.Html_mgr().Img_thumb_width(); // NOTE: used to be src_repo.Thumb_w()
}
Make_img_qry(); // NOTE: used to be "if (!Make_img_qry()) return false;" however some images are present, but don't return <iinfo> node; for now, try to proceed; DATE:2013-02-03
if (Make_img_thumb()) return true;
}
// BLOCK: orig; get orig for convert; note that Img_download will not download file again if src exists
src_str = this.Src_url(src_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null_deprecated);
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null_deprecated);
if (!Img_download(src_str, trg_url, false)) return false;
trg_url = rslt.Trg();
// BLOCK: convert thumb
if (lnki_thumbable || ext.Id_is_svg() || ext.Id_is_djvu()) {
rslt.Clear(); // clear error from failed thumb
Io_url src_url = trg_url;
if (ext.Id_is_djvu()) { // NOTE: this block converts djvu -> tiff b/c vanilla imageMagick cannot do djvu -> jpeg
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w).GenNewExt(".tiff"); // NOTE: manually change ext to tiff; note that djvu has view type of jpeg
wiki.App().File_mgr().Img_mgr().Wkr_convert_djvu_to_tiff().Exec(src_url, trg_url);
if (!Cmd_query_size(trg_url)) return false;
// meta_itm.Update_orig_size(file_w, file_h); // NOTE that thumb size is always orig size
src_url = trg_url;
}
boolean limit = !ext.Id_is_svg(); // do not limit if svg
Xof_xfer_itm_.Calc_xfer_size(calc_size, xfer_itm.Lnki_type(), wiki.Html_mgr().Img_thumb_width(), file_w, file_h, lnki_w, lnki_h, lnki_thumbable, xfer_itm.Lnki_upright(), limit); // NOTE: always recalc w/h; needed for (a) when width < 1 and (b) when w/h are wrong; xfer=160,160, lnki=65,50, actl should be 50,50; EX.WP: [[Image:Gnome-mime-audio-openclipart.svg|65x50px|center|link=|alt=]]
lnki_w = calc_size.Val_0(); lnki_h = calc_size.Val_1();
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w);
if (!Img_convert(src_url, trg_url)) return false; // convert failed; exit
if (ext.Id_is_djvu()) Io_mgr._.DeleteFil(src_url); // convert passed; if djvu, delete intermediary .tiff file;
}
return true;
} Int_2_ref calc_size = new Int_2_ref();
boolean Call_wmf_api() {
boolean found = wiki.App().File_mgr().Download_mgr().Api_size_wkr().Api_query_size(rslts, wiki, ttl, lnki_w, lnki_h);
if (found) {
if (rslts.Reg_wiki() != null) {
src_repo = wiki.App().File_mgr().Repo_mgr().Get_by_wmf(rslts.Reg_wiki());
trg_repo = wiki.App().File_mgr().Repo_mgr().Get_primary(rslts.Reg_wiki());
if (Bry_.Eq(rslts.Reg_wiki(), wiki.Domain_bry())) // wmf returned same wiki as current
xfer_itm.Trg_repo_idx_(Xof_meta_itm.Repo_same); // set repo to "same"
else { // wmf returned other wiki (which is 99% likely to be commons)
Xof_repo_pair trg_repo_pair = wiki.File_mgr().Repo_mgr().Repos_get_by_wiki(rslts.Reg_wiki()); // need to do this b/c commons is not always first; see wikinews; DATE:2013-12-04
int trg_repo_idx = trg_repo_pair == null ? 0 : (int)trg_repo_pair.Id(); // 0=commons
xfer_itm.Trg_repo_idx_(trg_repo_idx);
}
if (!Bry_.Eq(rslts.Reg_page(), ttl)) {
ttl = rslts.Reg_page();
md5 = Xof_xfer_itm_.Md5_(ttl);
meta_itm.Ptr_ttl_(ttl);
}
meta_itm.Vrtl_repo_(xfer_itm.Trg_repo_idx());
if (ext.Id_is_ogg() && rslts.Orig_w() == 0 && rslts.Orig_h() == 0) // file is ogg, but thumb has size of 0,0; assume audio and mark as oga
meta_itm.Update_thumb_oga_();
}
meta_itm.Load_orig_(rslts.Orig_w(), rslts.Orig_h());
return true;
}
else {
meta_itm.Orig_exists_(Xof_meta_itm.Exists_n); // not found; mark no
meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_missing); // not found; mark missing
rslt.Fail("api failed");
return false;
}
}
boolean Make_img_qry() {
if (meta_itm.Orig_w() < 1) {
if (src_repo.Wmf_api()) { // api_enabled
boolean wmf_api_found = Call_wmf_api();
if (!wmf_api_found) return false; // not found in wmf_api; exit now
}
else if (src_repo.Tarball()) {
String src_str = this.Src_url(src_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null_deprecated);
meta_itm.Orig_exists_(Xof_meta_itm.Exists_unknown); // mark exists unknown; note need to assertively mark unknown b/c it may have been marked n in previous pass through multiple repos; DATE:20121227
meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_unknown); // mark repo unknown;
if (!Cmd_query_size(Io_url_.new_fil_(src_str))) {
meta_itm.Orig_exists_(Xof_meta_itm.Exists_n); // not found; mark no
meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_missing); // not found; mark missing
rslt.Fail("img not found");
return false;
}
meta_itm.Vrtl_repo_(xfer_itm.Trg_repo_idx());
meta_itm.Load_orig_(file_w, file_h);
}
}
return true;
}
private boolean Make_img_thumb(){
String src_str; Io_url trg_url;
boolean limit = !ext.Id_is_svg(); // do not limit if svg
if (lnki_w > 0) { // if width is -1, don't bother (wmf only has > 0 width); EX.WP:Paris;[[File:IMA-Ile-St-Louis.jpg|thumb|x220]]
for (int i = 0; i < 2; i++) {
Xof_xfer_itm_.Calc_xfer_size(calc_size, xfer_itm.Lnki_type(), wiki.Html_mgr().Img_thumb_width(), meta_itm.Orig_w(), meta_itm.Orig_h(), lnki_w, lnki_h, lnki_thumbable, lnki_upright, limit);
lnki_w = calc_size.Val_0();
if (lnki_h != -1) lnki_h = calc_size.Val_1(); // NOTE: if -1 (no height specified) do not set height; EX:Tokage_2011-07-15.jpg; DATE:2013-06-03
src_str = src_repo.Tarball() ? this.Src_url(src_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null) : this.Src_url(src_repo, Xof_repo_itm.Mode_thumb, lnki_w);
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w);
if (Make_img_exec(src_str, trg_url)) { // download passed
trg_url = rslt.Trg();
if (lnki_w > 0 && lnki_h > 0) { // lnki specified width and height; check against xfer; needed when w/h are wrong; lnki=65,50 but xfer=160,160; actl should be 50,50; EX.WP: [[Image:Gnome-mime-audio-openclipart.svg|65x50px|center|link=|alt=]]; SEE:NOTE_1
Xof_xfer_itm_.Calc_xfer_size(calc_size, xfer_itm.Lnki_type(), wiki.Html_mgr().Img_thumb_width(), file_w, file_h, lnki_w, lnki_h, lnki_thumbable, -1, limit); // NOTE: do not use lnki_upright; already applied above to generate new lnki_w; using it again will double-apply it
if (Int_.Between(lnki_w, calc_size.Val_0() - 1, calc_size.Val_0() + 1)) // width matches; done
return true;
else { // width fails; cleanup invalid thumb
trg_url = rslt.Trg(); // NOTE: update url b/c size may have changed; EX.WP:commons/Image:Tempesta.djvu which is 800px, but resized to 799px
Io_mgr._.DeleteFil(trg_url); // delete file
meta_itm.Thumbs_del(lnki_w); // delete thumb
lnki_w = calc_size.Val_0(); lnki_h = calc_size.Val_1();
}
}
else // xfer found that matches lnki; exit;
return true;
}
else
break;
}
}
else { // only height specified
if (meta_itm.Orig_w() > 0) { // query discovered orig_w; note: not the same as orig_exists b/c flag may not be set yet
Xof_xfer_itm_.Calc_xfer_size(calc_size, xfer_itm.Lnki_type(), wiki.Html_mgr().Img_thumb_width(), file_w, file_h, lnki_w, lnki_h, lnki_thumbable, lnki_upright);// calculate again using width and height
Xof_xfer_itm_.Calc_xfer_size(calc_size, xfer_itm.Lnki_type(), wiki.Html_mgr().Img_thumb_width(), meta_itm.Orig_w(), meta_itm.Orig_h(), lnki_w, lnki_h, lnki_thumbable, lnki_upright, limit);
lnki_w = calc_size.Val_0(); lnki_h = calc_size.Val_1();
src_str = src_repo.Tarball() ? this.Src_url(src_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null) : this.Src_url(src_repo, Xof_repo_itm.Mode_thumb, lnki_w);
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w);
return Make_img_exec(src_str, trg_url);
}
else { // no orig dimensions; do download
if (lnki_w == Xof_img_size.Null)
lnki_w = wiki.Html_mgr().Img_thumb_width(); // set lnki_w to default thumb_width (220)
src_str = src_repo.Tarball() ? this.Src_url(src_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null) : this.Src_url(src_repo, Xof_repo_itm.Mode_thumb, lnki_w);
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w);
if (Make_img_exec(src_str, trg_url)) { // download
if (src_repo.Tarball()) return true; // convert worked; no need to download again;
int old_lnki_w = lnki_w;
lnki_w = (file_w * lnki_h) / file_h; // calculate correct width for specified height;
lnki_w = Xof_xfer_itm_.Calc_w(file_w, file_h, lnki_h);
if (lnki_w == old_lnki_w) return true; // download at 220 actually worked; this will probably occur very infrequently, but if so, exit
src_str = this.Src_url(src_repo, Xof_repo_itm.Mode_thumb, lnki_w);
trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w);
if (Make_img_exec(src_str, trg_url)) { // download again
trg_url = rslt.Trg();
Xof_xfer_itm_.Calc_xfer_size(calc_size, xfer_itm.Lnki_type(), wiki.Html_mgr().Img_thumb_width(), file_w, file_h, lnki_w, lnki_h, lnki_thumbable, lnki_upright);// calculate again using width and height
if (Int_.Between(lnki_w, calc_size.Val_0() - 1, calc_size.Val_0() + 1)) // width matches; done
return true;
else { // width fails; cleanup invalid thumb; EX:w:[[File:Upper and Middle Manhattan.jpg|x120px]]
trg_url = rslt.Trg(); // NOTE: update url b/c size may have changed; EX.WP:commons/Image:Tempesta.djvu which is 800px, but resized to 799px
Io_mgr._.DeleteFil(trg_url); // delete file
meta_itm.Thumbs_del(lnki_w); // delete thumb
lnki_w = calc_size.Val_0(); lnki_h = calc_size.Val_1();
}
}
}
}
}
return false;
}
boolean Make_img_exec(String src_str, Io_url trg_url) {
if (src_repo_is_wmf)
return Img_download(src_str, trg_url, true);
else
return Img_convert(Io_url_.new_fil_(src_str), trg_url);
}
private void Make_vid() {
boolean thumb_pass = false;
Make_other(); // NOTE: must go before thumb b/c rslt.Pass() is modified by both
if (src_repo_is_wmf) { // src is wmf >>> copy down thumb; NOTE: thumb not available in tar
String src_str = this.Src_url(src_repo, Xof_repo_itm.Mode_thumb, lnki_w);
Io_url trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_thumb, lnki_w);
thumb_pass = Cmd_download(src_str, trg_url, false); // NOTE: ogg audios may sometimes have thumb, but 0 size; thumb_pass will be true, but will fail on thumb_rename; EX.WP:Beethoven; [[File:Ludwig van Beethoven - Symphonie 5 c-moll - 1. Allegro con brio.ogg]]
if (thumb_pass) {
thumb_pass = Img_rename_by_size(trg_url); // NOTE: lnki cites view_w which will rarely match file_w; EX.WP:Earth;Northwest coast of United States to Central South America at Night.ogv|250px; which is atually 640
if (thumb_pass) {
Xof_meta_thumb thumb = meta_itm.Update_thumb_add(file_w, file_h); // NOTE: only store 1 width; depend on browser to resize to other widths; this matches MW's behavior
if (Xof_doc_thumb.Null_n(lnki_thumbtime)) { // lnki specified seek
thumb.Seeks_add(Xof_doc_thumb.X_int(lnki_thumbtime));
meta_itm.Owner_fil().Dirty_();
}
rslt.Clear();
}
else // something failed; delete file
Io_mgr._.DeleteFil(trg_url);
}
if (!thumb_pass) // NOTE: thumb failed; mark itm as oga
meta_itm.Update_thumb_oga_();
}
}
boolean Make_other() {
if (!Orig_max_download() && !force_orig) return false;
String src_str = this.Src_url(src_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null_deprecated);
Io_url trg_url = this.Trg_url(trg_repo, Xof_repo_itm.Mode_orig, Xof_img_size.Size_null_deprecated);
return Cmd_download(src_str, trg_url, true);
}
boolean Orig_max_download() {
long ext_max = ext_rule.View_max();
return (orig_file_len < ext_max) // file_len is less than defined max
|| (ext_max == Xoft_rule_itm.Max_wildcard); // max is defined as wildcard
// return !(orig_file_len < ext_max || (ext_max == Xoft_rule_itm.Max_wildcard && orig_file_len < 1));
}
boolean Img_download(String src_str, Io_url trg_url, boolean cur_is_thumb) {
rslt.Atrs_src_trg_(src_str, trg_url); // NOTE: must be set at start; Img_rename_by_size may overwrite trg
if (!Cmd_download(src_str, trg_url, !cur_is_thumb)) return false;
if (cur_is_thumb) {
if (orig_w < 1 || orig_h < 1 || lnki_w < 1 || lnki_h < 1) { // NOTE: if orig is unknown, calc will be based on lnki size which may be incorrect; EX.WP:{{Olympic Summer Games Host Cities}};[[File:Flag of the United States.svg|22x20px]] which is really 22x12px
if (!Img_rename_by_size(trg_url)) return false;
trg_url = rslt.Trg(); // NOTE: update url b/c size may have changed
}
else {
file_w = lnki_w; file_h = lnki_h;
}
meta_itm.Update_thumb_add(file_w, file_h);
}
else {
if ((orig_w < 1 || orig_h < 1) && !ext.Id_is_djvu()) { // NOTE: imageMagick cannot size djvu xfer_itm so ignore
if (!Cmd_query_size(trg_url)) return false;
meta_itm.Update_orig_size(file_w, file_h);
}
meta_itm.Orig_exists_(Xof_meta_itm.Exists_y);
}
return true;
} String_obj_ref img_convert_rslt = String_obj_ref.null_();
private boolean Img_convert(Io_url src_url, Io_url trg_url) {
rslt.Atrs_src_trg_(src_url.Xto_api(), trg_url); // NOTE: must be set at start; Img_rename_by_size may overwrite trg
if (Io_mgr._.ExistsFil(trg_url)) return true; // NOTE: already converted; occurs when same image used twice on same page (EX: flags)
if (!file_mgr.Img_mgr().Wkr_resize_img().Exec(src_url, trg_url, lnki_w, lnki_h, ext.Id(), img_convert_rslt)) {
return rslt.Fail("convert failed|" + src_url.Raw() + "|" + img_convert_rslt.Val());
}
if (lnki_w < 1 || lnki_h < 1) { // lnki_w or lnki_h is invalid >>> get real size for thumb
if (!Img_rename_by_size(trg_url)) return false;
trg_url = rslt.Trg(); // NOTE: update url b/c size may have changed
}
else {
file_w = lnki_w; file_h = lnki_h;
}
meta_itm.Vrtl_repo_(xfer_itm.Trg_repo_idx());
meta_itm.Orig_exists_(Xof_meta_itm.Exists_y);
meta_itm.Update_thumb_add(file_w, file_h);
return true;
}
private boolean Img_rename_by_size(Io_url trg_url) {
if (!Cmd_query_size(trg_url)) return false;
if (file_w != lnki_w) { // NOTE: only rename if file_w is different; this proc can be called if file_w is same, but file_h < 1; EX: A.svg|thumb|30px will call this proc to get size of thumb
String new_name = Xof_doc_thumb.Null_y(lnki_thumbtime) ? file_w + "px" : file_w + "px" + Xof_meta_thumb_parser.Dlm_seek_str + Xof_doc_thumb.X_str(lnki_thumbtime);
Io_url new_trg = trg_url.GenNewNameOnly(new_name);
if (trg_url.Eq(new_trg)) return true; // HACK: io will delete file if moving unto itself; (i.e.: mv A.png A.png is same as del A.png); problem is that this proc is being called too many times
try {Io_mgr._.MoveFil_args(trg_url, new_trg, true).Exec();}
catch (Exception exc) {Err_.Noop(exc); return rslt.Fail("move failed");}
rslt.Trg_(new_trg);
}
return true;
}
private boolean Cmd_download(String src_str, Io_url trg_url, boolean cur_is_orig) {
boolean exists = false;
if (check_file_exists_before_xfer) {
gplx.ios.IoItmFil fil_itm = Io_mgr._.QueryFil(trg_url);
exists = fil_itm.Exists() && fil_itm.Size() > 0;
}
boolean pass = false;
if (exists)
pass = true;
else {
byte download_rslt = file_mgr.Download_mgr().Download_wkr().Download(src_repo_is_wmf, src_str, trg_url, file_mgr.Download_mgr().Download_wkr().Download_xrg().Prog_fmt_hdr());
if (download_rslt == gplx.ios.IoEngine_xrg_downloadFil.Rslt_fail_host_not_found) {
wiki.File_mgr().Cfg_download().Enabled_(false);
throw Err_mgr._.fmt_("xowa.xfer_mgr", "download_failed", "download_failed: host not found");
}
pass = download_rslt == gplx.ios.IoEngine_xrg_downloadFil.Rslt_pass;
}
// update meta attributes; placed here b/c Cmd_download is called by 3 procs; note that thumb meta is handled by calling procs as the logic is more specific
if (cur_is_orig) {
if (pass) meta_itm.Orig_exists_(Xof_meta_itm.Exists_y);
else meta_itm.Orig_exists_(Xof_meta_itm.Exists_n);
}
if (pass)
meta_itm.Vrtl_repo_(xfer_itm.Trg_repo_idx());
else
rslt.Fail("download failed|" + src_str);
return pass;
}
private boolean Cmd_query_size(Io_url trg_url) {
SizeAdp file_size = file_mgr.Img_mgr().Wkr_query_img_size().Exec(trg_url);
if (file_size == SizeAdp_.Zero) return rslt.Fail("query size failed");
file_w = file_size.Width(); file_h = file_size.Height();
return true;
}
String Src_url(Xof_repo_itm repo, byte mode, int lnki_w) {return url_bldr.Set_src_file_(mode, repo, ttl, md5, ext, lnki_w, lnki_thumbtime, lnki_page).Xto_str();}
Io_url Trg_url(Xof_repo_itm repo, byte mode, int lnki_w) {return url_bldr.Set_trg_file_(mode, repo, ttl, md5, ext, lnki_w, lnki_thumbtime, lnki_page).Xto_url();}
Xof_url_bldr url_bldr = new Xof_url_bldr();
}
/*
NOTE_1:always recalc w/h
[[Image:Gnome-mime-audio-openclipart.svg|65x50px|center|link=|alt=]]
. orig size is 160,160
. lnki size is 65,50
. actl size should be 50,50
. however, WP actually happens to have a 65,65 on server
The problem is that WP always knows orig size info (160,160) and can correct 65,50 to 50,50
XO does not know orig size info (image.sql needs to be downloaded) and needs to somehow decide that 65,50 is wrong even though 65 is on server
So, do the following
. assume that dimensions of 65,65 are correctly scaled from 160,160
. calc 65,50 for the 65w image
.. if 65,50 is correct, then we should get back 65,50
.. if not, then the lnki is wrong. just download orig and rescale
... note that we can redownload thumb at 50, but simply easier to "fall-through" to orig processing
*/

View File

@@ -0,0 +1,87 @@
/*
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; import gplx.*;
import gplx.xowa.files.*; import gplx.xowa.files.fsdb.*; import gplx.xowa.files.bins.*;
import gplx.xowa.files.gui.*;
public class Xof_xfer_queue {
private ListAdp list = ListAdp_.new_(); private OrderedHash dirty = OrderedHash_.new_(); private Bry_obj_ref dirty_key = Bry_obj_ref.null_();
public Int_obj_ref Elem_id() {return elem_id;} private Int_obj_ref elem_id = Int_obj_ref.neg1_();
public int Count() {return list.Count();}
public void Clear() {
dirty.Clear();
list.Clear();
elem_id.Val_neg1_();
}
public void Add(Xof_xfer_itm xfer_itm) {list.Add(xfer_itm);}
public void Add_dirty_if_new(Xof_meta_mgr meta_mgr) {
byte[] meta_mgr_key = meta_mgr.Wiki().Domain_bry();
if (!dirty.Has(dirty_key.Val_(meta_mgr_key)))
dirty.AddReplace(meta_mgr_key, meta_mgr); // only add if new
}
public void Exec(byte exec_tid, Gfo_usr_dlg wtr, Xow_wiki wiki, Xoa_page page) {
if (wiki.File_mgr().Version() == Xow_file_mgr.Version_2)
Exec_v2(exec_tid, wtr, wiki, page);
else
Exec_v1(exec_tid, wtr, wiki, page);
}
private void Exec_v1(byte exec_tid, Gfo_usr_dlg wtr, Xow_wiki wiki, Xoa_page page) {
Xof_meta_mgr meta_mgr = null;
int xfer_len = list.Count();
for (int i = 0; i < xfer_len; i++) {
if (wiki.App().Gui_wtr().Canceled()) break;
Xof_xfer_itm xfer_itm = (Xof_xfer_itm)list.FetchAt(i);
meta_mgr = xfer_itm.Meta_itm().Owner_fil().Owner_mgr();
Add_dirty_if_new(meta_mgr); // only add if new
String queue_msg = wtr.Prog_many(GRP_KEY, "download.bgn", "downloading ~{0} of ~{1}: ~{2};", i + ListAdp_.Base1, xfer_len, xfer_itm.Lnki_ttl());
wiki.App().File_mgr().Download_mgr().Download_wkr().Download_xrg().Prog_fmt_hdr_(queue_msg);
wiki.File_mgr().Repo_mgr().Xfer_by_meta(xfer_itm, this);
xfer_itm.Atrs_by_meta(xfer_itm.Meta_itm(), xfer_itm.Meta_itm().Repo_itm(wiki), wiki.Html_mgr().Img_thumb_width());
xfer_itm.Atrs_calc_for_html();
if (!xfer_itm.Html_pass()) continue; // file not found; don't call Update_img, else invalid src will be passed and caption box will be incorrectly resized; EX:ar.d:جَبَّارَة; DATE:2014-04-13
if (Bry_.Len_gt_0(xfer_itm.Html_view_src()) // only update images that have been found; otherwise "Undefined" shows up in image box
&& xfer_itm.Html_elem_tid() != Xof_html_elem.Tid_none) { // skip updates when downloading orig on File page (there won't be any frame to update)
Js_img_mgr.Update_img(page, xfer_itm);
}
}
for (int i = 0; i < dirty.Count(); i++) {
meta_mgr = (Xof_meta_mgr)dirty.FetchAt(i);
meta_mgr.Save(true);
}
this.Clear();
}
private void Exec_v2(byte exec_tid, Gfo_usr_dlg wtr, Xow_wiki wiki, Xoa_page page) {
wiki.File_mgr().Fsdb_mgr().Init_by_wiki__add_bin_wkrs(wiki);
wiki.File_mgr().Fsdb_mgr().Reg_select(page, exec_tid, Xfer_itms_to_fsdb_itms(list, wiki.File_mgr().Fsdb_mgr().Patch_upright()));
}
private ListAdp Xfer_itms_to_fsdb_itms(ListAdp list, boolean upright_patch) {
ListAdp rv = ListAdp_.new_();
int list_len = list.Count();
for (int i = 0; i < list_len; i++) {
Xof_xfer_itm xfer_itm = (Xof_xfer_itm)list.FetchAt(i);
Xof_fsdb_itm fsdb_itm = new Xof_fsdb_itm();
fsdb_itm.Init_by_lnki(xfer_itm.Lnki_ttl(), xfer_itm.Lnki_ext(), xfer_itm.Lnki_md5(), xfer_itm.Lnki_type(), xfer_itm.Lnki_w(), xfer_itm.Lnki_h(), upright_patch, xfer_itm.Lnki_upright(), xfer_itm.Lnki_thumbtime(), xfer_itm.Lnki_page());
fsdb_itm.Html_uid_(xfer_itm.Html_uid());
fsdb_itm.Html_elem_tid_(xfer_itm.Html_elem_tid());
fsdb_itm.Gallery_mgr_h_(xfer_itm.Gallery_mgr_h());
fsdb_itm.Html_img_wkr_(xfer_itm.Html_img_wkr());
rv.Add(fsdb_itm);
}
return rv;
}
private static final String GRP_KEY = "xowa.xfer.queue";
}

View File

@@ -0,0 +1,112 @@
/*
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; import gplx.*;
import gplx.ios.*; import gplx.xowa.files.cnvs.*;
public class Xof_xfer_queue_base_fxt {
public Xof_img_wkr_api_size_base_mok Api_size() {return api_size;} private Xof_img_wkr_api_size_base_mok api_size = Xof_img_wkr_api_size_base_mok._;
public Xof_repo_itm Src_commons_repo() {return src_commons_repo;} private Xof_repo_itm src_commons_repo;
public Xof_repo_itm Src_en_wiki_repo() {return src_en_wiki_repo;} private Xof_repo_itm src_en_wiki_repo;
@gplx.Virtual public void Clear(boolean src_repo_is_wmf) {
Io_mgr._.InitEngine_mem();
if (app == null) {
app = Xoa_app_fxt.app_();
en_wiki = Xoa_app_fxt.wiki_(app, Xow_wiki_.Domain_enwiki_str);
commons = Xoa_app_fxt.wiki_(app, Xow_wiki_.Domain_commons_str);
app.Wiki_mgr().Add(commons);
app.Wiki_mgr().Add(en_wiki);
Xof_file_mgr file_mgr = app.File_mgr();
file_mgr.Img_mgr().Wkr_resize_img_(Xof_img_wkr_resize_img_mok._);
file_mgr.Img_mgr().Wkr_query_img_size_(new Xof_img_wkr_query_img_size_test());
file_mgr.Download_mgr().Api_size_wkr_(api_size);
byte[] src_commons = Bry_.new_ascii_("src_commons");
byte[] src_en_wiki = Bry_.new_ascii_("src_en_wiki");
byte[] trg_commons = Bry_.new_ascii_("trg_commons");
byte[] trg_en_wiki = Bry_.new_ascii_("trg_en_wiki");
src_commons_repo = Ini_repo_add(file_mgr, src_commons, "mem/src/commons.wikimedia.org/", Xow_wiki_.Domain_commons_str, false);
src_en_wiki_repo = Ini_repo_add(file_mgr, src_en_wiki, "mem/src/en.wikipedia.org/" , Xow_wiki_.Domain_enwiki_str, false);
Ini_repo_add(file_mgr, trg_commons, "mem/trg/commons.wikimedia.org/", Xow_wiki_.Domain_commons_str, true).Primary_(true);
Ini_repo_add(file_mgr, trg_en_wiki, "mem/trg/en.wikipedia.org/" , Xow_wiki_.Domain_enwiki_str, true).Primary_(true);
Xow_repo_mgr wiki_repo_mgr = en_wiki.File_mgr().Repo_mgr();
Xof_repo_pair pair = null;
pair = wiki_repo_mgr.Add_repo(src_commons, trg_commons);
pair.Src().Fsys_is_wnt_(true).Wmf_fsys_(src_repo_is_wmf).Tarball_(!src_repo_is_wmf);
pair.Trg().Fsys_is_wnt_(true);
pair = wiki_repo_mgr.Add_repo(src_en_wiki, trg_en_wiki);
pair.Src().Fsys_is_wnt_(true).Wmf_fsys_(src_repo_is_wmf);
pair.Trg().Fsys_is_wnt_(true);
}
en_wiki.Clear_for_tests();
commons.Clear_for_tests();
src_fils = trg_fils = Io_fil.Ary_empty;
html_src = null;
html_w = html_h = -1;
}
public Xoa_app App() {return app;} private Xoa_app app;
public Xow_wiki En_wiki() {return en_wiki;} private Xow_wiki en_wiki;
public Xow_wiki Commons() {return commons;} private Xow_wiki commons;
public void ini_page_create_commons(String ttl) {Init_page_create(commons, ttl, "");}
public void ini_page_create_commons_redirect(String ttl, String redirect) {Init_page_create(commons, ttl, "#REDIRECT [[" + redirect + "]]");}
public void ini_page_create_en_wiki(String ttl) {Init_page_create(en_wiki, ttl, "");}
public void ini_page_create_en_wiki_redirect(String ttl, String redirect) {Init_page_create(en_wiki, ttl, "#REDIRECT [[" + redirect + "]]");}
public void Init_page_create(Xow_wiki wiki, String ttl, String txt) {
Xoa_ttl page_ttl = Xoa_ttl.parse_(wiki, Bry_.new_utf8_(ttl));
byte[] page_raw = Bry_.new_utf8_(txt);
wiki.Db_mgr().Save_mgr().Data_create(page_ttl, page_raw);
}
Xof_repo_itm Ini_repo_add(Xof_file_mgr file_mgr, byte[] key, String root, String wiki, boolean trg) {
Xof_repo_itm repo = file_mgr.Repo_mgr().Set(String_.new_utf8_(key), root, wiki).Ext_rules_(Xoft_rule_grp.Grp_app_default).Dir_depth_(2);
if (trg) {
byte[][] ary = repo.Mode_names();
ary[0] = Bry_.new_ascii_("raw");
ary[1] = Bry_.new_ascii_("fit");
}
return repo;
}
public Xof_xfer_queue_base_fxt Src_base(Io_fil... v) {src_fils = v; return this;} Io_fil[] src_fils = Io_fil.Ary_empty;
public Xof_xfer_queue_base_fxt Trg_base(Io_fil... v) {trg_fils = v; return this;} Io_fil[] trg_fils = Io_fil.Ary_empty;
public String Html_view_src() {return html_src;} protected Xof_xfer_queue_base_fxt Html_src_base_(String v) {html_src = v; return this;} private String html_src;
public int Html_w() {return html_w;} public Xof_xfer_queue_base_fxt Html_w_(int v) {html_w = v; return this;} private int html_w = -1;
public int Html_h() {return html_h;} public Xof_xfer_queue_base_fxt Html_h_(int v) {html_h = v; return this;} private int html_h = -1;
public void ini_src_fils() {
if (src_fils != null) {
for (int i = 0; i < src_fils.length; i++) {
Io_fil src_fil = src_fils[i];
Io_mgr._.SaveFilStr(src_fil.Url(), src_fil.Data());
}
}
}
public void tst_trg_fils() {
for (int i = 0; i < trg_fils.length; i++) {
Io_fil trg_fil = trg_fils[i];
String data = Io_mgr._.LoadFilStr(trg_fil.Url());
Tfds.Eq_str_lines(trg_fil.Data(), data, trg_fil.Url().Raw());
}
}
public void save_(Io_fil v) {Io_mgr._.SaveFilStr(v.Url(), v.Data());}
public Io_fil reg_(String url, String... v) {return new Io_fil(Io_url_.mem_fil_(url), String_.Concat_lines_nl(v));}
public Io_fil img_(String url_str, int w, int h) {return file_(url_str, file_img(w, h));}
public Io_fil svg_(String url_str, int w, int h) {return file_(url_str, file_svg(w, h));}
public Io_fil ogg_(String url_str) {return file_(url_str, "");}
public void fil_absent(String url) {Tfds.Eq_false(Io_mgr._.ExistsFil(Io_url_.mem_fil_(url)), "fil should not exist: {0}", url);}
Io_fil file_(String url_str, String data) {return new Io_fil(Io_url_.mem_fil_(url_str), data);}
String file_img(int w, int h) {return String_.Format("{0},{1}", w, h);}
String file_svg(int w, int h) {return String_.Format("<svg width=\"{0}\" height=\"{1}\" />", w, h);}
}

View File

@@ -0,0 +1,153 @@
/*
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; import gplx.*;
import org.junit.*;
import gplx.ios.*; import gplx.gfui.*;
public class Xof_xfer_queue_bldr_tar_tst {
Xof_xfer_queue_bldr_fxt fxt = new Xof_xfer_queue_bldr_fxt();
@Before public void init() {fxt.Clear(false);}
@Test public void Png_orig() {
fxt.Rdr("A.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|")
)
.tst();
}
@Test public void Png_thumb() {
fxt.Rdr("A.png|||10000|90|80|8|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|1?45,40")
)
.tst();
}
@Test public void Png_many() {
fxt.Rdr("A.png|||10000|90|80|8|0||0,-1,-1;8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|1?45,40")
)
.tst();
}
@Test public void Redirect() {
fxt.Rdr("B.png|A.png||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|")
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv", "B.png|0|A.png|2?0,0|")
)
.tst();
}
@Test public void Long_file_name() {
String name = String_.Repeat("A", 200);
fxt.Rdr(name + ".png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/1/14/" + name + ".png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/1/4/" + String_.Repeat("A", (200 + 4) - (20 + 32 + 1 + 4)) + "_141b573216f8e4338f4f53409bd9d209.png", 90, 80) // SEE:NOTE_1
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/1/14.csv", name + ".png|0||1?90,80|")
)
.tst();
fxt .Lnki_thumb_(name + ".png", 200)
.Html_src_("file:///mem/trg/commons.wikimedia.org/raw/1/4/" + String_.Repeat("A", (200 + 4) - (20 + 32 + 1 + 4)) + "_141b573216f8e4338f4f53409bd9d209.png")
.tst();
}
@Test public void Svg_orig() {
fxt.Rdr("A.svg|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.svg_("mem/src/commons.wikimedia.org/7/75/A.svg", 90, 80))
.Trg( fxt.svg_("mem/trg/commons.wikimedia.org/raw/7/5/A.svg", 90, 80)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||1?90,80|1?90,80")
)
.tst();
}
@Test public void Svg_thumb() {
fxt.Rdr("A.svg|||10000|90|80|8|0||8,45,-1")
.Src( fxt.svg_("mem/src/commons.wikimedia.org/7/75/A.svg", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||1?90,80|1?45,40")
)
.tst();
}
@Test public void Invalid() {
fxt.Rdr("A\"*b.jpg|||10000|90|80|8|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/0/0f/A__b.jpg", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/0/f/A__b.jpg/45px.jpg", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/0/0f.csv", "A\"*b.jpg|0||1?90,80|1?45,40")
)
.tst();
}
@Test public void LowerCase() {
fxt.Rdr("a.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|")
)
.tst();
}
@Test public void Nil_size_thumb() {
fxt.Rdr("A.png|||0|0|0|0|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|1?45,40"
)
)
.tst();
}
@Test public void Redirect_orig() {
fxt.Rdr("B.png|A.png||0|0|0|0|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|")
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv", "B.png|0|A.png|2?0,0|")
)
.tst();
}
@Test public void Ogg() {
fxt.Rdr("A.ogg|||0|0|0|0|0||0,50,100") // NOTE: ignore size even if set in lnk
.Src( fxt.ogg_("mem/src/commons.wikimedia.org/4/42/A.ogg"))
.Trg( fxt.ogg_("mem/trg/commons.wikimedia.org/raw/4/2/A.ogg")
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|0||1?0,0|")
)
.tst();
}
@Test public void Char_apos() { // PURPOSE: ' should not be url-encoded
fxt.Rdr("A'b.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/6/66/A'b.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/6/6/A'b.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/6/66.csv", "A'b.png|0||1?90,80|")
)
.tst();
}
}
// Tfds.Write(gplx.xowa.files.Xof_xfer_itm_.Md5_(Bry_.new_utf8_("A,b.png")));
/*
NOTE_1:String_.Repeat("A", (200 + 4) - (24 + 20 + 32 + 1 + 4))
+
200: "A" repeated 200 times
4: ".png"
NOTE: 200 is 20 over max of 180
-
20: amount over 180
32: length of md5 hash; "141b573216f8e4338f4f53409bd9d209"
1: length of _
4: ".png"
*/

View File

@@ -0,0 +1,430 @@
/*
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; import gplx.*;
import org.junit.*;
import gplx.ios.*; import gplx.xowa.files.*;
public class Xof_xfer_queue_bldr_wmf_tst {
Xof_xfer_queue_bldr_fxt fxt = new Xof_xfer_queue_bldr_fxt();
@Before public void init() {fxt.Clear(true);}
@Test public void Png_orig() {
fxt.Rdr("A.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|0||1?900,800|")
)
.tst();
}
@Test public void Png_thumb() {
fxt.Rdr("A.png|||10000|90|80|8|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/45px-A.png", 45, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||2?90,80|1?45,40")
)
.tst();
}
@Test public void Png_many() {
fxt.Rdr("A.png|||10000|90|80|8|0||0,-1,-1;8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|1?45,40")
)
.tst();
}
// // Test: Thumb_resizeRaw; thumb does not exist; download orig and resize
// // Test: Thumb_upright specified tstr.Lnki_("[[File:A.png|thumb|upright]]").Src_xfer_("170,160", "mem/wiki/c0/thumb/7/70/A.png/170px-A.png")
// // Test: Thumb_height only specified "[[File:A.png|thumb|x50px]]").Src_xfer_("200,100", "mem/wiki/c0/7/70/A.png" -> 100,50
@Test public void Svg_orig() {
fxt.Rdr("A.svg|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.svg_("mem/src/commons.wikimedia.org/7/75/A.svg", 90, 80))
.Trg( fxt.svg_("mem/trg/commons.wikimedia.org/raw/7/5/A.svg", 90, 80) // NOTE: needs to download orig before converting
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||1?90,80|1?90,80")
)
.tst();
}
@Test public void Svg_thumb() {
fxt.Rdr("A.svg|||10000|90|80|8|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/75/A.svg/45px-A.svg.png", 45, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||2?90,80|1?45,40")
)
.tst();
}
@Test public void Nil_size_thumb() {
fxt.Rdr("A.png|||0|0|0|0|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/45px-A.png", 45, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/45px.png", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||2?0,0|1?45,40")
)
.tst();
}
@Test public void Nil_size_orig() {
fxt.Rdr("A.png|||0|0|0|0|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?90,80|")
)
.tst();
}
@Test public void Nil_height() {
fxt.Rdr("A.png|||0|0|0|0|0||8,-1,80")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 220, 160)
, fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/220px-A.png", 220, 160) // NOTE: make sure default thumb is ignored; i.e.: 220 should not be substituted for -1; EX.WP:Paris;[[File:IMA-Ile-St-Louis.jpg|thumb|x220]]
)
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 220, 160)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/110px.png", 110, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?220,160|1?220,160;1?110,80")
)
.tst();
}
@Test public void Nil_width_thumb() {
fxt.Rdr("A.png|||0|0|0|0|0||8,-1,80")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 180, 160)
, fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/220px-A.png", 220, 196) // NOTE: make sure default thumb is ignored
, fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/90px-A.png", 90, 80) // NOTE: make sure default thumb is ignored
)
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||2?0,0|1?220,196;1?90,80")
)
.tst();
}
@Test public void Nil_width_wrong_width() {
fxt.Rdr("A.svg|||0|0|0|0|0||8,65,50")
.Src( fxt.svg_("mem/src/commons.wikimedia.org/7/75/A.svg", 160, 160))
.Trg( fxt.svg_("mem/trg/commons.wikimedia.org/raw/7/5/A.svg", 160, 160)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/50px.png", 50, 50)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||1?160,160|1?50,50")
)
.tst();
}
@Test public void Nil_width_wrong_width_2() { // EX.WP: [[Image:Gnome-mime-audio-openclipart.svg|65x50px|center|link=|alt=]]
fxt.Rdr("A.svg|||0|0|0|0|0||8,65,50")
.Src( fxt.svg_("mem/src/commons.wikimedia.org/7/75/A.svg", 160, 160)
, fxt.img_("mem/src/commons.wikimedia.org/thumb/7/75/A.svg/65px-A.svg.png", 65, 60))
.Trg( fxt.svg_("mem/trg/commons.wikimedia.org/raw/7/5/A.svg", 160, 160)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/50px.png", 50, 50)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||1?160,160|1?50,50")
)
.tst();
}
@Test public void Svg_thumb_irregular() {// EX.WP:{{Olympic Summer Games Host Cities}};[[File:Flag of the United States.svg|22x20px]]
fxt.Rdr("A.svg|||0|0|0|8|0||8,22,20")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/75/A.svg/22px-A.svg.png", 22, 12)
)
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/22px.png", 22, 12)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||2?0,0|1?22,12")
)
.tst();
}
@Test public void Rounding_converts_to_double() {// bugfix wherein (double) is needed else integer division loses precision; EX.WP:{{Olympic Summer Games Host Cities}};[[File:Flag of the United States.svg|22x20px]]
fxt.Rdr("A.svg|||0|0|0|8|0||8,22,12")
.Src( fxt.svg_("mem/src/commons.wikimedia.org/7/75/A.svg", 1235, 650))
.Trg( fxt.svg_("mem/trg/commons.wikimedia.org/raw/7/5/A.svg", 1235, 650)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/5/A.svg/22px.png", 22, 12)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv", "A.svg|0||1?1235,650|1?22,12")
)
.tst();
}
@Test public void Nil_width_thumb_missing() {
fxt.Rdr("A.png|||0|0|0|0|0||8,-1,80")
.Src()
.Trg(fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|x||2?0,0|"))
.tst();
}
@Test public void Missing_do_not_redownload() {
fxt.Rdr("A.png|||0|0|0|0|0||8,45,40")
.Src( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|x||0?0,0|") // create reg and mark file missing
, fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/45px-A.png", 45, 40)) // create thumb (but should be ignored)
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|x||0?0,0|")) // note that 45,40 thumb does not show up
.tst();
}
@Test public void Ogg() {
fxt.Rdr("A.ogg|||0|0|0|0|0||0,-1,-1") // NOTE: ignore size even if set in lnk
.Src( fxt.ogg_("mem/src/commons.wikimedia.org/4/42/A.ogg")
, fxt.img_("mem/src/commons.wikimedia.org/thumb/4/42/A.ogg/mid-A.ogg.jpg", 300, 40)
)
.Trg( fxt.ogg_("mem/trg/commons.wikimedia.org/raw/4/2/A.ogg")
, fxt.img_("mem/trg/commons.wikimedia.org/fit/4/2/A.ogg/300px.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|0||1?0,0|1?300,40"
)
)
.tst();
}
@Test public void Ogv_width_standard() {
fxt.Rdr("A.ogv|||0|0|0|0|0||8,-1,-1") // NOTE: size matters for retrieval of thumb
.Src( fxt.ogg_("mem/src/commons.wikimedia.org/d/d0/A.ogv")
, fxt.img_("mem/src/commons.wikimedia.org/thumb/d/d0/A.ogv/mid-A.ogv.jpg", 300, 40)
)
.Trg( fxt.ogg_("mem/trg/commons.wikimedia.org/raw/d/0/A.ogv")
, fxt.img_("mem/trg/commons.wikimedia.org/fit/d/0/A.ogv/300px.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d0.csv", "A.ogv|0||1?0,0|1?300,40")
)
.tst();
}
@Test public void Ogv_width_custom() { // EX.WP:Earth;Northwest coast of United States to Central South America at Night.ogv|250px
fxt.Rdr("A.ogv|||0|0|0|0|0||8,250,-1")
.Src( fxt.ogg_("mem/src/commons.wikimedia.org/d/d0/A.ogv")
, fxt.img_("mem/src/commons.wikimedia.org/thumb/d/d0/A.ogv/mid-A.ogv.jpg", 640, 425)
)
.Trg( fxt.ogg_("mem/trg/commons.wikimedia.org/raw/d/0/A.ogv")
, fxt.img_("mem/trg/commons.wikimedia.org/fit/d/0/A.ogv/640px.jpg", 640, 425)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d0.csv", "A.ogv|0||1?0,0|1?640,425")
)
.tst();
}
@Test public void Ogv_width_seek() {
fxt.Rdr("A.ogv|||0|0|0|0|0||8,-1,-1,thumbtime=5") // NOTE: size matters for retrieval of thumb
.Src( fxt.ogg_("mem/src/commons.wikimedia.org/d/d0/A.ogv")
, fxt.img_("mem/src/commons.wikimedia.org/thumb/d/d0/A.ogv/seek%3D5-A.ogv.jpg", 300, 40)
)
.Trg( fxt.ogg_("mem/trg/commons.wikimedia.org/raw/d/0/A.ogv")
, fxt.img_("mem/trg/commons.wikimedia.org/fit/d/0/A.ogv/300px@5.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d0.csv", "A.ogv|0||1?0,0|1?300,40@5")
)
.tst();
}
@Test public void Djvu() {
fxt.Rdr("A.djvu|||10000|0|0|8|0||8,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/76/A.djvu/page1-45px-A.djvu.jpg", 45, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/6/A.djvu/45px.jpg", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/76.csv", "A.djvu|0||2?0,0|1?45,40")
)
.tst();
}
@Test public void Upright() { // PURPOSE: upright can generate thumb that is larger than orig; thumb is not on wmf, so orig must be used EX.WP:Saint Petersburg [[File:Georgyj Poltavchenko.jpeg|thumb|left|upright]]
fxt.Rdr("A.png|||0|0|0|0|0||8,-1,-1,upright=1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 148, 186))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 148, 186)
// , fxt.img_("mem/trg/commons.wikimedia.org/fit/7/70/A.png/130px.png", 130, 163) // FUTURE: should delete these since they are not used
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?148,186|1?148,186" // NOTE: upright=1 calculates width of 220; but since orig < 220, use orig
)
)
.tst();
fxt.tst_html_src("file:///mem/trg/commons.wikimedia.org/fit/7/0/A.png/148px.png"); // NOTE: changed from raw/A.png to fit/148px.png; DATE:2014-05-23
}
@Test public void Url_encoding_valid() { // PURPOSE: A%2Cb should (a) not become A%252Cb on file_system but (b) should have md5 calculated on A,b and (c) should be copied down as "A,b"
fxt.Rdr("A%2Cb.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/d/d6/A%2Cb.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/d/6/A,b.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d6.csv", "A,b.png|0||1?90,80|")
)
.tst();
}
@Test public void Url_encoding_invalid() { // PURPOSE: for invalid url encoding (%); note that A%b should not become A%25b on file_system
// Tfds.Write_bry(Xof_xfer_itm_.Md5_calc(Bry_.new_ascii_("A%b.png")));
fxt.Rdr("A%b.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/9/98/A%25b.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/9/8/A%b.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/9/98.csv", "A%b.png|0||1?90,80|")
)
.tst();
}
@Test public void Rounding() { // PURPOSE: bug; 3000,3002 image gets scaled to 99,99 instead of 100,100; EX.WP: Solar System#Visual summary
fxt.Rdr("A.png|||10000|3000|3002|8|0||0,100,100")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 3000, 3002))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 3000, 3002)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/100px.png", 100, 100)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||1?3000,3002|1?100,100"
)
)
.tst();
}
@Test public void Char_plus() {
fxt.Rdr("A+b.png|||10000|90|80|8|0||0,-1,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/d/d3/A%2Bb.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/d/3/A+b.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d3.csv", "A+b.png|0||1?90,80|"
)
)
.tst();
}
@Test public void Pdf_thumb() {
fxt.Rdr("A.pdf|||10000|0|0|8|0||0,45,-1")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/e/ef/A.pdf/page1-45px-A.pdf.jpg", 45, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/e/f/A.pdf/45px.jpg", 45, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/e/ef.csv", "A.pdf|0||2?0,0|1?45,40"
)
)
.tst();
}
}
class Xof_xfer_queue_bldr_fxt extends Xof_xfer_queue_html_fxt { Xof_xfer_itm xfer_itm = new Xof_xfer_itm();
Xof_xfer_queue queue = new Xof_xfer_queue();
@gplx.New public Xof_xfer_queue_bldr_fxt Src(Io_fil... v) {return (Xof_xfer_queue_bldr_fxt)Src_base(v);}
@gplx.New public Xof_xfer_queue_bldr_fxt Trg(Io_fil... v) {return (Xof_xfer_queue_bldr_fxt)Trg_base(v);}
public Xof_xfer_queue_bldr_fxt Rdr(String... v) {rdr = String_.Concat_lines_nl(v); return this;} private String rdr;
@Override public void Clear(boolean src_repo_is_wmf) {
super.Clear(src_repo_is_wmf);
bldr = Xoa_app_fxt.bldr_(this.App());
wkr = new Xobc_img_run_xfer(bldr, this.En_wiki());
GfoInvkAble_.InvkCmd_val(wkr, Xobc_img_run_xfer.Invk_rdr_dir_, "mem/rdr/");
} private Xob_bldr bldr; Xobc_img_run_xfer wkr;
@gplx.New public void tst() {
ini_src_fils();
Io_mgr._.SaveFilStr(wkr.Rdr_dir().GenSubFil("0000.csv"), rdr);
wkr.Cmd_bgn(bldr);
wkr.Cmd_run();
wkr.Cmd_end();
tst_trg_fils();
}
public void tst_html_src(String expd) {
boolean found = wkr.Xfer_itm().Atrs_calc_for_html();
Tfds.Eq(expd, String_.new_utf8_(wkr.Xfer_itm().Html_view_src()));
Tfds.Eq(true, found, "img not found");
}
}
///*
// @Test public void Thumb_resizeRaw() { // thumb does not exist; download raw and resize
// tstr.Lnki_("[[File:A.png|thumb]]").Src_xfer_("440,400", "mem/wiki/c0/7/70/A.png")
// .Expd_xfer_fail_
// ( "mem/wiki/c0/thumb/7/70/A.png/220px-A.png"
// , "mem/wiki/en/thumb/7/70/A.png/220px-A.png"
// )
// .Expd_xfer_pass_
// ( "mem/xowa/raw/7/0/A.png/440_400.png"
// , "mem/xowa/fit/7/0/A.png/220_200.png")
// .Expd_html_src_("file:///mem/xowa/fit/7/0/A.png/220_200.png")
// .Expd_fit_reg_
// ( "-1,-1|0|440,400"
// , "220,-1|1|220,200"
// )
// .tst()
// ;
// }
// @Test public void Thumb_upright() {
// tstr.Lnki_("[[File:A.png|thumb|upright]]").Src_xfer_("170,160", "mem/wiki/c0/thumb/7/70/A.png/170px-A.png")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_("mem/xowa/fit/7/0/A.png/170_160.png")
// .Expd_html_src_("file:///mem/xowa/fit/7/0/A.png/170_160.png")
// .Expd_fit_reg_
// ( "170,-1|1|170,160"
// )
// .tst()
// ;
// }
// @Test public void Thumb_height() {
// tstr.Lnki_("[[File:A.png|thumb|x50px]]").Src_xfer_("200,100", "mem/wiki/c0/7/70/A.png")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_
// ( "mem/xowa/raw/7/0/A.png/200_100.png"
// , "mem/xowa/fit/7/0/A.png/100_50.png"
// )
// .Expd_html_src_("file:///mem/xowa/fit/7/0/A.png/100_50.png")
// .Expd_fit_reg_
// ( "-1,-1|0|200,100"
// , "-1,50|1|100,50"
// )
// .tst()
// ;
// }
// @Test public void Thumb_height_no_resize() {
// tstr.Lnki_("[[File:A.png|thumb|x100px]]").Src_xfer_("200,100", "mem/wiki/c0/7/70/A.png")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_("mem/xowa/raw/7/0/A.png/200_100.png")
// .Expd_html_src_("file:///mem/xowa/raw/7/0/A.png/200_100.png")
// .Expd_fit_reg_
// ( "-1,-1|0|200,100"
// , "-1,100|0|200,100"
// )
// .tst()
// ;
// }
// @Test public void Thumb_width_basic() {
// tstr.Lnki_("[[File:A.png|thumb|100px]]").Src_xfer_("100,50", "mem/wiki/c0/thumb/7/70/A.png/100px-A.png")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_("mem/xowa/fit/7/0/A.png/100_50.png")
// .Expd_html_src_("file:///mem/xowa/fit/7/0/A.png/100_50.png")
// .Expd_fit_reg_
// ( "100,-1|1|100,50"
// )
// .tst()
// ;
// }
// @Test public void Thumb_resize_width_too_long() { // lnki width > raw; just use raw // WP.EX:[[File:Adhanema Lasva.jpg|thumb|300px|The Firman given to the Bosnian Franciscans]]; src=149,408
// tstr.Lnki_("[[File:A.png|thumb|200px]]").Src_xfer_("100,50", "mem/wiki/c0/7/70/A.png")
// .Expd_xfer_fail_
// ( "mem/wiki/c0/thumb/7/70/A.png/200px-A.png"
// , "mem/wiki/en/thumb/7/70/A.png/200px-A.png")
// .Expd_xfer_pass_
// ( "mem/xowa/raw/7/0/A.png/100_50.png"
// )
// .Expd_html_src_("file:///mem/xowa/raw/7/0/A.png/100_50.png")
// .Expd_fit_reg_
// ( "-1,-1|0|100,50"
// , "200,-1|0|100,50"
// )
// .tst()
// ;
// }
// @Test public void Thumb_resize_width_is_wrong() { // size does not match scaling; recalc; // WP.EX:[[File:Firma B.Ohiggins.svg|128x80px|alt=|Bernardo O'Higgins's signature]]; src=720,196
// tstr.Lnki_("[[File:A.png|thumb|128x80px]]").Src_xfer_("720,196", "mem/wiki/c0/7/70/A.png")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_("mem/xowa/raw/7/0/A.png/720_196.png", "mem/xowa/fit/7/0/A.png/128_34.png")
// .Expd_html_src_("file:///mem/xowa/fit/7/0/A.png/128_34.png")
// .Expd_fit_reg_
// ( "-1,-1|0|720,196"
// , "128,80|1|128,34"
// )
// .tst()
// ;
// }
// @Test public void Svg_height() {
// tstr.Lnki_("[[File:A.svg|x20px]]")
// .Src_xfer_(tstr.file_svg(80, 100) , "mem/wiki/c0/7/75/A.svg")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_
// ( "mem/xowa/raw/7/5/A.svg/80_100.svg"
// , "mem/xowa/fit/7/5/A.svg/16_20.png"
// )
// .Expd_html_src_("file:///mem/xowa/fit/7/5/A.svg/16_20.png")
// .Expd_fit_reg_
// ( "-1,20|1|16,20"
// )
// .tst()
// ;
// }
// @Test public void Svg_height_overrides_width() {
// tstr.Lnki_("[[File:A.svg|20x20px]]")
// .Src_xfer_(tstr.file_svg(80, 100) , "mem/wiki/c0/7/75/A.svg")
// .Expd_xfer_fail_()
// .Expd_xfer_pass_
// ( "mem/xowa/raw/7/5/A.svg/80_100.svg"
// , "mem/xowa/fit/7/5/A.svg/16_20.png"
// )
// .Expd_html_src_("file:///mem/xowa/fit/7/5/A.svg/16_20.png")
// .Expd_fit_reg_
// ( "20,20|1|16,20"
// )
// .tst()
// ;
// }
// @Test public void Svg_resize_width_too_long() {
// tstr.Lnki_("[[File:A.svg|50x40px]]")
// .Src_xfer_(tstr.file_svg(40, 40) , "mem/wiki/c0/7/75/A.svg")
// .Expd_xfer_pass_
// ( "mem/xowa/raw/7/5/A.svg/40_40.svg"
// , "mem/xowa/fit/7/5/A.svg/40_40.png")
// .Expd_html_src_("file:///mem/xowa/fit/7/5/A.svg/40_40.png")
// .Expd_fit_reg_
// ( "50,40|1|40,40"
// )
// .tst()
// ;
// }
//*/

View File

@@ -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; import gplx.*;
import org.junit.*;
import gplx.ios.*; import gplx.gfui.*; import gplx.xowa.files.*;
public class Xof_xfer_queue_html_basic_tst {
Xof_xfer_queue_html_fxt fxt = new Xof_xfer_queue_html_fxt();
@Before public void init() {fxt.Clear(true);}
@Test public void Main_orig() {
fxt .ini_page_create_en_wiki("File:A.png");
fxt .Lnki_orig_("A.png")
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|y||1?900,800|")
);
fxt.tst();
}
@Test public void Main_thumb_download() {
fxt .ini_page_create_en_wiki("File:A.png");
fxt .Lnki_thumb_("A.png", 90)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/90px-A.png", 90, 80))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|y||2?0,0|1?90,80")
);
fxt.tst();
}
@Test public void Main_thumb_convert() {
fxt .ini_page_create_en_wiki("File:A.png");
fxt .Lnki_thumb_("A.png", 90)
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/raw/7/0/A.png", 900, 800)
, fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|y||1?900,800|1?90,80")
);
fxt.tst();
}
@Test public void Ptr_orig() {
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .ini_page_create_en_wiki_redirect ("File:B.png", "File:A.png");
fxt .Lnki_orig_("B.png")
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv", "B.png|y|A.png|1?900,800|")
);
fxt.tst();
fxt .Lnki_orig_("B.png")
.Html_src_("file:///mem/trg/en.wikipedia.org/raw/7/0/A.png")
.tst();
}
@Test public void Ptr_thumb_download() {
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .ini_page_create_en_wiki_redirect ("File:B.png", "File:A.png");
fxt .Lnki_thumb_("B.png", 90)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/90px-A.png", 90, 80))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv", "B.png|y|A.png|2?0,0|1?90,80")
);
fxt.tst();
}
@Test public void Ptr_thumb_convert() {
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .ini_page_create_en_wiki_redirect ("File:B.png", "File:A.png");
fxt .Lnki_thumb_("B.png", 90)
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/raw/7/0/A.png", 900, 800)
, fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv", "B.png|y|A.png|1?900,800|1?90,80")
);
fxt.tst();
}
@Test public void Vrtl_orig() {
fxt .ini_page_create_commons ("File:A.png");
fxt .Lnki_orig_("A.png")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|0||1?900,800|")
);
fxt.tst();
}
@Test public void Vrtl_thumb_download() {
fxt .ini_page_create_commons ("File:A.png");
fxt .Lnki_thumb_("A.png", 90)
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/90px-A.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|0||2?0,0|1?90,80")
);
fxt.tst();
}
@Test public void Vrtl_thumb_convert() {
fxt .ini_page_create_commons ("File:A.png");
fxt .Lnki_thumb_("A.png", 90)
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 900, 800)
, fxt.img_("mem/trg/commons.wikimedia.org/fit/7/0/A.png/90px.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|0||1?900,800|1?90,80")
);
fxt.tst();
}
@Test public void Vrtl_ptr_orig() {
fxt .ini_page_create_commons_redirect ("File:B.png", "File:A.png");
fxt .ini_page_create_commons ("File:A.png");
fxt .Lnki_orig_("B.png")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv" , "B.png|0|A.png|1?900,800|")
);
fxt.tst();
}
@Test public void Ptr_vrtl_orig() {
fxt .ini_page_create_en_wiki_redirect ("File:B.png", "File:A.png");
fxt .ini_page_create_commons ("File:A.png");
fxt .Lnki_orig_("B.png")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 900, 800))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv" , "B.png|y|A.png|1?900,800|")
);
fxt.tst();
}
}

View File

@@ -0,0 +1,281 @@
/*
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; import gplx.*;
import org.junit.*;
import gplx.xowa.files.*;
public class Xof_xfer_queue_html_cases_tst {
Xof_xfer_queue_html_fxt fxt = new Xof_xfer_queue_html_fxt();
@Before public void init() {
fxt.Clear(true);
}
@Test public void Png_missing() {
fxt .Lnki_orig_("A.png")
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|z||0?0,0|")
);
fxt.tst();
}
@Test public void Png_missing_2() { // PURPOSE: orig is missing; do not download again; NOTE: simulating "do not download again" check by putting in thumb and making sure it doesn't get downloaded
fxt.save_(fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|z||0?0,0|")); // save reg file and mark file as missing
fxt .Lnki_thumb_("A.png", 90)
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/90px-A.png", 90, 80))
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|z||0?0,0|") // NOTE: 90,80 should not show up
);
fxt.tst();
}
@Test public void Png_encode() { // PURPOSE: make sure \s is converted to _; also ' should not be encoded on trg; done
fxt .ini_page_create_commons ("File:A'b c.png");
fxt .Lnki_orig_("A'b c.png")
.Src( fxt.img_("mem/src/commons.wikimedia.org/9/9c/A%27b_c.png", 90, 80))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/9/c/A'b_c.png", 90, 80)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/9/9c.csv", "A'b_c.png|0||1?90,80|")
);
fxt.tst();
}
@Test public void Ogg_vid_thumb() {
fxt .ini_page_create_commons ("File:A.ogg");
fxt .Lnki_orig_("A.ogg")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/4/42/A.ogg/mid-A.ogg.jpg", 300, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/4/2/A.ogg/300px.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|0||0?0,0|1?300,40")
);
fxt.tst();
}
@Test public void Ogg_vid_missing_thumb() {
fxt .Lnki_orig_("A.ogg")
.Src( )
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|z||0?0,0|0?0,0") // NOTE: mark thumb not found (since xfer_mgr checked all repos)
);
fxt.tst();
}
@Test public void Aud_do_not_download() {
fxt.save_(fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|z||2?0,0|0?0,0")); // save reg file and mark file as aud
fxt .Lnki_orig_("A.ogg")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/4/42/A.ogg/mid-A.ogg.jpg", 300, 40) // simulate thumb (make sure test does not download)
)
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "A.ogg|z||2?0,0|0?0,0") // 300,40 should not show up
);
fxt.tst();
}
@Test public void Img_thumb_djvu() {// PURPOSE: exact djvu thumbs are not on server; always seems to retrieve 1 off;
fxt .ini_page_create_commons ("File:A.djvu");
fxt .App().File_mgr().Img_mgr().Wkr_convert_djvu_to_tiff_(new Xof_img_wkr_convert_djvu_to_tiff_mok(199, 299));
fxt .Lnki_thumb_("A.djvu", 200)
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/76/A.djvu", 1990, 2990)
)
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/7/6/A.djvu/199px.jpg", 199, 299)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/76.csv", "A.djvu|0||1?0,0|1?199,299")
);
fxt.tst();
fxt .Lnki_thumb_("A.djvu", 200)
.Html_src_("file:///mem/trg/commons.wikimedia.org/fit/7/6/A.djvu/199px.jpg")
.Html_size_(200, 301)
.tst();
}
@Test public void Img_thumb_pdf() {// PURPOSE: download pdf thumb only; [[File:Physical world.pdf|thumb]]
fxt .ini_page_create_commons ("File:A.pdf");
fxt .Lnki_thumb_("A.pdf", 220)
.Src( fxt.img_("mem/src/commons.wikimedia.org/e/ef/A.pdf", 2200, 1700)
, fxt.img_("mem/src/commons.wikimedia.org/thumb/e/ef/A.pdf/page1-220px-A.pdf.jpg", 220, 170)
)
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/e/f/A.pdf/220px.jpg", 220, 170)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/e/ef.csv", "A.pdf|0||2?0,0|1?220,170")
);
fxt.tst();
fxt .Lnki_thumb_("A.pdf", 220)
.Html_src_("file:///mem/trg/commons.wikimedia.org/fit/e/f/A.pdf/220px.jpg")
.Html_size_(220, 170)
.tst();
}
@Test public void Img_missing_wiki_0() { // PURPOSE.outlier: page is in wiki_1 but file is actually in wiki_0; download from wiki_0; occurs when working with old commons/en.wikipedia.org against current wmf servers; EX: Mars Science Laboratory and File:Curiosity wheel pattern morse code.png; Curiosity rover
fxt .ini_page_create_en_wiki ("File:A.png"); // page is in en_wiki
fxt .Lnki_orig_("A.png")
.Src( fxt.img_("mem/src/commons.wikimedia.org/7/70/A.png", 900, 800)) // file is in commons
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/7/0/A.png", 900, 800)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||1?900,800|")
);
fxt.tst();
}
// @Test public void Img_missing_wiki_1() { // PURPOSE.outlier: page is in wiki_0 and in wiki_1; file is in wiki_1; EX:[[Image:Alcott-L.jpg|thumb|right|Louisa May Alcott]]
// fxt .ini_page_create_commons ("File:A.png"); // page is in commons also
// fxt .ini_page_create_en_wiki ("File:A.png"); // page is in en_wiki
// fxt .Lnki_thumb_("A.png", 220)
// .Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/220px-A.png", 220, 110)) // file is in en_wiki
// .Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/220px.png", 220, 110) // download en_wiki
// , fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "2|A.png|y||2?0,0|1?220,110")
// );
// fxt.tst();
// }
@Test public void Do_not_download_orig_0() {// PURPOSE: do not download orig if size can be inferred from thumb; EX: [[File:Vanadium etched.jpg|350x250px|Vanadium]]
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .Lnki_thumb_("A.png", 350, 250) // requesting w=350 and h=250; note that h trumps w
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/350px-A.png", 350, 309) // w=350 exists, but should not be used
, fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/283px-A.png", 283, 250) // h=250 exists, and should be used
, fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 3808, 3364) // orig image exists, and should not be downloaded
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/283px.png" , 283, 250)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?283,250") // note that orig does not exist
);
fxt.tst();
fxt.fil_absent( "mem/trg/en.wikipedia.org/raw/7/0/A.png");
fxt .Lnki_thumb_("A.png", 350, 250)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/0/A.png/283px.png")
.tst();
}
@Test public void Do_not_download_orig_1() {// PURPOSE: allow variance of 1 for thumbs (rounding errors); EX:<gallery>Image:President Woodrow Wilson portrait December 2 1912.jpg|US President Woodrow Wilson</gallery>
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .Lnki_thumb_("A.png", 120, 120) // requesting 120,120 (gallery default); note that h trumps w
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/120px-A.png", 120, 146) // w=120 exists, but should not be used
, fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/99px-A.png", 99, 121) // true width should be w=98, but b/c of rounding off of large 2976, getting 99 instead
, fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 2976, 3623) // orig image exists, and should not be downloaded
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/99px.png" , 99, 121)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?99,121") // note that orig does not exist
);
fxt.tst();
fxt.fil_absent( "mem/trg/en.wikipedia.org/raw/7/0/A.png");
fxt .Lnki_thumb_("A.png", 120, 120) // note that 120 is requested
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/0/A.png/99px.png") // note that image used is 99
.Html_size_(98, 120) // note that view width is 98
.tst();
}
@Test public void Do_not_download_orig_3() {// PURPOSE.defect: account for multiple thumbs; EX: <gallery heights="380" widths="454">File:Rembrandt van Rijn-De Nachtwacht-1642.jpg|1642.</gallery>
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .Lnki_thumb_("A.png", 454, 380) // standard request
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/454px-A.png", 454, 380)
, fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 3344, 2796)
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/454px.png" , 454, 380)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?454,380") // note that orig does not exist
);
fxt.tst();
fxt.fil_absent( "mem/trg/en.wikipedia.org/raw/7/0/A.png");
fxt .Lnki_thumb_("A.png", 718, 600) // this is the defect; 718 was not being brought down; instead 454 was being reused
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/718px-A.png", 718, 600)
, fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 3344, 2796)
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/718px.png" , 718, 600)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?454,380;1?718,600") // note that orig does not exist
)
.tst();
}
@Test public void Do_not_download_orig_height() {// PURPOSE: handles links with only height specified; EX: [[File:Fresh_Pesto.jpeg|x210px|center]]
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .Lnki_thumb_("A.png", -1, 210) // height-only request
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/291px-A.png", 291, 210)
, fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/220px-A.png", 220, 159)
, fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 2910, 2100)
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/291px.png" , 291, 210)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?220,159;1?291,210") // note that orig does not exist
);
fxt.tst();
fxt .Lnki_thumb_("A.png", -1, 210)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/0/A.png/291px.png")
.Html_size_(291, 210)
.tst();
}
@Test public void Upright_size_incorrect() {// PURPOSE.fix: incorrect image size being brought down; EX: w:ASCII; [[Image:ASCII Code Chart.svg|thumb|right|upright=1.6]]; 264, but should be 350
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .Lnki_("A.png", true, -1, -1, 1.6, Xof_doc_thumb.Null_as_int) // upright
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 830, 328)
, fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/350px-A.png", 350, 138)
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/350px.png" , 350, 138)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?350,138")
);
fxt.tst();
}
@Test public void Width_height_retrieves_wrong_size() {// PURPOSE.fix: EX: c:Yellowstone Park; [[Image:YellowstoneLake.jpg|Yellowstone Lake|120x120px|thumb]];
fxt .ini_page_create_en_wiki ("File:A.png");
fxt .Lnki_thumb_("A.png", 120, 120)
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 1756, 1204)
, fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/120px-A.png", 119, 82) // NOTE: wmf has 119px width, even though 120px file_name
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/119px.png" , 119, 82)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?0,0|1?119,82")
);
fxt.tst();
fxt .Lnki_thumb_("A.png", 120, 120)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/0/A.png/119px.png")
.Html_size_(120, 83)
.tst();
}
@Test public void Svg_thumb_can_be_bigger_than_orig__convert() {// PURPOSE: svg thumbs allowed to exceed orig in size; EX: w:Portal:Music; [[File:Treble a.svg|left|160px]]
fxt .ini_page_create_en_wiki ("File:A.svg");
fxt .Lnki_thumb_("A.svg", 220) // thumb = 220
.Src( fxt.svg_("mem/src/en.wikipedia.org/7/75/A.svg", 110, 100) // orig = 110
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/5/A.svg/220px.png" , 220, 200) // thumb = 220; not limited to 110
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv" , "A.svg|y||1?110,100|1?220,200")
)
.tst(
);
fxt .Lnki_thumb_("A.svg", 220)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/5/A.svg/220px.png")
.Html_size_(220, 200)
.tst();
}
@Test public void Ogv_width_seek_again_should_dirty() { // PURPOSE: outlier case wherein (a) downloading thumb then (b) downloading thumb seek; (b) does not dirty file since (a) exists; EX.WP: Wikipedia
fxt.Src_en_wiki_repo().Ext_rules().Get_or_new(Xof_ext_.Bry_ogv).View_max_(0);
Io_mgr._.SaveFilStr("mem/xowa/file/#meta/en.wikipedia.org/d/d0.csv", "A.ogv|0||2?0,0|1?300,40\n"); // simulate (a)
fxt .Lnki_("A.ogv", true, -1, -1, -1, 5)
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/d/d0/A.ogv/seek%3D5-A.ogv.jpg", 300, 40)
)
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/d/0/A.ogv/300px@5.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d0.csv", "A.ogv|0||2?0,0|1?300,40@5")
)
.tst();
fxt.Src_en_wiki_repo().Ext_rules().Get_or_new(Xof_ext_.Bry_ogv).View_max_(-1);
}
@Test public void Webm() {
fxt .ini_page_create_commons ("File:A.webm");
fxt .Lnki_thumb_("A.webm", 220)
.Src( fxt.ogg_("mem/src/commons.wikimedia.org/3/34/A.webm")
, fxt.img_("mem/src/commons.wikimedia.org/thumb/3/34/A.webm/mid-A.webm.jpg", 300, 40)
)
.Trg( fxt.ogg_("mem/trg/commons.wikimedia.org/raw/3/4/A.webm")
, fxt.img_("mem/trg/commons.wikimedia.org/fit/3/4/A.webm/300px.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/3/34.csv", "A.webm|0||1?0,0|1?300,40")
)
.tst();
}
@Test public void Ogv_thumb() {// d00d1d5019e37cc219a91a2f8ad47bfe
fxt .ini_page_create_commons ("File:A.ogv");
fxt .Lnki_orig_("A.ogv")
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/d/d0/A.ogv/mid-A.ogv.jpg", 300, 40))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/fit/d/0/A.ogv/300px.jpg", 300, 40)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/d/d0.csv", "A.ogv|0||0?0,0|1?300,40")
)
.tst();
fxt .Lnki_orig_("A.ogv")
.Html_src_("file:///mem/trg/commons.wikimedia.org/fit/d/0/A.ogv/300px.jpg")
.Html_size_(300, 40)
.tst();
}
// @Test public void Ogg_full_skip() { // DISABLED: 2012-12-03; not sure about logic
// fxt .ini_page_create_commons ("File:A.ogg");
// fxt .En_wiki().File_mgr().Repo_mgr().Repos_get_at(0).Src().Ext_rules().Get_or_new(Xof_ext_.Bry_ogg).View_max_(0); // set ogg to do not download
// fxt .Lnki_orig_("A.ogg")
// .Src( fxt.ogg_("mem/src/commons.wikimedia.org/4/2/A.ogg"))
// .Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv", "2|A.ogg|0|2?0,0|")
// );
// fxt.tst();
// fxt .En_wiki().File_mgr().Repo_mgr().Repos_get_at(0).Src().Ext_rules().Get_or_new(Xof_ext_.Bry_ogg).View_max_(1000); // undo above
// }
}

View File

@@ -0,0 +1,58 @@
/*
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; import gplx.*;
import gplx.ios.*; import gplx.xowa.files.*;
public class Xof_xfer_queue_html_fxt extends Xof_xfer_queue_base_fxt {
@Override public void Clear(boolean src_repo_is_wmf) {
super.Clear(src_repo_is_wmf);
this.Api_size().Clear();
}
public Xof_xfer_queue_html_fxt Lnki_orig_ (String lnki_ttl) {return Lnki_(lnki_ttl, Bool_.N, Xof_img_size.Size_null_deprecated, Xof_img_size.Size_null_deprecated, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int);}
public Xof_xfer_queue_html_fxt Lnki_thumb_(String lnki_ttl, int lnki_w) {return Lnki_(lnki_ttl, Bool_.Y, lnki_w, Xof_img_size.Size_null_deprecated, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int);}
public Xof_xfer_queue_html_fxt Lnki_thumb_(String lnki_ttl, int lnki_w, int lnki_h) {return Lnki_(lnki_ttl, Bool_.Y, lnki_w, lnki_h, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int);}
public Xof_xfer_queue_html_fxt Lnki_(String lnki_ttl, boolean thumb, int lnki_w, int lnki_h, double upright, int seek_time) { // NOTE: only one xfer_itm; supports one Lnki_ per test only
Xow_wiki wiki = this.En_wiki();
xfer_itm = wiki.Html_mgr().Html_wtr().Lnki_wtr().File_wtr().Lnki_eval(wiki.Ctx(), queue, Bry_.new_utf8_(lnki_ttl), thumb ? Xop_lnki_type.Id_thumb : Xop_lnki_type.Id_null, lnki_w, lnki_h, upright, Xof_doc_thumb.X_int(seek_time), Xof_doc_page.Null, false, queue_add_ref);
return this;
} private Xof_xfer_itm xfer_itm = new Xof_xfer_itm(); Bool_obj_ref queue_add_ref = Bool_obj_ref.n_();
Xof_xfer_queue queue = new Xof_xfer_queue();
public Xof_xfer_queue_html_fxt Src(Io_fil... v) {return (Xof_xfer_queue_html_fxt)Src_base(v);}
public Xof_xfer_queue_html_fxt Trg(Io_fil... v) {return (Xof_xfer_queue_html_fxt)Trg_base(v);}
public Xof_xfer_queue_html_fxt Html_src_(String v) {return (Xof_xfer_queue_html_fxt)Html_src_base_(v);}
public Xof_xfer_queue_html_fxt Html_size_(int w, int h) {this.Html_w_(w); this.Html_h_(h); return this;}
public Xof_xfer_queue_html_fxt Html_orig_src_(String v) {html_orig_src = v; return this;} private String html_orig_src;
public Xof_xfer_queue_html_fxt ini_page_api(String wiki_str, String ttl_str, String redirect_str, int orig_w, int orig_h) {return ini_page_api(wiki_str, ttl_str, redirect_str, orig_w, orig_h, true);}
public Xof_xfer_queue_html_fxt ini_page_api(String wiki_str, String ttl_str, String redirect_str, int orig_w, int orig_h, boolean pass) {
String wiki_key = String_.Eq(wiki_str, "commons") ? Xow_wiki_.Domain_commons_str : Xow_wiki_.Domain_enwiki_str;
this.Api_size().Ini(wiki_key, ttl_str, redirect_str, orig_w, orig_h, pass);
return this;
}
public void tst() {
Xow_wiki wiki = this.En_wiki();
ini_src_fils();
wiki.App().File_mgr().Download_mgr().Enabled_(true);
wiki.File_mgr().Cfg_download().Enabled_(true);
queue.Exec(Xof_exec_tid.Tid_wiki_page, usr_dlg, wiki, Xoa_page.Empty);
tst_trg_fils();
if (this.html_orig_src != null) Tfds.Eq(this.html_orig_src , String_.new_utf8_(xfer_itm.Html_orig_src()));
if (this.Html_view_src() != null) Tfds.Eq(this.Html_view_src(), String_.new_utf8_(xfer_itm.Html_view_src()));
if (this.Html_w() != -1) Tfds.Eq(this.Html_w(), xfer_itm.Html_w());
if (this.Html_h() != -1) Tfds.Eq(this.Html_h(), xfer_itm.Html_h());
queue.Clear();
} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Null;
}

View File

@@ -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; import gplx.*;
import org.junit.*;
import gplx.xowa.files.*;
public class Xof_xfer_queue_html_offline_tst {
Xof_xfer_queue_html_fxt fxt = new Xof_xfer_queue_html_fxt();
@Before public void init() {fxt.Clear(true); fxt.Src_commons_repo().Tarball_(true); fxt.Src_en_wiki_repo().Tarball_(true);}
@Test public void Missing() { // PURPOSE.fix: missing image was not being marked as missing; DATE:20121227
fxt .Lnki_("A.png", true, 220, -1, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int)
.Src()
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|x||0?0,0|")
)
.tst();
}
}

View File

@@ -0,0 +1,160 @@
/*
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; import gplx.*;
import org.junit.*;
import gplx.xowa.files.*;
public class Xof_xfer_queue_html_wmf_api_tst {
Xof_xfer_queue_html_fxt fxt = new Xof_xfer_queue_html_fxt();
@Before public void init() {fxt.Clear(true); fxt.Src_commons_repo().Wmf_api_(true); fxt.Src_en_wiki_repo().Wmf_api_(true);}
@Test public void Thumb() {
fxt .ini_page_api("en_wiki", "A.png", "", 2200, 2000);
fxt .Lnki_thumb_("A.png", 220)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/220px-A.png", 220, 200))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/220px.png", 220, 200)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|y||2?2200,2000|1?220,200")
)
.tst();
}
@Test public void Redirect() {
fxt .ini_page_api("en_wiki", "B.png", "A.png", 2200, 2000);
fxt .Lnki_thumb_("B.png", 220)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/220px-A.png", 220, 200))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/220px.png", 220, 200)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/5/57.csv", "B.png|y|A.png|2?2200,2000|1?220,200")
)
.tst();
}
@Test public void Svg_thumb_can_be_bigger_than_orig__download() {// PURPOSE: svg thumbs allowed to exceed orig in size; EX: w:Portal:Music; [[File:Treble a.svg|left|160px]]
fxt .ini_page_api("en_wiki", "A.svg", "", 110, 100); // put orig of 110,100 on server
fxt .Lnki_thumb_("A.svg", 220) // request 220
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/75/A.svg/220px-A.svg.png", 220, 200) // thumb = 220
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/5/A.svg/220px.png" , 220, 200) // thumb = 220
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/75.csv" , "A.svg|y||2?110,100|1?220,200")
)
.tst();
fxt .Lnki_thumb_("A.svg", 220)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/5/A.svg/220px.png")
.Html_size_(220, 200)
.tst();
}
@Test public void Pdf() {// PURPOSE: main page always assumes size of 800x600; if actual size does not scale to 800x600, don't redownload; [[File:Physical world.pdf|thumb]]
fxt.ini_page_api("en_wiki", "A.pdf", "", 6600, 5100);
fxt .ini_page_create_commons ("File:A.pdf");
fxt .Lnki_thumb_("A.pdf", 800, 600)
.Src( fxt.img_("mem/src/en.wikipedia.org/e/ef/A.pdf", 6600, 5100)
, fxt.img_("mem/src/en.wikipedia.org/thumb/e/ef/A.pdf/page1-777px-A.pdf.jpg", 777, 600)
)
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/e/f/A.pdf/777px.jpg", 777, 600)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/e/ef.csv", "A.pdf|y||2?6600,5100|1?777,600")
)
.tst();
fxt .Lnki_thumb_("A.pdf", 800, 600)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/e/f/A.pdf/777px.jpg")
.Html_size_(777, 600)
.tst();
}
@Test public void Upright_defect() { // PURPOSE.fix: upright not working; PAGE:en.w:Beethoven; [[File:Rudolf-habsburg-olmuetz.jpg|thumb|upright|]]; changed upright to = Upright_default; DATE:2014-05-23
fxt .ini_page_api("en_wiki", "A.png", "", 1378, 1829);
fxt .Lnki_("A.png", true, -1, -1, Xof_img_size.Upright_default, Xof_doc_thumb.Null_as_int)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/170px-A.png", 170, 226))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/170px.png", 170, 226)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?1378,1829|1?170,226")
)
.tst();
}
@Test public void Height_only() { // PURPOSE.fix: height only was still using old infer-size code; EX:w:[[File:Upper and Middle Manhattan.jpg|x120px]]; DATE:2012-12-27
fxt .ini_page_api("en_wiki", "A.png", "", 12591, 1847);
fxt .Lnki_("A.png", false, -1, 130, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/887px-A.png", 887, 130))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/887px.png", 887, 130)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?12591,1847|1?887,130")
)
.tst();
}
@Test public void Width_only_height_ignored() {// PURPOSE.fix: if height is not specified, do not recalc; needed when true scaled height is 150x151 but WM has 150x158; defect would discard 150x158; EX:[[File:Tokage_2011-07-15.jpg|150px]] simple.wikipedia.org/wiki/2011_Pacific_typhoon_season; DATE:2013-06-03
fxt .ini_page_api("en_wiki", "A.png", "", 4884, 4932);
fxt .Lnki_("A.png", true, 150, -1, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/7/70/A.png/150px-A.png", 150, 158))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/7/0/A.png/150px.png", 150, 158)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|y||2?4884,4932|1?150,158")
)
.tst();
}
@Test public void Missing_was_not_being_marked() { // PURPOSE.fix: missing image was not showing up as repo=x in meta; DATE:2013-01-10
fxt .Lnki_("A.png", false, -1, 130, Xop_lnki_tkn.Upright_null, Xof_doc_thumb.Null_as_int)
.Src()
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|x||0?0,0|")
)
.tst();
}
@Test public void Missing_was_not_redownloaded() { // PURPOSE.fix: missing image was not being redownloaded; DATE:2013-01-26
fxt.save_(fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|x||0?0,0|")); // mark file as missing
fxt .ini_page_api("en_wiki", "A.png", "", 220, 200);
fxt.En_wiki().File_mgr().Cfg_download().Redownload_(Xof_cfg_download.Redownload_missing); // redownload for missing
fxt .Lnki_orig_("A.png")
.Src( fxt.img_("mem/src/en.wikipedia.org/7/70/A.png", 220, 200))
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv" , "A.png|x||1?220,200|")// check that file shows up
)
.tst();
fxt.En_wiki().File_mgr().Cfg_download().Redownload_(Xof_cfg_download.Redownload_none); // redownload back to none (for other tests)
}
@Test public void Error_should_not_abort() { // PURPOSE: API sometimes returns xml but no <iinfo> node; try to download anyway
fxt .ini_page_api("commons", "A.png", "", 2200, 2000, false);
fxt .Lnki_thumb_("A.png", 220)
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/7/70/A.png/220px-A.png", 220, 200))
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0||0?0,0|1?220,200")
)
.tst();
}
@Test public void Tilde() {
fxt .ini_page_api("en_wiki", "A~.png", "", 2200, 2000);
fxt .Lnki_thumb_("A~.png", 220)
.Src( fxt.img_("mem/src/en.wikipedia.org/thumb/a/a5/A%7E.png/220px-A%7E.png", 220, 200))
.Trg( fxt.img_("mem/trg/en.wikipedia.org/fit/a/5/A~.png/220px.png", 220, 200)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/a/a5.csv", "A~~.png|y||2?2200,2000|1?220,200") // NOTE: tildes are doubled in meta file
)
.tst();
}
@Test public void Missing_from_1st_repo() { // PURPOSE: WMF now requires that API goes to image's actual repo (used to accept http://en.wikipedia.org and return back http://commons.wikimedia.org) DATE:2013-03-11
fxt .ini_page_api("commons", "A.png", "B.png", 2200, 2000); // put the redirect in commons wiki
fxt .Lnki_thumb_("A.png", 220)
.Src( fxt.img_("mem/src/commons.wikimedia.org/thumb/5/57/B.png/220px-B.png", 220, 200))
.Trg( fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|0|B.png|2?2200,2000|1?220,200")
)
.tst();
}
@Test public void Ogg_audio() { // PURPOSE: ogg is audio; (a) do not download thumb; (b) get from correct wiki; DATE:2013-08-03
fxt .ini_page_create_commons("File:A.ogg");
fxt .ini_page_api("commons", "A.ogg", "", 0, 0);
fxt .Lnki_("A.ogg", false, -1, -1, 1, Xof_doc_thumb.Null_as_int)
.Src( fxt.img_("mem/src/commons.wikimedia.org/4/42/A.ogg", 0, 0))
.Trg( fxt.img_("mem/trg/commons.wikimedia.org/raw/4/2/A.ogg", 0, 0)
, fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/4/42.csv" , "A.ogg|0||1?0,0|0?0,0")
)
.tst();
}
@Test public void Height_should_precede_width() {// PURPOSE: height should precede width; EX: <gallery>David_Self_Portrait.jpg</gallery>; c:Jacques-Louis David
fxt.save_(fxt.reg_("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|z||2?0,0|1?86,121;1?120,168"));
fxt .Lnki_thumb_("A.png", 120, 120)
.Html_src_("file:///mem/trg/en.wikipedia.org/fit/7/0/A.png/86px.png")
.Html_size_(85, 120)
.tst();
}
}
// Tfds.Write_bry(Xof_xfer_itm_.Md5_calc(Bry_.new_ascii_("A~.png")));

View File

@@ -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; import gplx.*;
public class Xof_xfer_rslt {
public boolean Pass() {return pass;} private boolean pass = true;
public String Err_msg() {return err_msg;} private String err_msg = String_.Empty;
public String Src() {return src;} private String src;
public Io_url Trg() {return trg;} public Xof_xfer_rslt Trg_(Io_url v) {trg = v; return this;} Io_url trg;
public void Atrs_src_trg_(String src, Io_url trg) {this.src = src; this.trg = trg;}
public boolean Fail(String msg) {
pass = false;
err_msg = msg;
return false;
}
public void Clear() {pass = true; err_msg = src = String_.Empty; trg = Io_url_.Null;}
}

View File

@@ -0,0 +1,241 @@
/*
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; import gplx.*;
import gplx.xowa.wikis.*; import gplx.xowa.files.*;
public class Xow_repo_mgr implements GfoInvkAble {
public Xow_repo_mgr(Xow_wiki wiki) {
this.wiki = wiki;
Xoa_app app = wiki.App();
xfer_mgr = new Xof_xfer_mgr(app.File_mgr());
page_finder = new Xofw_wiki_wkr_base(wiki, app.Wiki_mgr());
} private Xow_wiki wiki;
public Xof_xfer_mgr Xfer_mgr() {return xfer_mgr;} private Xof_xfer_mgr xfer_mgr;
public Xofw_wiki_finder Page_finder() {return page_finder;} public Xow_repo_mgr Page_finder_(Xofw_wiki_finder v) {page_finder = v; return this;} private Xofw_wiki_finder page_finder;
public int Repos_len() {return repos.Count();} ListAdp repos = ListAdp_.new_();
public Xof_repo_pair Repos_get_by_wiki(byte[] wiki) {
int len = repos.Count();
for (int i = 0; i < len; i++) {
Xof_repo_pair pair = (Xof_repo_pair)repos.FetchAt(i);
if (Bry_.Eq(wiki, pair.Wiki_key()))
return pair;
}
return null;
}
public Xof_repo_pair Repos_get_at(int i) {return (Xof_repo_pair)repos.FetchAt(i);}
public Xof_repo_pair Repos_get_by_id(int id) {
int len = repos.Count();
for (int i = 0; i < len; i++) {
Xof_repo_pair pair = (Xof_repo_pair)repos.FetchAt(i);
if (pair.Repo_id() == id) return pair;
}
return null;
}
public boolean Xfer_by_meta(Xof_xfer_itm xfer_itm, Xof_xfer_queue queue) {
byte[] ttl = xfer_itm.Lnki_ttl();
Xof_meta_itm meta_itm = xfer_itm.Meta_itm();
boolean chk_all = false;
byte[] src_wiki_key = wiki.Domain_bry();
if (meta_itm.State_new()) {
byte rslt = Xfer_by_meta__find_file(ttl, meta_itm, wiki.Domain_bry());
switch (rslt) {
case Xof_meta_itm.Tid_null: xfer_itm.Trg_repo_idx_(0); chk_all = true; break; // NOTE: src_wiki_key becomes wiki.Key_bry() for sake of simplicity
case Xof_meta_itm.Tid_main: xfer_itm.Trg_repo_idx_(Xof_meta_itm.Repo_same); break;
case Xof_meta_itm.Tid_ptr: src_wiki_key = Xfer_by_meta__find_main_ptr(meta_itm, xfer_itm); break;
case Xof_meta_itm.Tid_vrtl: src_wiki_key = Xfer_by_meta__find_main_vrtl(meta_itm, xfer_itm); break;
}
}
else {
Xof_repo_itm src_repo = meta_itm.Repo_itm(wiki);
src_wiki_key = src_repo.Wiki_key();
xfer_itm.Trg_repo_idx_(meta_itm.Vrtl_repo()); // NOTE: set trg_repo_idx b/c xfer_mgr will always set meta_itm.Vrtl_repo() with trg_repo_idx
}
if (meta_itm.Ptr_ttl_exists())
xfer_itm.Atrs_by_ttl(meta_itm.Ttl(), meta_itm.Ptr_ttl());
boolean main_exists_unknown = src_wiki_key == null; // WORKAROUND/HACK: SEE:NOTE_1:reset_main_exists
boolean rv = Xfer_by_meta__exec(chk_all, xfer_itm, meta_itm, src_wiki_key, queue, false);
if (!rv && (!chk_all && !main_exists_unknown)) { // xfer failed even with page found in wiki; try again, but chk all
rv = Xfer_by_meta__exec(true, xfer_itm, meta_itm, src_wiki_key, queue, true);
}
return rv;
}
byte[] Xfer_by_meta__find_main_ptr(Xof_meta_itm meta_itm, Xof_xfer_itm xfer_itm) {
byte[] redirect = meta_itm.Ptr_ttl(); int redirect_tries = 0;
byte[] md5 = Xof_xfer_itm_.Md5_(redirect);
while (true) {
boolean found = page_finder.Locate(tmp_rslt, repos, redirect);
if (!found) return null;
Xow_wiki trg_wiki = wiki;
int repo_idx = tmp_rslt.Repo_idx();
byte[] trg_wiki_key = Bry_.Empty;
if (repo_idx != Xof_meta_itm.Repo_unknown) {
trg_wiki_key = wiki.File_mgr().Repo_mgr().Repos_get_at(repo_idx).Wiki_key();
trg_wiki = wiki.App().Wiki_mgr().Get_by_key_or_make(trg_wiki_key);
}
Xof_meta_itm redirect_meta = trg_wiki.File_mgr().Meta_mgr().Get_itm_or_new(redirect, md5);
if (tmp_rslt.Redirect() == Xop_redirect_mgr.Redirect_null_bry) {
if (redirect_meta.State_new()) {
if (repo_idx == Xof_meta_itm.Repo_unknown) {
// meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_same);
xfer_itm.Trg_repo_idx_(Xof_meta_itm.Repo_same);
}
else {
if (!Bry_.Eq(trg_wiki_key, wiki.Domain_bry())) {
// meta_itm.Vrtl_repo_(tmp_rslt.Repo_idx());
xfer_itm.Trg_repo_idx_(tmp_rslt.Repo_idx());
}
else {
// meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_same);
xfer_itm.Trg_repo_idx_(Xof_meta_itm.Repo_same);
}
}
}
return trg_wiki_key;
}
redirect = tmp_rslt.Redirect();
if (++redirect_tries > Xop_redirect_mgr.Redirect_max_allowed) return null;
}
}
byte[] Xfer_by_meta__find_main_vrtl(Xof_meta_itm meta_itm, Xof_xfer_itm xfer_itm) {
int repo_idx = meta_itm.Vrtl_repo();
if (repo_idx == Xof_meta_itm.Repo_unknown) return null;;
Xof_repo_itm trg_repo = wiki.File_mgr().Repo_mgr().Repos_get_at(repo_idx).Trg();
xfer_itm.Trg_repo_idx_(repo_idx);
return trg_repo.Wiki_key();
}
boolean Xfer_by_meta__exec(boolean chk_all, Xof_xfer_itm xfer_itm, Xof_meta_itm meta_itm, byte[] main_wiki_key, Xof_xfer_queue queue, boolean second_chance) {
int repos_len = repos.Count();
for (int i = 0; i < repos_len; i++) { // iterate over all repo pairs
Xof_repo_pair pair = (Xof_repo_pair)repos.FetchAt(i);
Xof_repo_itm pair_src = pair.Src();
boolean main_wiki_key_is_pair_src = Bry_.Eq(main_wiki_key, pair_src.Wiki_key());
if ( (chk_all && !main_wiki_key_is_pair_src) // only do chk_all if main_wiki is not pair_src; note that chk_all will only be called in two ways (1) with main_wiki_key as null; (2) with main_key_as val
|| (!chk_all && main_wiki_key_is_pair_src)) { // pair.Src.Wiki == main.Wiki; note that there can be multiple pairs with same src; EX: have 2 pairs for commons: one for file and another for http
xfer_mgr.Atrs_by_itm(xfer_itm, pair_src, pair.Trg());
boolean make = xfer_mgr.Make_file(wiki);
if (make) {
xfer_itm.Trg_repo_(pair.Trg());
if (second_chance && xfer_itm.Meta_itm().Vrtl_repo() == 0) // second_chance and item found; change vrtl_repo from commons back to same; EX: tarball and [[Image:Rembrandt De aartsengel verlaat Tobias en zijn gezin. 1637.jpg|120px]]
xfer_itm.Meta_itm().Vrtl_repo_(Xof_meta_itm.Repo_same);
return true; // file was made; return; if not continue looking at other repos
}
}
}
return false;
}
public Xofw_file_finder_rslt Page_finder_locate(byte[] ttl_bry) {page_finder.Locate(tmp_rslt, repos, ttl_bry); return tmp_rslt;}
byte Xfer_by_meta__find_file(byte[] ttl_bry, Xof_meta_itm meta_itm, byte[] cur_wiki_key) {
byte new_tid = Byte_.MaxValue_127;
boolean found = page_finder.Locate(tmp_rslt, repos, ttl_bry);
if (found) {
if (Bry_.Eq(cur_wiki_key, tmp_rslt.Repo_wiki_key())) { // itm is in same repo as cur wiki
new_tid = Xof_meta_itm.Tid_main;
byte[] redirect = tmp_rslt.Redirect();
if (redirect != Xop_redirect_mgr.Redirect_null_bry) { // redirect found
meta_itm.Ptr_ttl_(redirect);
}
meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_same);
}
else { // itm is in diff repo
new_tid = Xof_meta_itm.Tid_vrtl;
meta_itm.Vrtl_repo_(tmp_rslt.Repo_idx());
meta_itm.Ptr_ttl_(tmp_rslt.Redirect());
}
}
else { // itm not found; has to be vrtl, but mark repo as unknown
meta_itm.Vrtl_repo_(Xof_meta_itm.Repo_unknown);
}
return new_tid;
} private Xofw_file_finder_rslt tmp_rslt = new Xofw_file_finder_rslt();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_add)) return Add_repo(m.ReadBry("src"), m.ReadBry("trg"));
else if (ctx.Match(k, Invk_clear)) repos.Clear();
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_add = "add", Invk_clear = "clear";
public Xof_repo_pair Add_repo(byte[] src_repo_key, byte[] trg_repo_key) {
Xof_meta_mgr trg_meta = wiki.File_mgr().Meta_mgr();
Xoa_repo_mgr repo_mgr = wiki.App().File_mgr().Repo_mgr();
Xof_repo_itm src_repo = repo_mgr.Get_by(src_repo_key), trg_repo = repo_mgr.Get_by(trg_repo_key);
byte[] src_wiki_key = src_repo.Wiki_key(), trg_wiki_key = trg_repo.Wiki_key();
if (!Bry_.Eq(src_wiki_key, trg_wiki_key) && !Bry_.Eq(src_wiki_key, Xow_wiki_domain_.Key_home_bry)) throw Err_mgr._.fmt_(GRP_KEY, "add_repo", "wiki keys do not match: ~{0} ~{1}", String_.new_utf8_(src_wiki_key), String_.new_utf8_(trg_wiki_key));
Xof_repo_pair pair = new Xof_repo_pair(repos.Count(), src_repo, trg_repo, trg_meta, src_wiki_key);
repos.Add(pair);
return pair;
}
public boolean Xfer_file(Xof_xfer_itm file) {
int repo_idx = file.Trg_repo_idx();
boolean wiki_is_unknown = repo_idx == Xof_meta_itm.Repo_unknown;
boolean make_pass = false;
int len = repos.Count();
if (!wiki_is_unknown) make_pass = Xfer_file_exec(file, this.Repos_get_at(repo_idx), repo_idx);
if (make_pass) return true;
for (int i = 0; i < len; i++) {
Xof_repo_pair pair = (Xof_repo_pair)repos.FetchAt(i);
if (i != repo_idx) { // try other wikis
file.Meta_itm().Orig_exists_(Xof_meta_itm.Exists_unknown); // always reset orig exists; this may have been flagged to missing above and should be cleared
make_pass = Xfer_file_exec(file, pair, i);
if (make_pass) break;
}
}
return make_pass;
}
private boolean Xfer_file_exec(Xof_xfer_itm file, Xof_repo_pair pair, int repo_idx) {
xfer_mgr.Atrs_by_itm(file, pair.Src(), pair.Trg());
Xof_meta_itm meta_itm = xfer_mgr.Meta_itm();
boolean rv = xfer_mgr.Make_file(wiki);
if (rv) {
meta_itm.Vrtl_repo_(repo_idx); // update repo_idx to whatever is found
}
return rv;
}
private static final String GRP_KEY = "Xow_repo_mgr";
}
/*
NOTE_1:reset_main_exists
this is primarily for Img_missing_wiki_1 and [[Image:Alcott-L.jpg|thumb|right|Louisa May Alcott]]
first some details:
. file pages exist in both en_wiki and in commons_wiki; w:File:Alcott-L.jpg; c:File:Alcott-L.jpg
. images are slightly different (w: is darker than c:)
. c was recently updated to redirect to File:Louisa May Alcott (1881 illustration).jpg
the actual effect:
. [[Image:Alcott-L.jpg|thumb|right|Louisa May Alcott]] in en.wikipedia should pull the w: one (not the c:) one
. this behavior seems contrary to all other wiki behavior where c: is given primacy over w:
.. EX: [[File:Tanks of WWI.ogg|thumb|thumbtime=12|alt=Primitive]] exists in both en_wiki and in commons, but the file only exists in commons
. moreover this page has a special note about the image deliberately remainining in en_wiki
the workaround/hack (described via intended sequence):
1: commons is defined as first repo_pair
2: image found in commons page (note that en_wiki is not checked for PERF reasons)
3: image is searched for in commons, but not found; note that both thumb and orig are missing
4: image will be searched for in en_wiki and found
note that (4) however reuses the same meta which is marked as "not found" from the commons attempt
. item will then have orig marked falsely as not-found
one approach would be to create a new meta and send that into the chk_all function. this turned out to be problematic
so, the workaround:
if going into chk_all
...and orig was previous unknown
...but is now marked no
then reset to unknown to give it a "clean" slate for the chk all
in theory, the above statement seems fine, but it does seem hackish...
*/