1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00

File: Handle long directories on Windows systems

This commit is contained in:
gnosygnu 2017-03-15 23:28:45 -04:00
parent 19b2d6226c
commit 2270a35c83
3 changed files with 85 additions and 8 deletions

View File

@ -26,13 +26,15 @@ public class Xof_itm_ttl_ {
}
public static byte[] Shorten(Bry_bfr bfr, byte[] ttl, int ttl_max, byte[] md5, byte[] ext_bry) {
byte[] rv = ttl;
int exceed_len = rv.length - ttl_max;
int exceed_len = rv.length - ttl_max; // calc exceed_len; EX: 21 = 201 - 180
if (exceed_len > 0) {
bfr.Add_mid(rv, 0, ttl_max - 33); // add truncated title; 33=_.length + md5.length
bfr.Add_byte(Byte_ascii.Underline); // add underline; EX: "_"
bfr.Add(md5); // add md5; EX: "abcdefghijklmnopqrstuvwxyz0123456"
bfr.Add_byte(Byte_ascii.Dot); // add dot; EX: "."
bfr.Add(ext_bry); // add ext; EX: ".png"
if (ttl_max > 33) {
bfr.Add_mid(rv, 0, ttl_max - 33); // add truncated title; 33=_.length + md5.length; EX: 180 - 33
bfr.Add_byte(Byte_ascii.Underline); // add underline; EX: "_"
}
bfr.Add(md5); // add md5; EX: "abcdefghijklmnopqrstuvwxyz0123456"
bfr.Add_byte(Byte_ascii.Dot); // add dot; EX: "."
bfr.Add(ext_bry); // add ext; EX: ".png"
rv = bfr.To_bry_and_clear();
}
return rv;

View File

@ -40,6 +40,7 @@ public class Xof_repo_itm implements Gfo_invk {
public byte[][] Mode_names() {return mode_names;} private byte[][] mode_names = new byte[][] {Xof_img_mode_.Names_ary[0], Xof_img_mode_.Names_ary[1]};
public Xof_rule_grp Ext_rules() {return ext_rules;} private Xof_rule_grp ext_rules;
public boolean Primary() {return primary;} private boolean primary;
public void Url_max_len_(int v) {url_max_len = v;} private int url_max_len = 250;
public Xof_repo_itm Fsys_is_wnt_(boolean v) {fsys_is_wnt = v; return this;}
public Xof_repo_itm Shorten_ttl_(boolean v) {shorten_ttl = v; return this;}
@ -82,7 +83,26 @@ public class Xof_repo_itm implements Gfo_invk {
}
public byte[] Gen_name_trg(Bry_bfr tmp_bfr, byte[] bry, byte[] md5, Xof_ext ext) {
byte[] rv = Gen_name_src(tmp_bfr, bry);
return shorten_ttl ? Xof_itm_ttl_.Shorten(tmp_bfr, rv, Ttl__max_len, md5, ext.Ext()) : rv;
if (shorten_ttl) {
int max = url_max_len;
if (fsys_is_wnt) {
max = url_max_len // 250 is approximate max of windows path
- root_bry.length // EX: "C:\xowa\"
- 5 // EX: "file\"
- 6 // EX: "thumb\"
- dir_depth * 2 // EX: "0\1\2\3\"; *2 is for "\"
- 17 // 17 is length of "\1234px@1234-1234"
- ext.Ext().length + 1 // EX: ".png"; +1 is for "."
;
}
else {
max = 180; // legacy val of max title; can probably be higher
}
return Xof_itm_ttl_.Shorten(tmp_bfr, rv, max, md5, ext.Ext());
}
else {
return rv;
}
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_owner)) throw Err_.new_unimplemented_w_msg("deprecated repo_itm.owner");
@ -96,5 +116,4 @@ public class Xof_repo_itm implements Gfo_invk {
return this;
}
private static final String Invk_owner = "owner", Invk_fsys_ = "fsys_", Invk_ext_rules_ = "ext_rules_", Invk_primary_ = "primary_", Invk_wmf_api_ = "wmf_api_", Invk_tarball_ = "tarball_", Invk_tid_ = "tid_";
public static final int Ttl__max_len = 180;
}

View File

@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.files.repos; import gplx.*; import gplx.xowa.*; import gplx.xowa.files.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.core.envs.*;
import gplx.xowa.apps.fsys.*;
import gplx.xowa.files.exts.*;
public class Xof_repo_itm__tst {
private final Xof_repo_itm__fxt fxt = new Xof_repo_itm__fxt();
@Test public void Gen_name_trg__long() {
// make a windows repo with a long directory name
Xof_repo_itm repo = fxt.Make__repo(Op_sys.Wnt.Os_name(), "C:\\xowa0123456789", "commons.wikimedia.org");
// mark it as wnt repo and reduce max ttl_len from 160 to 99 for shorter test vars
repo.Fsys_is_wnt_(true).Url_max_len_(99);
// short: full name
fxt.Test__gen_name_trg(repo, "A.png", "A.png");
// long: truncated_ttl + md5
fxt.Test__gen_name_trg(repo, "0123456789012345678901234567890123456789.png", "0123456789_965d037bf686058361510201be299ed4.png");
// extremely long; md5 only
repo.Root_str_("C:\\xowa012345678901234567890123456789");
fxt.Test__gen_name_trg(repo, "0123456789012345678901234567890123456789.png", "965d037bf686058361510201be299ed4.png");
}
}
class Xof_repo_itm__fxt {
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
public Xof_repo_itm Make__repo(String plat_name, String root_dir_str, String wiki_domain) {
String key = "test_repo";
Io_url root_dir = Io_url_.new_dir_(root_dir_str);
Xoa_fsys_mgr fsys_mgr = new Xoa_fsys_mgr(plat_name, root_dir, root_dir.GenSubDir("wiki"), root_dir.GenSubDir("file"), root_dir.GenSubDir("css"), root_dir.GenSubDir("html"));
Xof_repo_itm repo = new Xof_repo_itm(Bry_.new_u8(key), fsys_mgr, new Xof_rule_mgr(), Bry_.new_u8(wiki_domain));
repo.Root_str_(root_dir.Raw());
return repo;
}
public void Test__gen_name_trg(Xof_repo_itm repo, String ttl_str, String expd) {
byte[] ttl_bry = Bry_.new_u8(ttl_str);
byte[] md5 = Xof_file_wkr_.Md5(ttl_bry);
Gftest.Eq__str(expd, repo.Gen_name_trg(tmp_bfr, ttl_bry, md5, Xof_ext_.new_by_ttl_(ttl_bry)));
}
}