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
2015-07-12 21:10:02 -04:00
commit 794b5a232f
3099 changed files with 238212 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
import gplx.core.primitives.*; import gplx.gfui.*;
public class Xoc_layout_mgr implements GfoInvkAble {
public Xoc_layout_mgr(Xoae_app app) {
this.app = app;
Ctor_by_os();
} private Xoae_app app;
public byte Html_box_adj_type() {return html_box_adj_type;} private byte html_box_adj_type;
public RectAdp Html_box_adj_rect() {return html_box_adj_rect;} private RectAdp html_box_adj_rect = RectAdp_.Zero;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_html_box_adj_type)) return html_box_adj_type_enm.Get_str(html_box_adj_type);
else if (ctx.Match(k, Invk_html_box_adj_type_)) {html_box_adj_type = Byte_.parse_(m.ReadStr("v")); this.Refresh_window();}
else if (ctx.Match(k, Invk_html_box_adj_type_list)) return html_box_adj_type_enm.Get_kv_ary();
else if (ctx.Match(k, Invk_html_box_adj_rect)) return html_box_adj_rect.Xto_str();
else if (ctx.Match(k, Invk_html_box_adj_rect_)) {html_box_adj_rect = gplx.gfui.RectAdp_.parse_ws_(m.ReadStr("v")); this.Refresh_window();}
return this;
}
private void Refresh_window() {
app.Gui_mgr().Browser_win().Refresh_win_size();
}
public static final String
Invk_html_box_adj_type = "html_box_adj_type", Invk_html_box_adj_type_ = "html_box_adj_type_", Invk_html_box_adj_type_list = "html_box_adj_type_list"
, Invk_html_box_adj_rect = "html_box_adj_rect", Invk_html_box_adj_rect_ = "html_box_adj_rect_";
public static final byte Html_box_adj_type_none_byte = 0, Html_box_adj_type_rel_byte = 1, Html_box_adj_type_abs_byte = 2;
private static final Enm_mgr html_box_adj_type_enm = new Enm_mgr().Add(Html_box_adj_type_none_byte, "none").Add(Html_box_adj_type_rel_byte, "relative").Add(Html_box_adj_type_abs_byte, "absolute");
private void Ctor_by_os() {
if (Op_sys.Cur().Tid_is_osx()) {
html_box_adj_type = Html_box_adj_type_rel_byte;
html_box_adj_rect = RectAdp_.new_(0, 0, 5, 30);
}
}
}
class Enm_mgr {
private Ordered_hash str_hash = Ordered_hash_.new_(); private Hash_adp val_hash = Hash_adp_.new_();
private Int_obj_ref tmp_val_ref = Int_obj_ref.zero_();
public Enm_mgr Add(byte val, String str) {
Int_obj_ref val_ref = Int_obj_ref.new_(val);
KeyVal kv = KeyVal_.new_(str, val_ref);
str_hash.Add(str, kv);
val_hash.Add(val_ref, kv);
return this;
}
public String Get_str(byte val) {
Object o = val_hash.Get_by(tmp_val_ref.Val_(val));
if (o == null) return null;
return ((KeyVal)o).Val_to_str_or_null();
}
public KeyVal[] Get_kv_ary() {
int len = val_hash.Count();
KeyVal[] rv = new KeyVal[len];
for (int i = 0; i < len; i++) {
KeyVal trg = (KeyVal)str_hash.Get_at(i);
rv[i] = KeyVal_.new_(trg.Val_to_str_or_null(), trg.Key());
}
return rv;
}
}

View File

@@ -0,0 +1,45 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
public class Xou_cfg implements GfoInvkAble {
public Xou_cfg(Xoue_user user) {
this.user = user;
pages_mgr = new Xouc_pages_mgr(this); startup_mgr = new Xouc_startup_mgr(this); setup_mgr = new Xouc_setup_mgr(user);
layout_mgr = new Xoc_layout_mgr(user.Appe());
security_mgr = new Xou_security_mgr(user.Appe());
}
public Xoue_user User() {return user;} private Xoue_user user;
public Xouc_pages_mgr Pages_mgr() {return pages_mgr;} private Xouc_pages_mgr pages_mgr;
public Xouc_startup_mgr Startup_mgr() {return startup_mgr;} private Xouc_startup_mgr startup_mgr;
public Xouc_setup_mgr Setup_mgr() {return setup_mgr;} private Xouc_setup_mgr setup_mgr;
public Xoc_layout_mgr Layout_mgr() {return layout_mgr;} private Xoc_layout_mgr layout_mgr;
public Xou_security_mgr Security_mgr() {return security_mgr;} private Xou_security_mgr security_mgr;
public Xou_log_mgr Log_mgr() {return log_mgr;} private final Xou_log_mgr log_mgr = new Xou_log_mgr();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_pages)) return pages_mgr;
else if (ctx.Match(k, Invk_startup)) return startup_mgr;
else if (ctx.Match(k, Invk_setup)) return setup_mgr;
else if (ctx.Match(k, Invk_layout)) return layout_mgr;
else if (ctx.Match(k, Invk_security)) return security_mgr;
else if (ctx.Match(k, Invk_log)) return log_mgr;
return this;
}
public static final String
Invk_pages = "pages", Invk_startup = "startup", Invk_setup = "setup", Invk_layout = "layout", Invk_security = "security", Invk_log = "log"
;
}

View File

@@ -0,0 +1,48 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
import gplx.xowa.apps.*; import gplx.xowa.wikis.*;
public class Xou_fsys_mgr implements GfoInvkAble {
private Io_url app_root_dir; private Io_url wiki_root_dir; private Io_url cur_root;
public Xou_fsys_mgr(Xoae_app app, Xoue_user usr, Io_url user_dir) {
this.cur_root = user_dir;
app_root_dir = cur_root.GenSubDir("app");
app_temp_dir = app_root_dir.GenSubDir("tmp");
app_temp_html_dir = app_temp_dir.GenSubDir("html");
app_data_history_fil = app_root_dir.GenSubFil_nest("data", "history", "page_history.csv");
wiki_root_dir = cur_root.GenSubDir("wiki");
home_wiki_dir = wiki_root_dir.GenSubDir_nest(Xow_domain_type_.Key_str_home);
}
public Io_url Root_dir() {return cur_root;}
public Io_url Wiki_root_dir() {return wiki_root_dir;}
public Io_url Wiki_html_dir(String wiki) {return wiki_root_dir.GenSubDir_nest(wiki, "html");}
public Io_url App_data_history_fil() {return app_data_history_fil;} private Io_url app_data_history_fil;
public Io_url App_temp_dir() {return app_temp_dir;} private Io_url app_temp_dir;
public Io_url App_temp_html_dir() {return app_temp_html_dir;} private Io_url app_temp_html_dir;
public Io_url App_img_dir() {return app_root_dir.GenSubDir_nest("img");}
public Io_url App_data_dir() {return app_root_dir.GenSubDir_nest("data");}
public Io_url App_data_cfg_dir() {return app_root_dir.GenSubDir_nest("data", "cfg");}
public Io_url App_data_cfg_user_fil() {return app_root_dir.GenSubFil_nest("data", "cfg", Xoa_gfs_mgr.Cfg_user_file);}
public Io_url App_data_cfg_custom_fil() {return app_root_dir.GenSubFil_nest("data", "cfg", Xoa_gfs_mgr.Cfg_user_custom_file);}
public Io_url Home_wiki_dir() {return home_wiki_dir;} private Io_url home_wiki_dir;
public static final String Name_user_system_cfg = "user_system_cfg.gfs";
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_root_dir)) return cur_root;
else return GfoInvkAble_.Rv_unhandled;
} private static final String Invk_root_dir = "root_dir";
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users; import gplx.*; import gplx.xowa.*;
public class Xou_log_mgr implements GfoInvkAble {
public boolean Log_redlinks() {return log_redlinks;} private boolean log_redlinks;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_log_redlinks)) return Yn.Xto_str(log_redlinks);
else if (ctx.Match(k, Invk_log_redlinks_)) log_redlinks = m.ReadYn("v");
return this;
}
public static final String
Invk_log_redlinks = "log_redlinks", Invk_log_redlinks_ = "log_redlinks_"
;
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users; import gplx.*; import gplx.xowa.*;
public class Xou_security_mgr implements GfoInvkAble {
public Xou_security_mgr(Xoae_app app) {this.app = app;} private Xoae_app app;
public boolean Web_access_enabled() {return app.Api_root().Net().Enabled();}
public void Web_access_enabled_(boolean v) {app.Api_root().Net().Enabled_(v);}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_web_access_enabled)) return Yn.Xto_str(this.Web_access_enabled());
else if (ctx.Match(k, Invk_web_access_enabled_)) Web_access_enabled_(m.ReadYn("v"));
return this;
}
public static final String
Invk_web_access_enabled = "web_access_enabled", Invk_web_access_enabled_ = "web_access_enabled_";
}

View File

@@ -0,0 +1,27 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
public class Xou_session implements GfoInvkAble {
public Xou_session(Xoue_user user) {this.user = user; window_mgr = new Xous_window_mgr(user);}
public Xoue_user User() {return user;} private Xoue_user user;
public Xous_window_mgr Window_mgr() {return window_mgr;} private Xous_window_mgr window_mgr;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_window)) return window_mgr;
return this;
} public static final String Invk_window = "window";
}

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users; import gplx.*; import gplx.xowa.*;
import gplx.xowa.users.data.*;
import gplx.xowa.files.caches.*;
public interface Xou_user {
String Key();
int Gender();
Xou_db_mgr User_db_mgr();
Xow_wiki Wikii();
}

View File

@@ -0,0 +1,66 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
import gplx.xowa.langs.cases.*; import gplx.xowa.wikis.*; import gplx.xowa.xtns.scribunto.*;
import gplx.xowa.wikis.domains.*;
class Xou_user_ {
public static Xowe_wiki new_or_create_(Xoue_user user, Xoae_app app) {
Io_url wiki_dir = user.Fsys_mgr().Home_wiki_dir().GenSubDir_nest("wiki", Xow_domain_type_.Key_str_home);
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(app.Lang_mgr().Default_lang());
lang.Init_by_load(); // NOTE: lang.Load() must occur before Xowe_wiki.new() b/c wiki will create parsers based on lang
Xowe_wiki rv = new Xowe_wiki(app, lang, ns_home_(lang.Case_mgr()), Xow_domain_uid_.To_domain(Xow_domain_uid_.Tid_xowa), wiki_dir);
app.Wiki_mgr().Add(rv);
rv.Sys_cfg().Xowa_cmd_enabled_(true);
rv.Sys_cfg().Xowa_proto_enabled_(true);
return rv;
}
public static void User_system_cfg_make(Gfo_usr_dlg usr_dlg, Io_url cfg_fil) {
usr_dlg.Log_many(GRP_KEY, "user_system_cfg.create", "creating user_system_cfg.gfs: ~{0}", cfg_fil.Raw());
Io_mgr.I.SaveFilStr(cfg_fil, User_system_cfg_text);
}
public static void Bookmarks_make(Xoae_app app, Xowe_wiki home_wiki) {
app.Usr_dlg().Log_many(GRP_KEY, "bookmarks.create", "creating bookmarks page");
home_wiki.Db_mgr().Save_mgr().Data_create(Xoa_ttl.parse_(home_wiki, Bry_.new_a7("Data:Bookmarks")), Bry_.new_a7(Bookmarks_text));
}
public static final String User_system_cfg_text = String_.Concat_lines_nl
( "app.scripts.txns.get('user.prefs.general').version_('" + Xoa_app_.Version + "').bgn();"
, "app.files.download.enabled_('y');" // default to true; DATE:2015-01-05
, "app.files.math.enabled_('y');"
, "app.files.math.renderer_('mathjax');"
, "app.scripts.txns.get('user.prefs.general').end();\n"
);
public static final String Bookmarks_text = String_.Concat_lines_nl
( "Bookmarks are added automatically to the bottom of the page. All other text is not modified."
, ""
, "Please delete bookmarks by editing this page."
);
private static Xow_ns_mgr ns_home_(Xol_case_mgr case_mgr) {
Xow_ns_mgr rv = new Xow_ns_mgr(case_mgr);
rv = rv.Add_new(-2, "Media").Add_new(-1, "Special").Add_new(0, "").Add_new(1, "Talk").Add_new(2, "User").Add_new(3, "User talk").Add_new(4, "Wikipedia").Add_new(5, "Wikipedia talk")
.Add_new(6, "File").Add_new(7, "File talk").Add_new(8, "MediaWiki").Add_new(9, "MediaWiki talk").Add_new(10, "Template").Add_new(11, "Template talk")
.Add_new(12, "Help").Add_new(13, "Help talk").Add_new(14, "Category").Add_new(15, "Category talk").Add_new(100, "Portal").Add_new(101, "Portal talk")
.Add_new(gplx.xowa.xtns.wdatas.Wdata_wiki_mgr.Ns_property, gplx.xowa.xtns.wdatas.Wdata_wiki_mgr.Ns_property_name)
.Add_new(730, "Data").Add_new(731, "Data talk")
.Add_new(Scrib_xtn_mgr.Ns_id_module, Scrib_xtn_mgr.Ns_name_module).Add_new(Scrib_xtn_mgr.Ns_id_module_talk, Scrib_xtn_mgr.Ns_name_module_talk)
.Add_defaults()
;
rv.Init();
return rv;
}
static final String GRP_KEY = "xowa.user_";
}

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.users; import gplx.*; import gplx.xowa.*;
public class Xou_user_mgr implements GfoInvkAble {
public Xou_user_mgr(Xoae_app app, Xoue_user user) {this.app = app; this.Add(user);} private Xoae_app app;
public void Add(Xoue_user itm) {regy.Add(itm.Key(), itm);}
Xoue_user GetByKey(String key) {return (Xoue_user)regy.Get_by(key);}
Ordered_hash regy = Ordered_hash_.new_();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_get)) {
String user_key = m.ReadStr("key");
Xoue_user user = GetByKey(user_key);
if (user == null) {
user = new Xoue_user(app, app.Fsys_mgr().Root_dir().GenSubDir_nest("user", user_key));
this.Add(user);
}
return user;
}
else return GfoInvkAble_.Rv_unhandled;
// return this;
} private static final String Invk_get = "get";
}

View File

@@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users; import gplx.*; import gplx.xowa.*;
import org.junit.*; import gplx.xowa.wikis.xwikis.*;
public class Xou_user_tst {
private Xou_user_fxt fxt = new Xou_user_fxt();
@Test public void Run() {
Io_url user_system_cfg_url = Io_url_.mem_fil_("mem/xowa/user/test_user/app/data/cfg/user_system_cfg.gfs");
fxt.Test_fil(user_system_cfg_url, ""); // check that it is blank
fxt.App().Init_by_app(); // run Init_by_app
fxt.Test_fil(user_system_cfg_url, Xou_user_.User_system_cfg_text); // check that it is created
Io_mgr.I.SaveFilStr(user_system_cfg_url, ""); // simulate edit by blanking out file
fxt.App().Init_by_app(); // run Init_by_app again
fxt.Test_fil(user_system_cfg_url, ""); // check that it is still blank
}
@Test public void Available_from_fsys() {
Io_mgr.I.CreateDir(fxt.App().Fsys_mgr().Wiki_dir().GenSubDir("en.wikipedia.org"));
fxt.App().Usere().Available_from_fsys();
fxt.Test_xwikis
( fxt.Make_xwiki(Bool_.N, "home")
, fxt.Make_xwiki(Bool_.Y, "en.wikipedia.org") // available_from_fsys should mark as offline=y
);
}
}
class Xou_user_fxt {
public Xoae_app App() {return app;} private Xoae_app app = Xoa_app_fxt.app_();
public String Make_xwiki(boolean offline, String name) {return String_.Concat_with_str("|", Yn.Xto_str(offline), name);}
public void Test_fil(Io_url url, String expd) {
Tfds.Eq_str_lines(expd, Io_mgr.I.LoadFilStr(url));
}
public void Test_xwikis(String... expd) {
Xow_xwiki_mgr xwiki_mgr = app.Usere().Wiki().Xwiki_mgr();
int len = xwiki_mgr.Len();
String[] actl = new String[len];
for (int i = 0; i < len; ++i) {
Xow_xwiki_itm xwiki_itm = xwiki_mgr.Get_at(i);
actl[i] = Make_xwiki(xwiki_itm.Offline(), String_.new_u8(xwiki_itm.Domain_name()));
}
Tfds.Eq_ary_str(expd, actl);
}
}

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.users; import gplx.*; import gplx.xowa.*;
public class Xouc_pages_mgr implements GfoInvkAble {
public Xouc_pages_mgr(Xou_cfg config) {}
public String Home() {return home;} public Xouc_pages_mgr Home_(String v) {home = v; return this;} private String home = Page_xowa;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_home)) return home;
else if (ctx.Match(k, Invk_home_)) home = m.ReadStr("v");
return this;
} public static final String Invk_home = "home", Invk_home_ = "home_";
public static final String Page_xowa = "home/wiki/Main_Page";
}

View File

@@ -0,0 +1,60 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
public class Xouc_setup_mgr implements GfoInvkAble {
public Xouc_setup_mgr(Xoue_user user) {this.user = user;}
public Xoue_user User() {return user;} private Xoue_user user;
private String setup_completed = "";
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_setup_completed)) return setup_completed;
else if (ctx.Match(k, Invk_setup_completed_)) setup_completed = m.ReadStr("v");
return this;
} private static final String Invk_setup_completed = "setup_completed", Invk_setup_completed_ = "setup_completed_";
public void Setup_run_check(Xoae_app app) {
byte op_sys_tid = Op_sys.Cur().Tid();
switch (op_sys_tid) {
case Op_sys.Tid_drd:
case Op_sys.Tid_wnt: return;
}
String op_sys_name = Xoa_app_.Op_sys;
String[] plats_ary = String_.Split(setup_completed, ";");
int plats_ary_len = plats_ary.length;
for (int i = 0; i < plats_ary_len; i++) {
if (String_.Eq(plats_ary[i], op_sys_name)) return;
}
// Io_url lua_url = app.Fsys_mgr().Bin_plat_dir().GenSubFil_nest("lua", "lua");
// Io_url lua_install_url = app.Fsys_mgr().Bin_plat_dir().GenSubFil_nest("lua", "lua_install");
// Run(String_.Format("mv -f \"{0}\" \"{1}\"", lua_install_url.Raw(), lua_url.Raw()));
// Run(String_.Format("chmod 774 \"{0}\"", lua_url.Raw()));
Io_url setup_url = app.Fsys_mgr().Root_dir().GenSubFil_ary("setup_", op_sys_name, ".sh");
Run("sh", String_.Format("\"{0}\"", setup_url.Raw()));
setup_completed += op_sys_name + ";";
app.Cfg_mgr().Set_by_all("app.user.cfg.setup.setup_completed", setup_completed);
app.Cfg_mgr().Db_save_txt();
}
private boolean Run(String exe, String arg) {
boolean pass = false; String fail = "";
try {pass = new ProcessAdp().Exe_url_(Io_url_.new_fil_(exe)).Args_str_(arg).Run_wait_sync().Exit_code_pass();}
catch (Exception e) {
fail = Err_.Message_gplx_brief(e);
}
if (!pass)
user.Appe().Usr_dlg().Prog_many("xowa.setup_mgr", "run.fail", "process exec failed: ~{0} ~{1} ~{2}", exe, arg, fail);
return pass;
}
}

View File

@@ -0,0 +1,66 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
public class Xouc_startup_mgr implements GfoInvkAble {
public Xouc_startup_mgr(Xou_cfg config) {this.config = config; window_mgr = new Xouc_window_mgr(config.User());} private Xou_cfg config;
public Xouc_window_mgr Window_mgr() {return window_mgr;} private Xouc_window_mgr window_mgr;
public String Page() {return page;} public Xouc_startup_mgr Page_(String v) {page = v; return this;} private String page = "xowa";
public String Page_url() {
byte v = Page_parse(page);
switch (v) {
case Page_home: return config.Pages_mgr().Home();
case Page_last: return String_.new_u8(config.User().Appe().Gui_mgr().Browser_win().Active_page().Ttl().Raw());
case Page_xowa: return Xouc_pages_mgr.Page_xowa;
default: throw Exc_.new_unhandled(page);
}
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_page)) return page;
else if (ctx.Match(k, Invk_page_)) page = m.ReadStr("v");
else if (ctx.Match(k, Invk_custom_config)) return Custom_config();
else if (ctx.Match(k, Invk_custom_config_)) Custom_config_(m.ReadStr("v"));
else if (ctx.Match(k, Invk_window)) return window_mgr;
return this;
}
public static final String Invk_window = "window", Invk_page = "page", Invk_page_ = "page_", Invk_custom_config = "custom_config", Invk_custom_config_ = "custom_config_";
private byte Page_parse(String s) {
if (String_.Eq(s, "home")) return Page_home;
else if (String_.Eq(s, "last")) return Page_last;
else if (String_.Eq(s, "xowa")) return Page_xowa;
else return Page_xowa;
}
private String Custom_config() {
if (custom_config == null) { // NOTE: LoadFilStr never returns null, so this will only execute once
Io_url custom_config_url = config.User().Fsys_mgr().App_data_cfg_custom_fil();
custom_config = Io_mgr.I.LoadFilStr_args(custom_config_url).MissingIgnored_().Exec();
}
return custom_config;
} private String custom_config;
private void Custom_config_(String v) {
Xoae_app app = config.User().Appe();
Object rslt = app.Gfs_mgr().Run_str(v);
if (rslt == GfoInvkAble_.Rv_error) {
app.Usr_dlg().Warn_many("", "", "custom script failed: ~{0}", v);
return;
}
custom_config = v;
// Io_url custom_config_url = config.User().Fsys_mgr().App_data_cfg_custom_fil(); // DELETE: no longer sync user_cfg to custom.gfs; already saved in user.gfs; DATE:2014-05-30
// Io_mgr.I.SaveFilStr(custom_config_url, v);
}
public static final byte Page_home = 0, Page_last = 1, Page_xowa = 2;
}

View File

@@ -0,0 +1,103 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
import gplx.gfui.*; import gplx.xowa.gui.views.*;
public class Xouc_window_mgr implements GfoInvkAble {
public Xouc_window_mgr(Xoue_user user) {this.user = user;} private Xoue_user user;
public byte Mode_tid() {return mode_tid;} private byte mode_tid = Mode_tid_previous;
public String Mode_str() {return mode_str;} private String mode_str = "previous";
public Rect_ref Rect() {return rect;} Rect_ref rect = new Rect_ref(0, 0, 800, 640);
public boolean Safe_mode() {return safe_mode;} private boolean safe_mode = true;
public Rect_ref Previous_adj() {return previous_adj;} Rect_ref previous_adj = new Rect_ref(0, 0, 0, 0);
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_mode)) return mode_str;
else if (ctx.Match(k, Invk_mode_)) {mode_str = m.ReadStr("v"); mode_tid = Xto_mode_tid(mode_str);}
else if (ctx.Match(k, Invk_mode_list)) return Options_mode_list;
else if (ctx.Match(k, Invk_rect)) return rect;
else if (ctx.Match(k, Invk_rect_)) rect = Rect_ref.parse_(m.ReadStr("v"));
else if (ctx.Match(k, Invk_safe_mode)) return Yn.Xto_str(safe_mode);
else if (ctx.Match(k, Invk_safe_mode_)) safe_mode = m.ReadYn("v");
else if (ctx.Match(k, Invk_previous_adj)) return previous_adj;
else if (ctx.Match(k, Invk_previous_adj_)) previous_adj = Rect_ref.parse_(m.ReadStr("v"));
return this;
}
public static final String Invk_mode = "mode", Invk_mode_ = "mode_", Invk_mode_list = "mode_list"
, Invk_rect = "rect", Invk_rect_ = "rect_", Invk_safe_mode = "safe_mode", Invk_safe_mode_ = "safe_mode_", Invk_previous_adj = "previous_adj", Invk_previous_adj_ = "previous_adj_";
private static KeyVal[] Options_mode_list = KeyVal_.Ary(KeyVal_.new_("previous"), KeyVal_.new_("maximized"), KeyVal_.new_("absolute"), KeyVal_.new_("relative"), KeyVal_.new_("default"));
public void Init_window(GfuiWin win) {
boolean init_is_maximized = false;
switch (mode_tid) {
case Mode_tid_previous:
Xous_window_mgr session_window = user.Session_mgr().Window_mgr();
if (session_window.Maximized()) {
win.Maximized_(true);
init_is_maximized = true;
}
else
win.Rect_set(session_window.Rect().XtoRectAdp_add(previous_adj));
break;
case Mode_tid_absolute: win.Rect_set(rect.XtoRectAdp()); break;
case Mode_tid_maximized: win.Maximized_(true); init_is_maximized = true; break;
case Mode_tid_default: break; // noop
case Mode_tid_relative:
SizeAdp screen_maximized = Screen_maximized_calc();
Rect_ref win_rect = new Rect_ref(0, 0, screen_maximized.Width(), screen_maximized.Height());
win.Rect_set(win_rect.XtoRectAdp_add(rect));
break;
}
if (safe_mode && !init_is_maximized) {
RectAdp rect = win.Rect();
boolean force = false; int x = rect.X(), y = rect.Y(), w = rect.Width(), h = rect.Height();
SizeAdp screen_size = Screen_maximized_calc();
int max_w = screen_size.Width(), max_h = screen_size.Height();
if (x < -Safe_mode_buffer || x > max_w + Safe_mode_buffer) {force = true; x = 0;}
if (y < -Safe_mode_buffer || y > max_h + Safe_mode_buffer) {force = true; y = 0;}
if (w < Safe_mode_buffer || x + w > max_w + Safe_mode_buffer) {force = true; w = max_w - x;}
if (h < Safe_mode_buffer || y + h > max_h + Safe_mode_buffer) {force = true; h = max_h - y;}
if (force)
win.Rect_set(RectAdp_.new_(x, y, w, h));
}
} private static final int Safe_mode_buffer = 20; // allow minor negative positioning (x=-5), off-screen positioning (w=1605)
public static SizeAdp Screen_maximized_calc() {
Op_sys os = Op_sys.Cur();
SizeAdp screen = ScreenAdp_.screen_(0).Size();
int w = screen.Width();
int h = screen.Height() - 30; // -20=application menu bar; -10 for start bar padding
switch (os.Tid()) {
case Op_sys.Tid_wnt:
switch (os.Sub_tid()) {
case Op_sys.Sub_tid_win_xp: h += -4; break; // NOOP; will keep values as above
default: break; // for all else, use Windows 7 border (which is thicker); note that Windows 8 is being detected as "Windows NT (unknown)", so need to use default; this may not work with Windows 2000
}
break;
default:
h += -4; // default adjustments since version 0.0.0.0; seems to work on XP and LNX
break;
}
return SizeAdp_.new_(w, h);
}
private static byte Xto_mode_tid(String s) {
if (String_.Eq(s, "previous")) return Mode_tid_previous;
else if (String_.Eq(s, "maximized")) return Mode_tid_maximized;
else if (String_.Eq(s, "absolute")) return Mode_tid_absolute;
else if (String_.Eq(s, "relative")) return Mode_tid_relative;
else if (String_.Eq(s, "default")) return Mode_tid_default;
else return Mode_tid_previous;
}
public static final byte Mode_tid_previous = 0, Mode_tid_maximized = 1, Mode_tid_absolute = 2, Mode_tid_relative = 3, Mode_tid_default = 4;
}

View File

@@ -0,0 +1,133 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
import gplx.dbs.*;
import gplx.xowa.wikis.*; import gplx.xowa.wikis.xwikis.*; import gplx.xowa.users.history.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.users.data.*;
import gplx.xowa.files.*; import gplx.xowa.files.caches.*;
import gplx.xowa.langs.genders.*;
public class Xoue_user implements Xou_user, GfoEvMgrOwner, GfoInvkAble {
public Xoue_user(Xoae_app app, Io_url user_dir) {
this.app = app; this.key = user_dir.NameOnly();
this.ev_mgr = GfoEvMgr.new_(this);
this.fsys_mgr = new Xou_fsys_mgr(app, this, user_dir);
this.user_db_mgr = new Xou_db_mgr(app);
this.history_mgr = new Xou_history_mgr(fsys_mgr.App_data_history_fil());
this.prefs_mgr = new gplx.xowa.users.prefs.Prefs_mgr(app);
this.cfg_mgr = new Xou_cfg(this);
this.session_mgr = new Xou_session(this);
}
public GfoEvMgr EvMgr() {return ev_mgr;} private final GfoEvMgr ev_mgr;
public String Key() {return key;} private String key;
public Xou_db_mgr User_db_mgr() {return user_db_mgr;} private final Xou_db_mgr user_db_mgr;
public Xow_wiki Wikii() {return wiki;}
public int Gender() {return Xol_gender_.Tid_unknown;}
public Xoae_app Appe() {return app;} private final Xoae_app app;
public Xol_lang Lang() {if (lang == null) {lang = app.Lang_mgr().Get_by_key_or_new(app.Sys_cfg().Lang()); lang.Init_by_load();} return lang;} private Xol_lang lang;
public void Lang_(Xol_lang v) {
lang = v;
this.Msg_mgr().Lang_(v);
wiki.Msg_mgr().Clear(); // clear home wiki msgs whenever lang changes; else messages cached from old lang will not be replaced; EX:Read/Edit; DATE:2014-05-26
GfoEvMgr_.PubVal(this, Evt_lang_changed, lang);
}
public Xou_fsys_mgr Fsys_mgr() {return fsys_mgr;} private Xou_fsys_mgr fsys_mgr;
public Xowe_wiki Wiki() {if (wiki == null) wiki = Xou_user_.new_or_create_(this, app); return wiki;} private Xowe_wiki wiki;
public Xou_history_mgr History_mgr() {return history_mgr;} private Xou_history_mgr history_mgr;
public Xou_cfg Cfg_mgr() {return cfg_mgr;} private Xou_cfg cfg_mgr;
public Xou_session Session_mgr() {return session_mgr;} private Xou_session session_mgr;
public gplx.xowa.users.prefs.Prefs_mgr Prefs_mgr() {return prefs_mgr;} gplx.xowa.users.prefs.Prefs_mgr prefs_mgr;
public Xow_msg_mgr Msg_mgr() {
if (msg_mgr == null)
msg_mgr = new Xow_msg_mgr(this.Wiki(), this.Lang()); // NOTE: must call this.Lang() not this.lang, else nullRef exception when using "app.shell.fetch_page"; DATE:2013-04-12
return msg_mgr;
} private Xow_msg_mgr msg_mgr;
public void Init_by_app(Xoae_app app) {
Io_url user_system_cfg = fsys_mgr.App_data_cfg_dir().GenSubFil(Xou_fsys_mgr.Name_user_system_cfg);
if (!Io_mgr.I.ExistsFil(user_system_cfg)) Xou_user_.User_system_cfg_make(app.Usr_dlg(), user_system_cfg);
user_db_mgr.Init_by_app(Bool_.N, fsys_mgr.Root_dir().OwnerDir().GenSubFil("xowa.user." + key + ".sqlite3")); // EX: /xowa/user/xowa.user.anonymous.sqlite3
if (!Env_.Mode_testing()) {
this.Available_from_fsys();
// data_mgr.Init_by_app(app);
}
}
public void App_term() {
session_mgr.Window_mgr().Save_window(app.Gui_mgr().Browser_win().Win_box());
history_mgr.Save(app);
if (app.Gui_mgr().Browser_win().Tab_mgr().Html_load_tid__url())
Io_mgr.I.DeleteDirDeep(fsys_mgr.App_temp_html_dir());
app.File_mgr().Cache_mgr().Db_term();
}
public void Bookmarks_add(byte[] wiki_domain, byte[] ttl_full_txt) {
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_k004();
bookmarks_add_fmtr.Bld_bfr_many(tmp_bfr, wiki_domain, ttl_full_txt);
byte[] new_entry = tmp_bfr.To_bry_and_rls();
Xoa_ttl bookmarks_ttl = Xoa_ttl.parse_(wiki, Bry_data_bookmarks);
Xoae_page bookmarks_page = wiki.Data_mgr().Get_page(bookmarks_ttl, false);
byte[] new_data = Bry_.Add(bookmarks_page.Data_raw(), new_entry);
wiki.Db_mgr().Save_mgr().Data_update(bookmarks_page, new_data);
} private Bry_fmtr bookmarks_add_fmtr = Bry_fmtr.new_("* [[~{wiki_key}:~{page_name}]]\n", "wiki_key", "page_name"); byte[] Bry_data_bookmarks = Bry_.new_u8("Data:Bookmarks");
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_available_from_bulk)) Available_from_bulk(m.ReadBry("v"));
else if (ctx.Match(k, Invk_available_from_fsys)) Available_from_fsys();
else if (ctx.Match(k, Invk_msgs)) return this.Msg_mgr();
else if (ctx.Match(k, Invk_lang)) return lang;
else if (ctx.Match(k, Invk_bookmarks_add_fmt_)) bookmarks_add_fmtr.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_wiki)) return this.Wiki(); // NOTE: mass parse relies on this being this.Wiki(), not wiki
else if (ctx.Match(k, Invk_history)) return history_mgr;
else if (ctx.Match(k, Invk_fsys)) return fsys_mgr;
else if (ctx.Match(k, Invk_prefs)) return prefs_mgr;
else if (ctx.Match(k, Invk_cfg)) return cfg_mgr;
else if (ctx.Match(k, Invk_session)) return session_mgr;
else if (ctx.Match(k, "name")) return key; //throw Exc_.new_unhandled(k); // OBSOLETE: used to return key
else return GfoInvkAble_.Rv_unhandled;
return this;
}
public static final String Invk_available_from_fsys = "available_from_fsys", Invk_available_from_bulk = "available_from_bulk", Invk_bookmarks_add_fmt_ = "bookmarks_add_fmt_"
, Invk_wiki = "wiki", Invk_history = "history", Invk_fsys = "fsys", Invk_lang = "lang", Invk_msgs = "msgs", Invk_prefs = "prefs", Invk_cfg = "cfg", Invk_session = "session";
public static final String Key_xowa_user = "anonymous";
public static final String Evt_lang_changed = "lang_changed";
public void Available_from_fsys() {
Io_url bookmarks_dir = fsys_mgr.Home_wiki_dir().GenSubDir_nest("wiki", "home", "ns", "730"); // NOTE: putting bookmark check here (instead of at init) b/c Init runs before xowa.gfs, and Bookmarks needs xowa.gfs to run first
if (!Io_mgr.I.ExistsDir(bookmarks_dir)) Xou_user_.Bookmarks_make(app, this.Wiki());
Io_url[] dirs = Io_mgr.I.QueryDir_args(app.Fsys_mgr().Wiki_dir()).Recur_(false).DirOnly_().ExecAsUrlAry();
Xowe_wiki usr_wiki = Wiki();
int dirs_len = dirs.length;
for (int i = 0; i < dirs_len; i++) {
Io_url dir = dirs[i];
String name = dir.NameOnly();
if (String_.Eq(name, gplx.xowa.bldrs.cmds.utils.Xob_core_batch_utl.Dir_dump)
// || !Io_mgr.I.ExistsDir(dir.GenSubFil_nest("ns"))
) continue;
byte[] dir_name_as_bry = Bry_.new_u8(name);
Xow_xwiki_itm xwiki = Available_add(usr_wiki, dir_name_as_bry);
if (xwiki != null) // Add_full can return null if adding invalid lang; should not apply here, but guard against null ref
xwiki.Offline_(true); // mark xwiki as offline; needed for available wikis sidebar; DATE:2014-09-21
app.Setup_mgr().Maint_mgr().Wiki_mgr().Add(dir_name_as_bry);
}
}
private void Available_from_bulk(byte[] raw) {
byte[][] wikis = Bry_.Split(raw, Byte_ascii.Nl);
Xowe_wiki usr_wiki = Wiki();
int wikis_len = wikis.length;
for (int i = 0; i < wikis_len; i++)
Available_add(usr_wiki, wikis[i]);
}
private Xow_xwiki_itm Available_add(Xowe_wiki usr_wiki, byte[] wiki_name) {
return usr_wiki.Xwiki_mgr().Add_full(wiki_name, wiki_name);
}
}

View File

@@ -0,0 +1,64 @@
/*
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.users; import gplx.*; import gplx.xowa.*;
import gplx.xowa.gui.views.*;
import gplx.xowa.apis.xowa.startups.tabs.*;
public class Xous_window_mgr implements GfoInvkAble {
public Xous_window_mgr(Xoue_user user) {
this.user = user;
}
public Xoue_user User() {return user;} private Xoue_user user;
public Rect_ref Rect() {if (rect == null) rect = Rect_new(); return rect;} Rect_ref rect;
public boolean Maximized() {return maximized;} private boolean maximized = false;
public void Save_window(gplx.gfui.GfuiWin win) {
Xoae_app app = user.Appe();
gplx.xowa.cfgs.Xoa_cfg_mgr cfg_mgr = app.Cfg_mgr();
if (user.Cfg_mgr().Startup_mgr().Window_mgr().Mode_tid() == Xouc_window_mgr.Mode_tid_previous) {
cfg_mgr.Set_by_app("app.user.session.window.maximized" , Yn.Xto_str(win.Maximized()));
cfg_mgr.Set_by_app("app.user.session.window.rect" , win.Rect().Xto_str());
}
Xoapi_startup_tabs startup_tabs = app.Api_root().App().Startup().Tabs();
if (startup_tabs.Type() == Xoapi_startup_tabs_tid_.Tid_previous) {
cfg_mgr.Set_by_app("xowa.api.app.startup.tabs.previous" , Calc_previous_tabs(app.Gui_mgr().Browser_win().Tab_mgr()));
}
cfg_mgr.Set_by_app("xowa.api.app.env.version_previous" , Xoa_app_.Version);
app.Api_root().Html().Page().Toggle_mgr().Save(cfg_mgr);
cfg_mgr.Db_save_txt();
}
private String Calc_previous_tabs(Xog_tab_mgr tab_mgr) {
Bry_bfr bfr = Bry_bfr.new_();
int len = tab_mgr.Tabs_len();
for (int i = 0; i < len; ++i) {
if (i != 0) bfr.Add_byte_nl();
Xog_tab_itm tab = tab_mgr.Tabs_get_at(i);
bfr.Add_str(tab.Page().Url().Xto_full_str_safe());
}
return bfr.Xto_str_and_clear();
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_rect)) return rect;
else if (ctx.Match(k, Invk_rect_)) rect = Rect_ref.parse_(m.ReadStr("v"));
else if (ctx.Match(k, Invk_maximized)) return Yn.Xto_str(maximized);
else if (ctx.Match(k, Invk_maximized_)) maximized = m.ReadYn("v");
return this;
} public static final String Invk_rect = "rect", Invk_rect_ = "rect_", Invk_maximized = "maximized", Invk_maximized_ = "maximized_";
private static Rect_ref Rect_new() { // NOTE: lazy initialization, else will fail for non-X11 environments; DATE:2014-03-02
gplx.gfui.SizeAdp size = Xouc_window_mgr.Screen_maximized_calc();
return new Rect_ref(0, 0, size.Width(), size.Height());
}
}

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.users; import gplx.*; import gplx.xowa.*;
import gplx.dbs.*;
import gplx.xowa.users.data.*;
import gplx.xowa.files.*; import gplx.xowa.files.caches.*;
import gplx.xowa.wikis.*;
import gplx.xowa.langs.genders.*;
public class Xouv_user implements Xou_user {
private Xoa_wiki_mgr wiki_mgr;
public Xouv_user(String key) {this.key = key;}
public String Key() {return key;} private String key;
public Xou_db_mgr User_db_mgr() {return user_db_mgr;} private Xou_db_mgr user_db_mgr;
public int Gender() {return Xol_gender_.Tid_unknown;}
public Xow_wiki Wikii() {if (wiki == null) wiki = wiki_mgr.Get_by_key_or_make_init_y(Xow_domain_.Domain_bry_home); return wiki;} private Xow_wiki wiki;
public void Init_db(Xoa_app app, Xoa_wiki_mgr wiki_mgr, Io_url db_url) {
this.wiki_mgr = wiki_mgr;
this.user_db_mgr = new Xou_db_mgr(app);
user_db_mgr.Init_by_app(Bool_.Y, db_url);
}
}

View File

@@ -0,0 +1,27 @@
/*
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.users.bmks; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_bmk_dir_row {
public Xoud_bmk_dir_row(int id, int owner, int sort, byte[] name) {
this.id = id; this.owner = owner; this.sort = sort; this.name = name;
}
public int Id() {return id;} private final int id;
public int Owner() {return owner;} private final int owner;
public int Sort() {return sort;} private final int sort;
public byte[] Name() {return name;} private final byte[] name;
}

View File

@@ -0,0 +1,60 @@
/*
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.users.bmks; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.dbs.qrys.*;
public class Xoud_bmk_dir_tbl implements RlsAble {
private final String tbl_name = "bmk_dir"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_id, fld_owner, fld_sort, fld_name;
public Xoud_bmk_dir_tbl(Db_conn conn) {
this.conn = conn;
fld_id = flds.Add_int_pkey_autonum("dir_id");
fld_owner = flds.Add_int("dir_owner");
fld_sort = flds.Add_int("dir_sort");
fld_name = flds.Add_str("dir_name", 255);
conn.Rls_reg(this);
}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public String Tbl_name() {return tbl_name;}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds.To_fld_ary()));}
public void Insert(int owner, int sort, byte[] name) {
Db_stmt stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_owner, owner).Val_int(fld_sort, sort).Val_bry_as_str(fld_name, name)
.Exec_insert();
}
public void Update(int id, int owner, int sort, byte[] name) {
Db_stmt stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_id);
stmt_update.Clear()
.Val_int(fld_owner, owner).Val_int(fld_sort, sort).Val_bry_as_str(fld_name, name)
.Crt_int(fld_id, id)
.Exec_update();
}
public void Delete(int id) {
Db_stmt stmt_delete = conn.Stmt_delete(tbl_name, fld_id);
stmt_delete.Clear().Crt_int(fld_id, id).Exec_delete();
}
// private Xoud_bmk_dir_row new_row(Db_rdr rdr) {
// return new Xoud_bmk_dir_row
// ( rdr.Read_int(fld_id)
// , rdr.Read_int(fld_owner)
// , rdr.Read_int(fld_sort)
// , rdr.Read_bry_by_str(fld_name)
// );
// }
public void Rls() {}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.bmks; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_bmk_itm_row {
public Xoud_bmk_itm_row(int id, int owner, int sort, byte[] name, byte[] wiki, byte[] url, byte[] comment) {
this.id = id; this.owner = owner; this.sort = sort; this.name = name; this.wiki = wiki; this.url = url; this.comment = comment;
}
public int Id() {return id;} private final int id;
public int Owner() {return owner;} private final int owner;
public int Sort() {return sort;} private final int sort;
public byte[] Name() {return name;} private final byte[] name;
public byte[] Wiki() {return wiki;} private final byte[] wiki;
public byte[] Url() {return url;} private final byte[] url;
public byte[] Comment() {return comment;} private final byte[] comment;
}

View File

@@ -0,0 +1,92 @@
/*
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.users.bmks; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.dbs.qrys.*;
public class Xoud_bmk_itm_tbl implements RlsAble {
private final String tbl_name = "bmk_itm"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_id, fld_owner, fld_sort, fld_name, fld_wiki, fld_url, fld_comment;
public Xoud_bmk_itm_tbl(Db_conn conn) {
this.conn = conn;
fld_id = flds.Add_int_pkey_autonum("itm_id");
fld_owner = flds.Add_int("itm_owner");
fld_sort = flds.Add_int("itm_sort");
fld_name = flds.Add_str("itm_name", 255);
fld_wiki = flds.Add_str("itm_wiki", 255);
fld_url = flds.Add_str("itm_url", 255);
fld_comment = flds.Add_str("itm_comment", 255);
conn.Rls_reg(this);
}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public String Tbl_name() {return tbl_name;}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds.To_fld_ary()));}
public void Insert(int owner, int sort, byte[] name, byte[] wiki, byte[] url, byte[] comment) {
Db_stmt stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_owner, owner).Val_int(fld_sort, sort).Val_bry_as_str(fld_name, name)
.Val_bry_as_str(fld_wiki, wiki).Val_bry_as_str(fld_url, url).Val_bry_as_str(fld_comment, comment)
.Exec_insert();
}
public void Update(int id, int owner, int sort, byte[] name, byte[] wiki, byte[] url, byte[] comment) {
Db_stmt stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_id);
stmt_update.Clear()
.Val_int(fld_owner, owner).Val_int(fld_sort, sort).Val_bry_as_str(fld_name, name)
.Val_bry_as_str(fld_wiki, wiki).Val_bry_as_str(fld_url, url).Val_bry_as_str(fld_comment, comment)
.Crt_int(fld_id, id)
.Exec_update();
}
public void Delete(int id) {
Db_stmt stmt_delete = conn.Stmt_delete(tbl_name, fld_id);
stmt_delete.Clear().Crt_int(fld_id, id).Exec_delete();
}
public Xoud_bmk_itm_row[] Select_grp(int owner) {
List_adp list = List_adp_.new_();
Db_rdr rdr = conn.Stmt_select_order(tbl_name, flds, String_.Ary(fld_owner), fld_sort)
.Crt_int(fld_owner, owner)
.Exec_select__rls_auto();
try {
while (rdr.Move_next())
list.Add(new_row(rdr));
}
finally {rdr.Rls();}
return (Xoud_bmk_itm_row[])list.To_ary_and_clear(Xoud_bmk_itm_row.class);
}
public int Select_sort_next(int owner) {
Db_rdr rdr = conn.Stmt_select_max(tbl_name, fld_sort, fld_owner).Crt_int(fld_owner, owner).Exec_select__rls_manual();
try {
int rv = 0;
if (rdr.Move_next()) {
Object rv_obj = rdr.Read_obj(fld_sort);
rv = rv_obj == null ? 0 : Int_.cast_(rv_obj) + 1;
}
return rv;
}
finally {rdr.Rls();}
}
private Xoud_bmk_itm_row new_row(Db_rdr rdr) {
return new Xoud_bmk_itm_row
( rdr.Read_int(fld_id)
, rdr.Read_int(fld_owner)
, rdr.Read_int(fld_sort)
, rdr.Read_bry_by_str(fld_name)
, rdr.Read_bry_by_str(fld_wiki)
, rdr.Read_bry_by_str(fld_url)
, rdr.Read_bry_by_str(fld_comment)
);
}
public void Rls() {}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.bmks; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*;
public class Xoud_bmk_mgr {
public Xoud_bmk_itm_tbl Tbl__itm() {return tbl__itm;} private Xoud_bmk_itm_tbl tbl__itm;
public Xoud_bmk_dir_tbl Tbl__dir() {return tbl__dir;} private Xoud_bmk_dir_tbl tbl__dir;
public void Conn_(Db_conn conn, boolean created) {
this.tbl__dir = new Xoud_bmk_dir_tbl(conn);
this.tbl__itm = new Xoud_bmk_itm_tbl(conn);
// if (!conn.Meta_tbl_exists(tbl__dir.Tbl_name())) tbl__dir.Create_tbl(); // bmk_v2
// if (!conn.Meta_tbl_exists(tbl__itm.Tbl_name())) tbl__itm.Create_tbl();
}
public void Itms__add(int owner, Xoa_url url) {
tbl__itm.Insert(owner, tbl__itm.Select_sort_next(owner), Xoa_ttl.Replace_unders(url.Page_bry()), url.Wiki_bry(), url.Raw(), Bry_.Empty);
}
public Xoud_bmk_itm_row[] Itms__get(int owner) {return tbl__itm.Select_grp(owner);}
public static final int Owner_root = -1;
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.dbs.metas.*;
import gplx.xowa.files.caches.*;
import gplx.xowa.users.bmks.*;
public class Xou_db_file {
private final Db_conn conn;
public Xou_db_file(Db_conn conn) {
this.conn = conn;
this.tbl__cfg = new Db_cfg_tbl(conn, "xowa_cfg");
this.tbl__site = new Xoud_site_tbl(conn);
this.tbl__history = new Xoud_history_tbl(conn);
this.tbl__cache = new Xou_cache_tbl(conn);
// this.tbl__bmk = new Xoud_bmk_tbl(conn);
}
public Db_cfg_tbl Tbl__cfg() {return tbl__cfg;} private final Db_cfg_tbl tbl__cfg;
public Xoud_site_tbl Tbl__site() {return tbl__site;} private final Xoud_site_tbl tbl__site;
public Xoud_history_tbl Tbl__history() {return tbl__history;} private final Xoud_history_tbl tbl__history;
public Xou_cache_tbl Tbl__cache() {return tbl__cache;} private final Xou_cache_tbl tbl__cache;
// public Xoud_bmk_tbl Tbl__bmk() {return tbl__bmk;} private final Xoud_bmk_tbl tbl__bmk;
public void Init_assert() {
if (!conn.Meta_tbl_exists(tbl__cache.Tbl_name())) {
tbl__cfg.Create_tbl();
tbl__cache.Create_tbl();
}
// if (!conn.Meta_tbl_exists(tbl__bmk.Tbl_name())) {
// tbl__bmk.Create_tbl();
// }
}
}

View File

@@ -0,0 +1,50 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.threads.*; import gplx.dbs.*; import gplx.dbs.metas.updates.*; import gplx.dbs.metas.*;
import gplx.xowa.files.caches.*;
import gplx.xowa.users.bmks.*;
public class Xou_db_mgr {
private final Xoa_app app;
private final Xoud_id_mgr id_mgr;
public Xou_db_mgr(Xoa_app app) {
this.app = app;
this.id_mgr = new Xoud_id_mgr(cfg_mgr);
this.site_mgr = new Xoud_site_mgr(id_mgr);
}
public Xou_db_file Db_file() {return db_file;} private Xou_db_file db_file;
public Xoud_cfg_mgr Cfg_mgr() {return cfg_mgr;} private final Xoud_cfg_mgr cfg_mgr = new Xoud_cfg_mgr();
public Xoud_site_mgr Site_mgr() {return site_mgr;} private final Xoud_site_mgr site_mgr;
public Xoud_history_mgr History_mgr() {return history_mgr;} private final Xoud_history_mgr history_mgr = new Xoud_history_mgr();
public Xoud_bmk_mgr Bmk_mgr() {return bmk_mgr;} private final Xoud_bmk_mgr bmk_mgr = new Xoud_bmk_mgr();
public Xou_cache_mgr Cache_mgr() {return cache_mgr;} private Xou_cache_mgr cache_mgr;
public Xou_file_itm_finder File__xfer_itm_finder() {return xfer_itm_finder;} private Xou_file_itm_finder xfer_itm_finder;
public void Init_by_app(boolean drd, Io_url db_url) {
Db_conn_bldr_data db_conn_bldr = Db_conn_bldr.I.Get_or_new(db_url);
Db_conn conn = db_conn_bldr.Conn(); boolean created = db_conn_bldr.Created();
this.db_file = new Xou_db_file(conn); db_file.Init_assert();
this.cache_mgr = new Xou_cache_mgr(app.Wiki_mgri(), app.Fsys_mgr().File_dir(), db_file);
this.xfer_itm_finder = new Xou_file_itm_finder(cache_mgr);
this.bmk_mgr.Conn_(conn, created);
if (drd) {
cfg_mgr.Conn_(conn, created);
site_mgr.Conn_(conn, created);
// history_mgr.Conn_(user_conn, created);
}
}
}

View File

@@ -0,0 +1,64 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.dbs.cfgs.*;
public class Xoud_cfg_mgr {
public Db_cfg_tbl Tbl() {return tbl;} private Db_cfg_tbl tbl;
public void Conn_(Db_conn new_conn, boolean created) {
tbl = new Db_cfg_tbl(new_conn, "user_opt");
if (created) tbl.Create_tbl();
}
public int Select_int_or(String grp, String key, int or) {
String rv = Select_str_or(grp, key, null);
return rv == null ? or : Int_.parse_or_(rv, or);
}
public byte[] Select_bry_or(String key, byte[] or) {return Select_bry_or("" , key, or);}
public byte[] Select_bry_or(String grp, String key, byte[] or) {
String rv = Select_str_or(grp, key, null);
return rv == null ? or : Bry_.new_u8(rv);
}
public String Select_str_or(String grp, String key, String or) {
String rv = tbl.Select_str_or(grp, key, null);
return rv == null ? or : rv;
}
public byte[] Assert_bry_or(String key, byte[] or) {return Assert_bry_or("", key, or);}
public byte[] Assert_bry_or(String grp, String key, byte[] or) {
String rv = tbl.Select_str_or(grp, key, null);
if (rv == null) {
Insert_bry(grp, key, or);
return or;
}
else
return Bry_.new_u8(rv);
}
public void Update_bry(String key, byte[] val) {Update_bry("", key, val);}
public void Update_bry(String grp, String key, byte[] val) {tbl.Update_bry(grp, key, val);}
public void Insert_bry(String key, byte[] val) {Insert_bry("", key, val);}
public void Insert_bry(String grp, String key, byte[] val) {tbl.Insert_bry(grp, key, val);}
public void Insert_int(String grp, String key, int val) {tbl.Insert_int(grp, key, val);}
public int Next_id(String tbl_name) {
String grp = "xowa." + tbl_name, key = "next_id";
int next_id = tbl.Select_int_or(grp, key, 1); // EX: xowa.cfg_history|next_id|1
int new_val = next_id + 1;
if (next_id == 1)
tbl.Insert_int(grp, key, new_val);
else
tbl.Update_int(grp, key, new_val);
return next_id;
}
}

View File

@@ -0,0 +1,57 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.threads.*; import gplx.dbs.*;
import gplx.xowa.specials.*;
public class Xoud_history_mgr implements GfoInvkAble {
private Xoud_history_tbl history_tbl;
public void Conn_(Db_conn new_conn, boolean created) {
history_tbl = new Xoud_history_tbl(new_conn);
if (created) history_tbl.Create_tbl();
}
public void Update_async(Gfo_async_mgr async_mgr, Xoa_ttl ttl, Xoa_url url) {
// if (Skip_history(ttl)) return;
// async_mgr.Queue(this, Invk_update, "wiki", String_.new_u8(url.Wiki_bry()), "page", String_.new_u8(url.Page_bry()), "qarg", String_.new_u8(url.Args_all_as_bry()));
}
private void Update(String wiki, String page, String qarg) {
Xoud_history_row row = history_tbl.Select_by_page(wiki, page, qarg);
DateAdp time = DateAdp_.Now();
if (row == null)
history_tbl.Insert(wiki, page, qarg, time, 1);
else
history_tbl.Update(wiki, page, qarg, time, row.History_count() + 1);
}
public void Select(List_adp rv, int top) {
history_tbl.Select_by_top(rv, top);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_update)) Update(m.ReadStr("wiki"), m.ReadStr("page"), m.ReadStr("qarg"));
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_update = "update";
public static boolean Skip_history(Xoa_ttl ttl) {
byte[] page_db = ttl.Page_db();
return ( ttl.Ns().Id_special()
&& ( Bry_.Eq(page_db, gplx.xowa.users.history.Xou_history_mgr.Ttl_name) // do not add XowaPageHistory to history
|| Bry_.Eq(page_db, Xows_special_meta_.Itm__popup_history.Key_bry())
|| Bry_.Eq(page_db, Xows_special_meta_.Itm__default_tab.Key_bry())
|| Bry_.Eq(page_db, Xows_special_meta_.Itm__page_history.Key_bry())
)
);
}
}

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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_history_row {
public Xoud_history_row(String history_wiki, String history_page, String history_qarg, DateAdp history_time, int history_count) {
this.history_wiki = history_wiki;
this.history_page = history_page;
this.history_qarg = history_qarg;
this.history_time = history_time;
this.history_count = history_count;
}
public String History_wiki() {return history_wiki;} private final String history_wiki;
public String History_page() {return history_page;} private final String history_page;
public String History_qarg() {return history_qarg;} private final String history_qarg;
public DateAdp History_time() {return history_time;} private final DateAdp history_time;
public int History_count() {return history_count;} private final int history_count;
public static final Xoud_history_row Null = null;
}

View File

@@ -0,0 +1,59 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.xowa.specials.*;
public class Xoud_history_special implements Bry_fmtr_arg, Xows_page {
private List_adp rows = List_adp_.new_();
public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__page_history;}
public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) {
Xoae_app app = wiki.Appe();
Xoud_history_mgr mgr = app.User().User_db_mgr().History_mgr();
mgr.Select(rows, 100);
Bry_bfr bfr = app.Utl__bfr_mkr().Get_m001();
html_grp.Bld_bfr_many(bfr, this);
page.Data_raw_(bfr.To_bry_and_rls());
}
public void XferAry(Bry_bfr bfr, int idx) {
int len = rows.Count();
for (int i = 0; i < len; i++) {
Xoud_history_row row = (Xoud_history_row)rows.Get_at(i);
html_itm.Bld_bfr_many(bfr, row.History_wiki(), row.History_page(), row.History_count(), row.History_time().XtoStr_fmt_yyyy_MM_dd_HH_mm());
}
}
private static Bry_fmtr html_grp = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<table class='sortable'>"
, " <tr>"
, " <th>page</th>"
, " <th>wiki</th>"
, " <th>views</th>"
, " <th>time</th>"
, " </tr>~{itms}"
, "</table>"
), "itms"
);
private static Bry_fmtr html_itm = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <tr>"
, " <td>[[~{itm_wiki}:~{itm_page}|~{itm_page}]]</td>"
, " <td>~{itm_wiki}</td>"
, " <td>~{itm_count}</td>"
, " <td>~{itm_last}</td>"
, " </tr>"
), "itm_wiki", "itm_page", "itm_count", "itm_last"
);
}

View File

@@ -0,0 +1,94 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.dbs.qrys.*; import gplx.dbs.metas.*; import gplx.dbs.metas.updates.*;
public class Xoud_history_tbl implements RlsAble {
private final String tbl_name = "user_history"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_wiki, fld_page, fld_qarg, fld_time, fld_count;
private final Db_conn conn; private Db_stmt stmt_select_by_page, stmt_select_by_top, stmt_insert, stmt_update, stmt_delete;
public Xoud_history_tbl(Db_conn conn) {
this.conn = conn;
fld_wiki = flds.Add_str("hist_wiki", 255);
fld_page = flds.Add_str("hist_page", 255);
fld_qarg = flds.Add_str("hist_qarg", 255);
fld_time = flds.Add_str("hist_time", 20);
fld_count = flds.Add_int("hist_count");
stmt_insert = stmt_update = stmt_delete = stmt_select_by_page = stmt_select_by_top = null;
conn.Rls_reg(this);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds, Db_meta_idx.new_unique_by_tbl(tbl_name, "pkey", fld_wiki, fld_page, fld_qarg)));}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_update = Db_stmt_.Rls(stmt_update);
stmt_delete = Db_stmt_.Rls(stmt_delete);
stmt_select_by_page = Db_stmt_.Rls(stmt_select_by_page);
stmt_select_by_top = Db_stmt_.Rls(stmt_select_by_top);
}
public void Insert(String wiki, String page, String qarg, DateAdp time, int count) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_str(fld_wiki, wiki).Val_str(fld_page, page).Val_str(fld_qarg, qarg)
.Val_str(fld_time, time.XtoStr_fmt_iso_8561()).Val_int(fld_count, count)
.Exec_insert();
}
public void Update(String wiki, String page, String qarg, DateAdp time, int count) {
if (stmt_update == null) stmt_update = conn.Stmt_update(tbl_name, String_.Ary(fld_wiki, fld_page, fld_qarg), fld_time, fld_count);
stmt_update.Clear()
.Val_str(fld_time, time.XtoStr_fmt_iso_8561()).Val_int(fld_count, count)
.Crt_str(fld_wiki, wiki).Crt_str(fld_page, page).Crt_str(fld_qarg, qarg)
.Exec_update();
}
public void Delete(String wiki, String page, String qarg) {
if (stmt_delete == null) stmt_delete = conn.Stmt_delete(tbl_name, fld_wiki, fld_page, fld_qarg);
stmt_delete.Clear()
.Crt_str(fld_wiki, wiki).Crt_str(fld_page, page).Crt_str(fld_qarg, qarg)
.Exec_delete();
}
public Xoud_history_row Select_by_page(String wiki, String page, String qarg) {
if (stmt_select_by_page == null) stmt_select_by_page = conn.Stmt_select(tbl_name, flds, fld_wiki, fld_page, fld_qarg);
Db_rdr rdr = stmt_select_by_page.Clear().Crt_str(fld_wiki, wiki).Crt_str(fld_page, page).Crt_str(fld_qarg, qarg).Exec_select__rls_manual();
try {
return rdr.Move_next() ? new_row(rdr) : Xoud_history_row.Null;
}
finally {rdr.Rls();}
}
public void Select_by_top(List_adp rv, int count) {
if (stmt_select_by_top == null) {
Db_qry__select_in_tbl qry = new Db_qry__select_in_tbl(tbl_name, flds.To_str_ary(), null, null, null, fld_time + " DESC", " LIMIT " + Int_.Xto_str(count));
stmt_select_by_top = conn.Stmt_new(qry);
}
Db_rdr rdr = stmt_select_by_top.Clear().Exec_select__rls_manual();
try {
rv.Clear();
while (rdr.Move_next()) {
Xoud_history_row row = new_row(rdr);
rv.Add(row);
}
}
finally {rdr.Rls();}
}
private Xoud_history_row new_row(Db_rdr rdr) {
return new Xoud_history_row
( rdr.Read_str(fld_wiki)
, rdr.Read_str(fld_page)
, rdr.Read_str(fld_qarg)
, rdr.Read_date_by_str(fld_time)
, rdr.Read_int(fld_count)
);
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_id_mgr {
private Xoud_cfg_mgr cfg_mgr;
public Xoud_id_mgr(Xoud_cfg_mgr cfg_mgr) {this.cfg_mgr = cfg_mgr;}
public int Get_next(String key) {return cfg_mgr.Select_int_or(Grp_key, key, 1);}
public void Set_next(String key, int v) {cfg_mgr.Insert_int(Grp_key, key, v);}
public int Get_next_and_save(String key) {
int rv = Get_next(key);
Set_next(key, rv + 1);
return rv;
}
private static final String Grp_key = "gplx.next_id";
}

View File

@@ -0,0 +1,84 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.btries.*; import gplx.core.primitives.*;
import gplx.xowa.langs.*; import gplx.xowa.wikis.*;
class Xoud_opt_scope {
public Xoud_opt_scope(int lang_id, int type_id) {this.lang_id = lang_id; this.type_id = type_id;}
public int Lang_id() {return lang_id;} private final int lang_id;
public int Type_id() {return type_id;} private final int type_id;
public String To_str() {
String lang_str = lang_id == Lang_id_wildcard ? "*" : String_.new_u8(Xol_lang_itm_.Get_by_id(lang_id).Key());
String type_str = type_id == Lang_id_wildcard ? "*" : String_.new_u8(Xow_domain_type_.Get_type_as_bry(type_id));
return lang_str + "." + type_str;
}
public static final int Lang_id_wildcard = -1, Type_id_wildcard = -1;
public static final Xoud_opt_scope App = new Xoud_opt_scope(Lang_id_wildcard, Type_id_wildcard);
}
class Xoud_opt_scope_parser {
private Gfo_usr_dlg usr_dlg; private final List_adp list = List_adp_.new_();
public Xoud_opt_scope[] Parse(byte[] src) {
usr_dlg = Gfo_usr_dlg_.I;
list.Clear();
int pos = 0; int src_len = src.length;
while (pos < src_len) {
int comma_pos = Bry_finder.Find_fwd(src, Byte_ascii.Comma, pos, src_len); if (comma_pos == Bry_finder.Not_found) comma_pos = src_len;
Xoud_opt_scope itm = Parse_itm(src, pos, comma_pos);
if (itm == Xoud_opt_scope.App) return Ary_app;
list.Add(itm);
pos = comma_pos + 1;
}
return (Xoud_opt_scope[])list.To_ary_and_clear(Xoud_opt_scope.class);
}
public Xoud_opt_scope Parse_itm(byte[] src, int bgn, int end) {
int lang_dot = Bry_finder.Find_fwd(src, Byte_ascii.Dot, bgn, end); if (lang_dot == Bry_finder.Not_found) return Warn("scope.parse.missing_lang_dot: src=~{0}", src, bgn, end);
int lang_id = Int_.MinValue;
if (lang_dot == 1 && src[bgn] == Byte_ascii.Star)
lang_id = Xoud_opt_scope.Lang_id_wildcard;
else {
Xol_lang_itm lang_itm = Xol_lang_itm_.Get_by_key_or_null(src, bgn, lang_dot); if (lang_itm == null) return Warn("scope.parse.invalid_lang: src=~{0}", src, bgn, end);
lang_id = lang_itm.Id();
}
Object type_tid_obj = btrie_by_type.Match_bgn(src, lang_dot + 1, end); if (type_tid_obj == null) return Warn("scope.parse.invalid_type: src=~{0}", src, bgn, end);
int type_id = ((Int_obj_val)type_tid_obj).Val();
return new Xoud_opt_scope(lang_id, type_id);
}
private Xoud_opt_scope Warn(String fmt, byte[] src, int bgn, int end) {
usr_dlg.Warn_many("", "", fmt, String_.new_u8(src, bgn, end));
return Xoud_opt_scope.App;
}
private static final Btrie_slim_mgr btrie_by_type = Btrie_slim_mgr.cs_()
.Add_str_int("w" , Xow_domain_type_.Tid_wikipedia)
.Add_str_int("d" , Xow_domain_type_.Tid_wiktionary)
.Add_str_int("s" , Xow_domain_type_.Tid_wikisource)
.Add_str_int("v" , Xow_domain_type_.Tid_wikivoyage)
.Add_str_int("q" , Xow_domain_type_.Tid_wikiquote)
.Add_str_int("b" , Xow_domain_type_.Tid_wikibooks)
.Add_str_int("u" , Xow_domain_type_.Tid_wikiversity)
.Add_str_int("n" , Xow_domain_type_.Tid_wikinews)
.Add_str_int("*" , Xoud_opt_scope.Type_id_wildcard)
.Add_str_int("xowa" , Xow_domain_type_.Tid_home)
.Add_str_int("wd" , Xow_domain_type_.Tid_wikidata)
.Add_str_int("c" , Xow_domain_type_.Tid_commons)
.Add_str_int("species" , Xow_domain_type_.Tid_species)
.Add_str_int("meta" , Xow_domain_type_.Tid_meta)
.Add_str_int("mw" , Xow_domain_type_.Tid_mediawiki)
.Add_str_int("wmf" , Xow_domain_type_.Tid_wmfblog)
;
private static final Xoud_opt_scope[] Ary_app = new Xoud_opt_scope[] {Xoud_opt_scope.App};
}

View File

@@ -0,0 +1,51 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import org.junit.*; import gplx.xowa.langs.*; import gplx.xowa.wikis.*;
public class Xoud_opt_scope_tst {
private Xoud_opt_scope_fxt fxt = new Xoud_opt_scope_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Basic() {
fxt.Test_parse("en.w" , fxt.Make(Xol_lang_itm_.Id_en, Xow_domain_type_.Tid_wikipedia));
fxt.Test_parse("en.*" , fxt.Make(Xol_lang_itm_.Id_en, Xoud_opt_scope.Type_id_wildcard));
fxt.Test_parse("*.w" , fxt.Make(Xoud_opt_scope.Lang_id_wildcard, Xow_domain_type_.Tid_wikipedia));
fxt.Test_parse("<any>" , Xoud_opt_scope.App);
fxt.Test_parse("en.w,fr.d" , fxt.Make(Xol_lang_itm_.Id_en, Xow_domain_type_.Tid_wikipedia), fxt.Make(Xol_lang_itm_.Id_fr, Xow_domain_type_.Tid_wiktionary));
}
}
class Xoud_opt_scope_fxt {
private final Xoud_opt_scope_parser parser = new Xoud_opt_scope_parser();
public void Clear() {
// Gfo_usr_dlg_.I = Xoa_app_.usr_dlg_console_();
}
public Xoud_opt_scope Make(int lang_id, int type_id) {return new Xoud_opt_scope(lang_id, type_id);}
public void Test_parse(String raw, Xoud_opt_scope... expd) {
Xoud_opt_scope[] actl = parser.Parse(Bry_.new_u8(raw));
Tfds.Eq(To_str(expd), To_str(actl));
}
private static String To_str(Xoud_opt_scope[] ary) {
Bry_bfr bfr = Bry_bfr.new_();
int len = ary.length;
for (int i = 0; i < len; ++i) {
Xoud_opt_scope itm = ary[i];
if (i != 0) bfr.Add_str_a7(",");
bfr.Add_str_a7(itm.To_str());
}
return bfr.Xto_str_and_clear();
}
}

View File

@@ -0,0 +1,24 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_regy_row {
public Xoud_regy_row(String cfg_grp, String cfg_key, String cfg_val) {this.cfg_grp = cfg_grp; this.cfg_key = cfg_key; this.cfg_val = cfg_val;}
public String Cfg_grp() {return cfg_grp;} private final String cfg_grp;
public String Cfg_key() {return cfg_key;} private final String cfg_key;
public String Cfg_val() {return cfg_val;} private final String cfg_val;
}

View File

@@ -0,0 +1,89 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.dbs.qrys.*; import gplx.dbs.metas.*; import gplx.dbs.metas.updates.*;
public class Xoud_regy_tbl {
public static final String Tbl_name = "user_regy", Fld_regy_grp = "regy_grp", Fld_regy_key = "regy_key", Fld_regy_val = "regy_val";
private static final String[] Flds__all = new String[] {Fld_regy_grp, Fld_regy_key, Fld_regy_val};
public static final Db_idx_itm Idx_core = Db_idx_itm.sql_("CREATE UNIQUE INDEX user_regy_core ON user_regy (regy_grp, regy_key);");
public static final String Tbl_sql = String_.Concat_lines_nl
( "CREATE TABLE user_regy"
, "( regy_grp nvarchar(255) NOT NULL -- EX: xowa.schema.site"
, ", regy_key nvarchar(255) NOT NULL -- EX: next_id"
, ", regy_val nvarchar(255) NOT NULL -- EX: 1"
, ");"
);
private Db_stmt stmt_select_grp, stmt_select_key, stmt_insert, stmt_update, stmt_delete;
public Db_conn Conn() {return conn;}
public Xoud_regy_tbl Conn_(Db_conn v, boolean created) {
this.Rls_all(); conn = v;
if (created) {
Schema_update_cmd cmd = Schema_update_cmd_.Make_tbl_create(Xoud_regy_tbl.Tbl_name , Xoud_regy_tbl.Tbl_sql , Xoud_regy_tbl.Idx_core);
cmd.Exec(null, conn);
// conn.Ddl_create_tbl(meta);
}
return this;
} private Db_conn conn;
@gplx.Virtual public void Insert(String grp, String key, String val) {
if (stmt_insert == null) stmt_insert = Db_stmt_.new_insert_(conn, Tbl_name, Flds__all);
stmt_insert.Clear().Val_str(grp).Val_str(key).Val_str(val).Exec_insert();
}
@gplx.Virtual public void Update(String grp, String key, String val) {
if (stmt_update == null) stmt_update = Db_stmt_.new_update_(conn, Tbl_name, String_.Ary(Fld_regy_grp, Fld_regy_key), Fld_regy_val);
stmt_update.Clear().Val_str(val).Val_str(grp).Val_str(key).Exec_update();
}
@gplx.Virtual public void Delete(String grp, String key) {
if (stmt_delete == null) stmt_delete = Db_stmt_.new_delete_(conn, Tbl_name, Fld_regy_grp, Fld_regy_key);
stmt_delete.Clear().Val_str(grp).Val_str(key).Exec_delete();
}
@gplx.Virtual public void Select_by_grp(List_adp rv, String grp) {
if (stmt_select_grp == null) stmt_select_grp = Db_stmt_.new_select_as_rdr(conn, Db_qry__select_in_tbl.new_(Tbl_name, String_.Ary(Fld_regy_grp), Flds__all, Db_qry__select_in_tbl.Order_by_null));
Db_rdr rdr = stmt_select_grp.Clear().Val_str(grp).Exec_select__rls_manual();
try {
while (rdr.Move_next()) {
Xoud_regy_row row = Make_row(rdr);
rv.Add(row);
}
}
finally {rdr.Rls();}
}
@gplx.Virtual public String Select_val(String grp, String key) {
if (stmt_select_key == null) stmt_select_key = Db_stmt_.new_select_as_rdr(conn, Db_qry__select_in_tbl.new_(Tbl_name, String_.Ary(Fld_regy_grp, Fld_regy_key), Flds__all, Db_qry__select_in_tbl.Order_by_null));
Db_rdr rdr = stmt_select_key.Clear().Val_str(Fld_regy_grp, grp).Val_str(Fld_regy_key, key).Exec_select__rls_manual();
String rv = null;
if (rdr.Move_next())
rv = rdr.Read_str(Fld_regy_val);
rdr.Rls();
return rv;
}
private Xoud_regy_row Make_row(Db_rdr rdr) {
return new Xoud_regy_row
( rdr.Read_str(Fld_regy_grp)
, rdr.Read_str(Fld_regy_key)
, rdr.Read_str(Fld_regy_val)
);
}
public void Rls_all() {
if (stmt_select_grp != null) {stmt_select_grp.Rls(); stmt_select_grp = null;}
if (stmt_select_key != null) {stmt_select_key.Rls(); stmt_select_key = null;}
if (stmt_insert != null) {stmt_insert.Rls(); stmt_insert = null;}
if (stmt_update != null) {stmt_update.Rls(); stmt_update = null;}
if (stmt_delete != null) {stmt_delete.Rls(); stmt_delete = null;}
conn = null;
}
}

View File

@@ -0,0 +1,45 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*; import gplx.xowa.users.data.*;
public class Xoud_site_mgr {
private Xoud_site_tbl tbl;
private final Xoud_id_mgr id_mgr;
public Xoud_site_mgr(Xoud_id_mgr id_mgr) {this.id_mgr = id_mgr;}
public void Conn_(Db_conn conn, boolean created) {
tbl = new Xoud_site_tbl(conn);
if (created) tbl.Create_tbl();
}
public Xoud_site_row[] Get_all() {return tbl.Select_all();}
public void Import(String domain, String name, String path, String xtn) { // insert or update wiki
Xoud_site_row[] ary = tbl.Select_by_domain(domain);
int len = ary.length, update_id = -1, priority = 0;
for (int i = 0; i < len; ++i) {
Xoud_site_row itm = ary[i];
if (priority <= itm.Priority()) priority = itm.Priority() + 1;
if (String_.Eq(path, itm.Path())) { // same domain and same path; change insert to update;
update_id = itm.Id();
break;
}
}
if (update_id == -1)
tbl.Insert(id_mgr.Get_next_and_save("xowa.user.site"), priority, domain, name, path, xtn);
else
tbl.Update(update_id, priority, domain, name, path, xtn);
}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_site_row {
public Xoud_site_row(int id, int priority, String domain, String name, String path, String xtn) {
this.id = id; this.priority = priority; this.domain = domain; this.name = name; this.path = path; this.xtn = xtn;
}
public int Id() {return id;} private final int id;
public int Priority() {return priority;} private final int priority;
public String Domain() {return domain;} private final String domain;
public String Name() {return name;} private final String name;
public String Path() {return path;} private final String path;
public String Xtn() {return xtn;} private String xtn;
}

View File

@@ -0,0 +1,82 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*;
public class Xoud_site_tbl implements RlsAble {
private final String tbl_name = "user_site"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_site_id, fld_site_priority, fld_site_domain, fld_site_name, fld_site_path, fld_site_xtn;
private final Db_conn conn;
public Xoud_site_tbl(Db_conn conn) {
this.conn = conn;
fld_site_id = flds.Add_int_pkey("site_id");
fld_site_priority = flds.Add_int("site_priority"); // EX: 0=default; 1+ is order if 0 is unavailable
fld_site_domain = flds.Add_str("site_domain", 255); // EX: en.wikipedia.org; NOTE: no protocol (https:)
fld_site_name = flds.Add_str("site_name", 255); // EX: English Wikipedia
fld_site_path = flds.Add_str("site_path", 255); // EX: ~{xowa_root}/wiki/en.wikipedia.org/
fld_site_xtn = flds.Add_text("site_xtn");
conn.Rls_reg(this);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds));}
public void Rls() {}
public void Insert(int site_id, int priority, String domain, String name, String path, String xtn) {
Db_stmt stmt = conn.Stmt_insert(tbl_name, flds);
stmt.Val_int(fld_site_id, site_id)
.Val_int(fld_site_priority, priority).Val_str(fld_site_domain, domain).Val_str(fld_site_name, name).Val_str(fld_site_path, path).Val_str(fld_site_xtn, xtn)
.Exec_insert();
}
public void Update(int site_id, int priority, String domain, String name, String path, String xtn) {
Db_stmt stmt = conn.Stmt_update_exclude(tbl_name, flds, fld_site_id);
stmt.Val_int(fld_site_priority, priority).Val_str(fld_site_domain, domain).Val_str(fld_site_name, name).Val_str(fld_site_path, path).Val_str(fld_site_xtn, xtn)
.Crt_int(fld_site_id, site_id)
.Exec_update();
}
public void Delete(int site_id) {
Db_stmt stmt = conn.Stmt_delete(tbl_name, fld_site_id);
stmt.Crt_int(fld_site_id, site_id).Exec_delete();
}
public Xoud_site_row[] Select_all() {
List_adp rv = List_adp_.new_();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds).Exec_select__rls_auto();
try {
while (rdr.Move_next())
rv.Add(new_row(rdr));
return (Xoud_site_row[])rv.To_ary_and_clear(Xoud_site_row.class);
}
finally {rdr.Rls();}
}
public Xoud_site_row[] Select_by_domain(String domain) {
List_adp rv = List_adp_.new_();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_site_domain).Crt_str(fld_site_domain, domain).Exec_select__rls_auto();
try {
while (rdr.Move_next())
rv.Add(new_row(rdr));
return (Xoud_site_row[])rv.To_ary_and_clear(Xoud_site_row.class);
}
finally {rdr.Rls();}
}
private Xoud_site_row new_row(Db_rdr rdr) {
return new Xoud_site_row
( rdr.Read_int(fld_site_id)
, rdr.Read_int(fld_site_priority)
, rdr.Read_str(fld_site_domain)
, rdr.Read_str(fld_site_name)
, rdr.Read_str(fld_site_path)
, rdr.Read_str(fld_site_xtn)
);
}
}

View File

@@ -0,0 +1,71 @@
/*
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.users.data; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*;
class Xoud_user_mgr {
private Xoud_user_tbl tbl = new Xoud_user_tbl();
public void Conn_(Db_conn conn, boolean created) {tbl.Conn_(conn, created);}
public int Get_id_or_new(String name) {
int rv = tbl.Select_id_by_name(name);
if (rv == Int_.MinValue) {
rv = tbl.Select_id_next();
tbl.Insert(rv, name);
}
return rv;
}
}
class Xoud_user_tbl {
private String tbl_name = "user_user_regy"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private String fld_id, fld_name;
private Db_conn conn;
public void Conn_(Db_conn new_conn, boolean created) {
this.conn = new_conn; flds.Clear();
fld_id = flds.Add_int_pkey("id");
fld_name = flds.Add_str("name", 255);
if (created) {
Db_meta_tbl meta = Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_unique_by_tbl(tbl_name, "name", fld_name)
);
conn.Ddl_create_tbl(meta);
}
}
public void Insert(int id, String name) {
Db_stmt stmt = conn.Stmt_insert(tbl_name, flds);
stmt.Val_int(fld_id, id).Val_str(fld_name, name)
.Exec_insert();
}
public int Select_id_by_name(String name) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_name).Crt_str(fld_name, name).Exec_select__rls_auto();
try {
return rdr.Move_next() ? rdr.Read_int(fld_id) : Int_.MinValue;
}
finally {rdr.Rls();}
}
public int Select_id_next() {
int rv = 1;
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Db_meta_fld.Ary_empty).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
int cur = rdr.Read_int(fld_id);
if (cur >= rv) rv = cur + 1;
}
return rv;
}
finally {rdr.Rls();}
}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xou_history_cfg implements GfoInvkAble {
public Xou_history_cfg() {
this.enabled = true; // CFG: default to true for general user; privacy-conscious users must disable
}
public boolean Enabled() {return enabled;} private boolean enabled;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_enabled_)) enabled = m.ReadBool("v");
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_enabled_ = "enabled_";
}

View File

@@ -0,0 +1,55 @@
/*
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.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.xowa.specials.*;
public class Xou_history_html implements Bry_fmtr_arg, Xows_page {
public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__page_history;}
public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) {
this.app = wiki.Appe(); this.mgr = app.Usere().History_mgr();
mgr.Sort();
Bry_bfr bfr = app.Utl__bfr_mkr().Get_m001();
html_grp.Bld_bfr_many(bfr, this);
page.Data_raw_(bfr.To_bry_and_rls());
}
public void XferAry(Bry_bfr bfr, int idx) {
int len = mgr.Len();
for (int i = 0; i < len; i++) {
Xou_history_itm itm = mgr.Get_at(i);
html_itm.Bld_bfr_many(bfr, itm.Wiki(), itm.Page(), itm.View_count(), itm.View_end().XtoStr_fmt_yyyy_MM_dd_HH_mm());
}
} private Xou_history_mgr mgr; Xoae_app app;
public Bry_fmtr Html_grp() {return html_grp;} Bry_fmtr html_grp = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<table class='sortable'>"
, " <tr>"
, " <th>page</th>"
, " <th>wiki</th>"
, " <th>views</th>"
, " <th>time</th>"
, " </tr>~{itms}"
, "</table>"
), "itms");
public Bry_fmtr Html_itm() {return html_itm;} Bry_fmtr html_itm = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <tr>"
, " <td>[[~{itm_wiki}:~{itm_page}|~{itm_page}]]</td>"
, " <td>~{itm_wiki}</td>"
, " <td>~{itm_count}</td>"
, " <td>~{itm_last}</td>"
, " </tr>"
), "itm_wiki", "itm_page", "itm_count", "itm_last");
}

View File

@@ -0,0 +1,72 @@
/*
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.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.primitives.*;
public class Xou_history_itm {
public Xou_history_itm(byte[] wiki, byte[] page) {
this.wiki = wiki;
this.page = page;
this.key = key_(wiki, page);
this.view_bgn = DateAdp_.Now();
} private Xou_history_itm() {}
public byte[] Key() {return key;} private byte[] key;
public byte[] Wiki() {return wiki;} private byte[] wiki;
public byte[] Page() {return page;} private byte[] page;
public int View_count() {return view_count;} private int view_count;
public DateAdp View_bgn() {return view_bgn;} DateAdp view_bgn;
public DateAdp View_end() {return view_end;} DateAdp view_end;
public Object Fld(int idx) {
switch (idx) {
case Fld_key : return key;
case Fld_wiki : return wiki;
case Fld_page : return page;
case Fld_view_count : return view_count;
case Fld_view_bgn : return view_bgn;
case Fld_view_end : return view_end;
default : throw Exc_.new_unhandled(idx);
}
}
public void Tally() {
view_end = view_count == 0 ? view_bgn : DateAdp_.Now();
view_count++;
}
public void Merge(Xou_history_itm merge) {
view_count += merge.View_count();
if (merge.View_bgn().compareTo(view_bgn) < CompareAble_.Same) view_bgn = merge.View_bgn();
if (merge.View_end().compareTo(view_end) > CompareAble_.Same) view_end = merge.View_end();
}
public static Xou_history_itm csv_(byte[] ary, Int_obj_ref pos) {
Xou_history_itm rv = new Xou_history_itm();
rv.view_bgn = Bry_.ReadCsvDte(ary, pos, Bry_.Dlm_fld);
rv.view_end = Bry_.ReadCsvDte(ary, pos, Bry_.Dlm_fld);
rv.view_count = Bry_.ReadCsvInt(ary, pos, Bry_.Dlm_fld);
rv.wiki = Bry_.ReadCsvBry(ary, pos, Bry_.Dlm_fld);
rv.page = Bry_.ReadCsvBry(ary, pos, Bry_.Dlm_row);
rv.key = key_(rv.wiki, rv.page);
return rv;
}
public void Save(Bry_bfr bb) {
bb .Add_dte(view_bgn) .Add_byte(Bry_.Dlm_fld)
.Add_dte(view_end) .Add_byte(Bry_.Dlm_fld)
.Add_int_variable(view_count) .Add_byte(Bry_.Dlm_fld)
.Add(wiki) .Add_byte(Bry_.Dlm_fld)
.Add(page) .Add_byte(Bry_.Dlm_row);
}
public static byte[] key_(byte[] wiki, byte[] page) {return Bry_.Add(wiki, Key_dlm, page);} private static final byte[] Key_dlm = Xoa_consts.Pipe_bry;
public static final byte Fld_key = 0, Fld_wiki = 1, Fld_page = 2, Fld_view_count = 3, Fld_view_bgn = 4, Fld_view_end = 5;
}

View File

@@ -0,0 +1,143 @@
/*
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.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.primitives.*; import gplx.xowa.html.hrefs.*;
public class Xou_history_mgr implements GfoInvkAble {
private final Xou_history_html html_mgr = new Xou_history_html(); private Xou_history_sorter sorter = new Xou_history_sorter().Sort_fld_(Xou_history_itm.Fld_view_end).Ascending_(false);
private final Io_url history_fil;
private Ordered_hash itms = Ordered_hash_.new_bry_();
private boolean load_chk = false;
public Xou_history_mgr(Io_url history_fil) {this.history_fil = history_fil;}
public int Len() {return itms.Count();}
public void Clear() {itms.Clear();}
public Xou_history_itm Get_at(int i) {return (Xou_history_itm)itms.Get_at(i);}
public String Get_at_last() {
if (!load_chk) Load();
int len = itms.Count(); if (len == 0) return String_.new_a7(Xoa_page_.Main_page_bry); // if no history, return Main_page (which should go to home/wiki/Main_page)
Xou_history_itm itm = (Xou_history_itm)itms.Get_at(0);
return String_.new_u8(Bry_.Add(itm.Wiki(), Xoh_href_parser.Href_wiki_bry, itm.Page()));
}
public Xou_history_itm Get_or_null(byte[] wiki, byte[] page) {
if (!load_chk) Load();
byte[] key = Xou_history_itm.key_(wiki, page);
return (Xou_history_itm)itms.Get_by(key);
}
public boolean Has(byte[] wiki, byte[] page) {
if (!load_chk) Load();
byte[] key = Xou_history_itm.key_(wiki, page);
return itms.Has(key);
}
public void Add(Xoae_page page) {
Xoa_url url = page.Url();
Xoa_ttl ttl = page.Ttl();
byte[] page_ttl = null;
List_adp redirect_list = page.Redirected_ttls();
if (redirect_list.Count() > 0) // page was redirected; add src ttl to history, not trg; EX: UK -> United Kingdom; add "UK"; DATE:2014-02-28
page_ttl = page.Redirected_ttls__itm_0();
else {
page_ttl = Bry_.Add(ttl.Ns().Name_db_w_colon(), ttl.Page_txt()); // use ttl.Page_txt() b/c it normalizes space/casing (url.Page_txt does not)
if (url.Args().length > 0)
page_ttl = Bry_.Add(page_ttl, url.Args_all_as_bry());
}
Add(url, ttl, page_ttl);
}
public void Add(Xoa_url url, Xoa_ttl ttl, byte[] page_ttl) {
if (gplx.xowa.users.data.Xoud_history_mgr.Skip_history(ttl)) return;
if (!load_chk) Load();
byte[] key = Xou_history_itm.key_(url.Wiki_bry(), page_ttl);
Xou_history_itm itm = (Xou_history_itm)itms.Get_by(key);
if (itm == null) {
itm = new Xou_history_itm(url.Wiki_bry(), page_ttl);
itms.Add(key, itm);
}
itm.Tally();
}
public void Sort() {itms.Sort_by(sorter);}
public void Load() {
if (load_chk) return;
load_chk = true;
itms.Clear();
Xou_history_itm_srl.Load(Io_mgr.I.LoadFilBry(history_fil), itms);
itms.Sort_by(sorter);
}
public void Save(Xoae_app app) {
if (!load_chk) return; // nothing loaded; nothing to save
int itms_len = itms.Count();
if (itms_len == 0) return; // no items; occurs when history disable;
itms.Sort_by(sorter);
if (itms_len > current_itms_max) itms = Archive(app);
byte[] ary = Xou_history_itm_srl.Save(itms);
Io_mgr.I.SaveFilBry(app.Usere().Fsys_mgr().App_data_history_fil(), ary);
}
public Ordered_hash Archive(Xoae_app app) {
itms.Sort_by(sorter);
int itms_len = itms.Count();
Ordered_hash current_itms = Ordered_hash_.new_bry_();
Ordered_hash archive_itms = Ordered_hash_.new_bry_();
for (int i = 0; i < itms_len; i++) {
Xou_history_itm itm = (Xou_history_itm)itms.Get_at(i);
Ordered_hash itms_hash = (i < current_itms_reset) ? current_itms : archive_itms;
itms_hash.Add(itm.Key(), itm);
}
byte[] ary = Xou_history_itm_srl.Save(archive_itms);
Io_url url = app.Usere().Fsys_mgr().App_data_history_fil().GenNewNameOnly(DateAdp_.Now().XtoStr_fmt_yyyyMMdd_HHmmss_fff());
Io_mgr.I.SaveFilBry(url, ary);
return current_itms;
} private int current_itms_max = 512, current_itms_reset = 256;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_html_grp)) return String_.new_u8(html_mgr.Html_grp().Fmt());
else if (ctx.Match(k, Invk_html_grp_)) html_mgr.Html_grp().Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_html_itm)) return String_.new_u8(html_mgr.Html_itm().Fmt());
else if (ctx.Match(k, Invk_html_itm_)) html_mgr.Html_itm().Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_current_itms_max_)) current_itms_max = m.ReadInt("v");
else if (ctx.Match(k, Invk_current_itms_reset_)) current_itms_reset = m.ReadInt("v");
else return GfoInvkAble_.Rv_unhandled;
return this;
}
public static final String Invk_html_grp = "html_grp", Invk_html_grp_ = "html_grp_", Invk_html_itm = "html_itm", Invk_html_itm_ = "html_itm_", Invk_current_itms_max_ = "current_itms_max_", Invk_current_itms_reset_ = "current_itms_reset_";
public static final byte[] Ttl_name = Bry_.new_a7("XowaPageHistory");
public static final byte[] Ttl_full = Bry_.new_a7("Special:XowaPageHistory");
}
class Xou_history_itm_srl {
public static void Load(byte[] ary, Ordered_hash list) {
try {
list.Clear();
int aryLen = ary.length;
if (aryLen == 0) return; // no file
Int_obj_ref pos = Int_obj_ref.zero_();
while (true) {
if (pos.Val() == aryLen) break;
Xou_history_itm itm = Xou_history_itm.csv_(ary, pos);
byte[] key = itm.Key();
Xou_history_itm existing = (Xou_history_itm)list.Get_by(key);
if (existing == null) // new itm; add
list.Add(itm.Key(), itm);
else // existing itm; update
existing.Merge(itm);
}
}
catch (Exception e) {throw Exc_.new_parse_exc(e, Xou_history_itm.class, String_.new_u8(ary));}
}
public static byte[] Save(Ordered_hash list) {
Bry_bfr bb = Bry_bfr.new_();
int listLen = list.Count();
for (int i = 0; i < listLen; i++)
((Xou_history_itm)list.Get_at(i)).Save(bb);
return bb.Xto_bry();
}
}

View File

@@ -0,0 +1,97 @@
/*
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.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import org.junit.*;
public class Xou_history_mgr_tst {
private Xou_history_mgr_fxt fxt = new Xou_history_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Archive() {
Tfds.Now_enabled_y_(); // NOTE: each DateTime_.Now() advances clock by 1 min; adding a new DateAdp_.Now() anywhere will throw off times on this test; DATE:2014-04-01
fxt.Invk(Xou_history_mgr.Invk_current_itms_max_, 4).Invk(Xou_history_mgr.Invk_current_itms_reset_, 2);
fxt.Add_many("A", "B", "C", "D", "E");
fxt.Save();
fxt.List_tst("E", "D");
fxt.Fil_tst("mem/xowa/user/test_user/app/data/history/20010101_001000.000.csv", String_.Concat_lines_nl
( "20010101 000500.000|20010101 000500.000|1|en.wikipedia.org|C"
, "20010101 000300.000|20010101 000300.000|1|en.wikipedia.org|B"
, "20010101 000100.000|20010101 000100.000|1|en.wikipedia.org|A"
));
}
@Test public void Normalize() {
fxt.Clear();
fxt.Add_many("Category:A_B", "Category:A B", "Category:a B", "Category:_A B_");
fxt.List_tst("Category:A B");
}
@Test public void Args() {
fxt.Clear();
fxt.Add_one("Special:AllPages", "?from=A");
fxt.List_tst("Special:AllPages?from=A");
}
}
class Xou_history_mgr_fxt {
Xoae_app app; Xowe_wiki wiki;
Xou_history_mgr under;
public void Clear() {
if (app == null) {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
under = app.Usere().History_mgr();
}
Io_mgr.I.DeleteDirDeep(Io_url_.new_dir_("mem/xowa/user/test_user/app/data/history/"));
under.Clear();
}
public Xou_history_mgr_fxt Add_many(String... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
String itm = ary[i];
Add_one(itm, null);
}
return this;
}
public Xou_history_mgr_fxt Add_one(String ttl_str, String arg_str) {
byte[] ttl_bry = Bry_.new_u8(ttl_str);
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
Xoae_page page = Xoae_page.test_(wiki, ttl);
page.Revision_data().Modified_on_(DateAdp_.Now());
byte[] url_bry = ttl_bry;
if (arg_str != null) url_bry = Bry_.Add(url_bry, Bry_.new_u8(arg_str));
Xoa_url url = app.Utl__url_parser().Parse(url_bry);
url.Wiki_bry_(wiki.Domain_bry());
page.Url_(url); // set url b/c history_mgr.Add uses url
// page.Url_(Xoa_url.new_(wiki.Key_bry(), url_bry)); // set url b/c history_mgr.Add uses url
under.Add(page);
return this;
}
public Xou_history_mgr_fxt List_tst(String... expd) {
int actl_len = under.Len();
String[] actl = new String[actl_len];
for (int i = 0; i < actl_len; i++) {
Xou_history_itm itm = under.Get_at(i);
actl[i] = String_.new_u8(itm.Page());
}
Tfds.Eq_ary_str(expd, actl);
return this;
}
public Xou_history_mgr_fxt Invk(String key, Object v) {GfoInvkAble_.InvkCmd_val(under, key, v); return this;}
public Xou_history_mgr_fxt Save() {under.Save(app); return this;}
public Xou_history_mgr_fxt Fil_tst(String expd_url, String expd) {
String actl = Io_mgr.I.LoadFilStr(expd_url);
Tfds.Eq_str_lines(expd, actl);
return this;
}
}

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.users.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xou_history_sorter implements gplx.lists.ComparerAble {
public boolean Ascending() {return ascending;} public Xou_history_sorter Ascending_(boolean v) {ascending = v; return this;} private boolean ascending = false;
public int Sort_fld() {return sort_fld;} public Xou_history_sorter Sort_fld_(int v) {sort_fld = v; return this;} private int sort_fld = Xou_history_itm.Fld_view_end;
public int compare(Object lhsObj, Object rhsObj) {
Xou_history_itm lhs = (Xou_history_itm)lhsObj, rhs = (Xou_history_itm)rhsObj;
int comp = CompareAble_.Compare_obj(lhs.Fld(sort_fld), rhs.Fld(sort_fld));
if (!ascending) comp *= -1;
return comp;
}
}

View File

@@ -0,0 +1,113 @@
/*
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.users.prefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.xowa.cfgs.*;
public class Prefs_converter {
private Bry_bfr bfr = Bry_bfr.new_();
private List_adp list = List_adp_.new_();
public void Check(Xoae_app app) {
int options_version = app.Sys_cfg().Options_version();
if (options_version == 1) {
Io_url cfg_dir = app.Usere().Fsys_mgr().App_data_cfg_dir();
Io_url cfg_fil = cfg_dir.GenSubFil("user_system_cfg.gfs");
Io_url trg_fil = cfg_fil.GenNewNameAndExt(gplx.xowa.cfgs.Xoa_cfg_db_txt.File_name);
if (!Io_mgr.I.ExistsFil(trg_fil)) { // do not overwrite file if it is there (i.e.: it's already converted); needed when running in app_mode = cmd (see HACK in Xob_bldr.Run)
String old_str = Io_mgr.I.LoadFilStr_args(cfg_fil).MissingIgnored_(true).Exec();
String new_str = Convert(old_str);
Io_mgr.I.SaveFilStr(trg_fil, new_str);
app.Cfg_mgr().Db_load_txt();
app.Cfg_mgr().Set_by_app("app.setup.dumps.wiki_storage_type", "sqlite");
app.Log_wtr().Log_to_session_fmt("converted options to v2");
}
}
}
public String Convert(String raw) {
list.Clear();
GfoMsg root_msg = gplx.gfs.Gfs_msg_bldr._.ParseToMsg(raw);
int len = root_msg.Subs_count();
for (int i = 0; i < len; i++) {
GfoMsg msg = root_msg.Subs_getAt(i);
Convert_msg(msg, 0);
}
return Convert_to_stage2(list);
}
public String Convert_to_stage2(List_adp list) {
bfr.Add_str_a7("app.cfgs.get('app.sys_cfg.options_version', 'app').val = '2';").Add_byte_nl();
int len = list.Count();
for (int i = 0; i < len; i++) {
Prefs_converter_itm itm = (Prefs_converter_itm)list.Get_at(i);
bfr.Add_str_a7("app.cfgs.get('");
Write_escaped_str(bfr, itm.Key());
bfr.Add_str_a7("', '" + Xoa_cfg_grp_tid.Key_app_str + "'");
bfr.Add_str_a7(").val = '");
Write_escaped_str(bfr, itm.Val());
bfr.Add_str_a7("';\n");
}
return bfr.Xto_str_and_clear();
}
private void Write_escaped_str(Bry_bfr bfr, String str) {
byte[] bry = Bry_.new_u8(str);
int len = bry.length;
for (int i = 0; i < len; i++) {
byte b = bry[i];
if (b == Byte_ascii.Apos)
bfr.Add_byte_repeat(Byte_ascii.Apos, 2);
else
bfr.Add_byte(b);
}
}
private void Convert_msg(GfoMsg m, int depth) {
int subs_len = m.Subs_count();
if (subs_len == 0) {
bfr.Add_byte(Byte_ascii.Dot);
byte[] prop_set_key = Bry_.new_u8(m.Key());
int prop_set_key_len = prop_set_key.length;
if (prop_set_key_len == 0) return; // empty key; return now, else error
if (prop_set_key[prop_set_key_len - 1] != Byte_ascii.Underline) return; // doesn't end with _
bfr.Add_mid(prop_set_key, 0, prop_set_key_len - 1);
Prefs_converter_itm itm = new Prefs_converter_itm();
itm.Key_(bfr.Xto_str_and_clear());
String prop_val = m.Args_getAt(0).Val_to_str_or_empty();
itm.Val_(prop_val);
list.Add(itm);
}
else {
if (depth != 0) bfr.Add_byte(Byte_ascii.Dot);
if (String_.Eq(m.Key(), "scripts")) {bfr.Clear(); return;}
bfr.Add_str(m.Key());
int args_count = m.Args_count();
if (args_count > 0) {
bfr.Add_byte(Byte_ascii.Paren_bgn);
for (int i = 0; i < args_count; i++) {
if (i != 0) bfr.Add_byte(Byte_ascii.Comma);
KeyVal kv = m.Args_getAt(i);
bfr.Add_byte(Byte_ascii.Quote);
bfr.Add_str(kv.Val_to_str_or_empty());
bfr.Add_byte(Byte_ascii.Quote);
}
bfr.Add_byte(Byte_ascii.Paren_end);
}
Convert_msg(m.Subs_getAt(0), depth + 1);
}
}
public static final Prefs_converter _ = new Prefs_converter(); Prefs_converter() {}
}
class Prefs_converter_itm {
public String Key() {return key;} public void Key_(String v) {this.key = v;} private String key;
public String Val() {return val;} public void Val_(String v) {this.val = v;} private String val;
}

View File

@@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.prefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import org.junit.*;
public class Prefs_converter_tst {
@Before public void init() {} Prefs_converter_fxt fxt = new Prefs_converter_fxt();
@Test public void Basic() {
fxt.Test_convert(String_.Concat_lines_nl
( "app.scripts.txns.get('user.prefs.general').version_('0.7.2.0').bgn();"
, "a.b.c_('d');"
, "e.f.g_h_(1);"
, "i.j('k').l_(2);"
), String_.Concat_lines_nl
( "app.cfgs.get('app.sys_cfg.options_version', 'app').val = '2';"
, "app.cfgs.get('a.b.c', 'app').val = 'd';"
, "app.cfgs.get('e.f.g_h', 'app').val = '1';"
, "app.cfgs.get('i.j(\"k\").l', 'app').val = '2';"
));
}
}
class Prefs_converter_fxt {
Prefs_converter converter = Prefs_converter._;
public void Test_convert(String raw, String expd) {
String actl = converter.Convert(raw);
Tfds.Eq_str_lines(expd, actl);
}
public void Parse(String raw_str) {
byte[] raw_bry = Bry_.new_u8(raw_str);
int bgn_pos = Bry_finder.Find_fwd(raw_bry, Byte_ascii.Paren_bgn);
if (bgn_pos == Bry_.NotFound) throw Exc_.new_("unable to find paren_bgn", "raw", raw_str);
int end_pos = Bry_finder.Find_fwd(raw_bry, Byte_ascii.Paren_end, bgn_pos);
if (end_pos == Bry_.NotFound) throw Exc_.new_("unable to find paren_end", "raw", raw_str);
raw_bry = Bry_.Mid(raw_bry, bgn_pos, end_pos);
int len = raw_bry.length;
for (int i = 0; i < len; i++) {
byte[] c = gplx.intl.Utf8_.Get_char_at_pos_as_bry(raw_bry, i);
if (c.length == 1) {
switch (c[0]) {
case Byte_ascii.Dash:
break;
case Byte_ascii.Pipe:
break;
}
}
}
}
}

View File

@@ -0,0 +1,124 @@
/*
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.users.prefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.html.*;
class Prefs_html_wtr {
public Prefs_html_wtr(Prefs_mgr prefs_mgr) {this.prefs_mgr = prefs_mgr;} Prefs_mgr prefs_mgr; Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
public void Write(Bry_bfr bfr, byte[] src, Html_nde hnde, int prop_idx, byte[] trg_type, byte[] trg_val) {
Object prop_val = Eval_prop_get(hnde);
byte elem_type = Prefs_mgr.Elem_tid_tid_of(hnde);
bfr.Add_mid(src, hnde.Tag_lhs_bgn(), hnde.Tag_lhs_end() - 1);
switch (elem_type) {
case Prefs_mgr.Elem_tid_input_text: this.Write_input(bfr, hnde, prop_idx, prop_val); break;
case Prefs_mgr.Elem_tid_select: this.Write_select(bfr, hnde, prop_idx, prop_val); break;
case Prefs_mgr.Elem_tid_input_xowa_io: this.Write_io(bfr, hnde, prop_idx, prop_val); return;
case Prefs_mgr.Elem_tid_input_checkbox: this.Write_checkbox(bfr, hnde, prop_idx, prop_val); break;
case Prefs_mgr.Elem_tid_textarea: this.Write_textarea(bfr, hnde, prop_idx, prop_val); break;
}
bfr.Add_mid(src, hnde.Tag_rhs_bgn(), hnde.Tag_rhs_end());
}
private void Write_input(Bry_bfr bfr, Html_nde hnde, int prop_idx, Object prop_val) {
Write__id(bfr, prop_idx); // " id='xowa_prop_123'"
Write__value_atr(bfr, prop_val); // " value='abc'"
Write__nde_end(bfr); // ">"
}
private void Write_textarea(Bry_bfr bfr, Html_nde hnde, int prop_idx, Object prop_val) {
Write__id(bfr, prop_idx); // " id='xowa_prop_123'"
Write__nde_end(bfr); // ">"
bfr.Add(Html_utl.Escape_html_as_bry(Bry_.new_u8(Object_.Xto_str_strict_or_empty(prop_val))));
// "abcde"
}
private void Write_checkbox(Bry_bfr bfr, Html_nde hnde, int prop_idx, Object prop_val) {
Write__id(bfr, prop_idx); // " id='xowa_prop_123'"
boolean prop_val_is_true = String_.Eq((String)prop_val, "y");
if (prop_val_is_true)
bfr.Add(Atr_stub_checked); // " checked='checked'"
Write__nde_end(bfr); // ">"
}
private void Write_select(Bry_bfr bfr, Html_nde hnde, int prop_idx, Object prop_val) {
KeyVal[] options_list = Get_select_options(hnde);
Write__id(bfr, prop_idx); // " id='xowa_prop_123'"
Write__nde_end(bfr); // ">"
bfr.Add_byte_nl(); // "\n"
int len = options_list.length;
for (int i = 0; i < len; i++) {
KeyVal option = options_list[i];
bfr.Add(Nde_stub_option_bgn); // " <option value='"
bfr.Add_str(option.Key()); // "option_key"
bfr.Add_byte(Byte_ascii.Apos); // "'"
if (String_.Eq(Object_.Xto_str_strict_or_empty(prop_val), option.Key()))
bfr.Add_str_a7(" selected='selected'"); // " selected='selected'"
bfr.Add_byte(Byte_ascii.Gt); // ">"
bfr.Add_str(option.Val_to_str_or_empty()); // "option_text"
bfr.Add(Nde_stub_option_end); // "</option>\n"
}
}
private void Write_io(Bry_bfr bfr, Html_nde hnde, int prop_idx, Object prop_val) {
Write__id(bfr, prop_idx); // " id='xowa_prop_123'"
Write__value_atr(bfr, prop_val); // " value='abc'"
Write__nde_end(bfr); // ">"
Write__tag_end(bfr, hnde); // "</input>"
Write_io_btn(bfr, hnde, prop_idx);
}
private void Write_io_btn(Bry_bfr bfr, Html_nde hnde, int prop_idx) {
bfr.Add_str_a7("<button id='xowa_prop_").Add_int_variable(prop_idx).Add_str("_io").Add_byte(Byte_ascii.Apos);
bfr.Add_str_a7(" class='options_button' onclick='xowa_io_select(\"file\", \"");
bfr.Add_str_a7("xowa_prop_").Add_int_variable(prop_idx);
byte[] xowa_io_msg = hnde.Atrs_val_by_key_bry(Bry_.new_a7("xowa_io_msg"));
if (xowa_io_msg == null) xowa_io_msg = Bry_.new_a7("Please select a file.");
bfr.Add_str_a7("\", \"").Add(xowa_io_msg).Add_str("\");'>");
bfr.Add_str_a7("...</button>").Add_byte_nl();
}
private static final byte[] Atr_key_xowa_prop_list = Bry_.new_a7("xowa_prop_list")
, Atr_stub_id = Bry_.new_a7(" id='xowa_prop_")
, Atr_stub_value = Bry_.new_a7(" value='")
, Atr_stub_checked = Bry_.new_a7(" checked='checked'")
, Nde_stub_option_bgn = Bry_.new_a7(" <option value='")
, Nde_stub_option_end = Bry_.new_a7("</option>\n")
;
Object Eval_prop_get(Html_nde hnde) {
byte[] cmd = hnde.Atrs_val_by_key_bry(Prefs_mgr.Bry_prop);
if (cmd == null)
cmd = hnde.Atrs_val_by_key_bry(Prefs_mgr.Bry_prop_get);
tmp_bfr.Add(cmd).Add_byte(Byte_ascii.Semic);
try {return prefs_mgr.Eval(tmp_bfr.Xto_bry_and_clear());}
catch (Exception e) {return Err_.Message_gplx_brief(e);}
}
KeyVal[] Get_select_options(Html_nde hnde) {
byte[] options_list_key = hnde.Atrs_val_by_key_bry(Atr_key_xowa_prop_list);
tmp_bfr.Add(options_list_key).Add_byte(Byte_ascii.Semic);
try {return (KeyVal[])prefs_mgr.Eval(tmp_bfr.Xto_bry_and_clear());}
catch (Exception e) {Exc_.Noop(e); return KeyVal_.Ary_empty;}
}
private void Write__nde_end(Bry_bfr bfr) {bfr.Add_byte(Byte_ascii.Gt);}
private void Write__id(Bry_bfr bfr, int prop_idx) {
bfr.Add(Atr_stub_id); // " id='xowa_prop_"
bfr.Add_int_variable(prop_idx); // "123"
bfr.Add_byte(Byte_ascii.Apos); // "'"
}
private void Write__value_atr(Bry_bfr bfr, Object prop_val) {
bfr.Add(Atr_stub_value); // " value='"
bfr.Add(Html_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, Object_.Xto_str_strict_or_empty(prop_val)));
// "abcde"
bfr.Add_byte(Byte_ascii.Apos); // "'"
}
private void Write__tag_end(Bry_bfr bfr, Html_nde hnde) {
bfr.Add_mid(hnde.Src(), hnde.Tag_rhs_bgn(), hnde.Tag_rhs_end()); // "</input>"
// bfr.Add_byte_nl(); // "\n"; NOTE: do not write \n; will move to next line; DATE:2013-10-16
}
}

View File

@@ -0,0 +1,155 @@
/*
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.users.prefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.primitives.*; import gplx.html.*; import gplx.gfui.*;
import gplx.xowa.gui.views.*;
public class Prefs_mgr implements GfoInvkAble {
public Prefs_mgr(Xoae_app app) {
this.app = app;
atrs_hash = Hash_adp_bry.cs_();
atrs_hash.Add(Bry_prop, Byte_obj_val.new_(Tid_prop));
atrs_hash.Add(Bry_prop_get, Byte_obj_val.new_(Tid_prop_get));
atrs_hash.Add(Bry_prop_set, Byte_obj_val.new_(Tid_prop_set));
html_wtr = new Prefs_html_wtr(this);
} private Xoae_app app; private Hash_adp_bry atrs_hash; private Html_parser html_rdr = new Html_parser(); private Prefs_html_wtr html_wtr;
private Prefs_trg_mgr option_trgs_mgr = new Prefs_trg_mgr();
public void Html_box_mok_(Xog_html_itm v) {this.html_box_mok = v;} private Xog_html_itm html_box_mok;
public byte[] Props_get(byte[] src) {
// option_trgs_mgr.Init(app.Gui_mgr().Browser_win().Active_page().Url());
if (props_get_fmtr == null) props_get_fmtr = Bry_fmtr.keys_().Eval_mgr_(app.Gfs_mgr().Eval_mgr());
src = this.Parse_wikitext_to_html(src);
props_get_fmtr.Fmt_(src);
Bry_bfr bfr = Bry_bfr.new_();
try {src = props_get_fmtr.Fmt_(src).Bld_bry_none(bfr);}
catch (Exception e) {src = Bry_.Add(src, Bry_.new_u8(Err_.Message_gplx_brief(e)));}
Html_nde[] hndes = html_rdr.Parse_as_ary(src);
hndes = Html_selecter.Select(src, hndes, atrs_hash);
int pos = 0;
int len = hndes.length;
for (int i = 0; i < len; i++) {
Html_nde hnde = hndes[i];
bfr.Add_mid(src, pos, hnde.Tag_lhs_bgn());
html_wtr.Write(bfr, src, hnde, i, option_trgs_mgr.Trg_type(), option_trgs_mgr.Trg_val());
pos = hnde.Tag_rhs_end();
}
bfr.Add_mid(src, pos, src.length);
return bfr.Xto_bry_and_clear();
} private Bry_fmtr props_get_fmtr;
private void Props_set_and_reload() {
Xoae_page page = app.Gui_mgr().Browser_win().Active_page();
Props_set(page.Data_raw());
page.Wikie().ParsePage_root(page, true); // reparse in order to save new values to root; needed for history and going back / fwd; DATE:2014-02-07
app.Api_root().Gui().Page().View().Reload(); // force reload to update page; needed for language; DATE:2014-05-26
app.Usr_dlg().Prog_direct("options saved (" + DateAdp_.Now().XtoStr_fmt("HH:mm:ss") + ")");
}
public void Props_set(byte[] src) {
src = Bry_.Replace(src, Bry_.new_a7("<xowa_cmd>"), Bry_.new_a7("&lt;xowa_cmd>"));
src = Bry_.Replace(src, Bry_.new_a7("</xowa_cmd>"), Bry_.new_a7("&lt;/xowa_cmd>"));
src = this.Parse_wikitext_to_html(src);
Html_nde[] hndes = html_rdr.Parse_as_ary(src);
hndes = Html_selecter.Select(src, hndes, atrs_hash);
int len = hndes.length;
boolean tidy_enabled = app.Html_mgr().Tidy_mgr().Enabled();
Bry_bfr cmd_bfr = Bry_bfr.reset_(255);
for (int i = 0; i < len; i++) {
Html_nde hnde = hndes[i];
Props_set_by_hnde(cmd_bfr, src, hnde, i, tidy_enabled);
}
app.Cfg_mgr().Db_save_txt();
}
private void Props_set_by_hnde(Bry_bfr cmd_bfr, byte[] src, Html_nde hnde, int i, boolean tidy_enabled) {
byte[] eval_code = hnde.Atrs_val_by_key_bry(Bry_prop);
if (eval_code == null) eval_code = hnde.Atrs_val_by_key_bry(Bry_prop_set);
String hnde_val = null;
String hnde_key = "xowa_prop_" + Int_.Xto_str(i);
Xog_html_itm html_itm = html_box_mok == null ? app.Gui_mgr().Browser_win().Active_tab().Html_itm() : html_box_mok; // TEST:
byte elem_tid = Prefs_mgr.Elem_tid_tid_of(hnde);
switch (elem_tid) {
case Elem_tid_input_text:
case Elem_tid_input_xowa_io:
case Elem_tid_select: hnde_val = html_itm.Html_elem_atr_get_str(hnde_key, gplx.gfui.Gfui_html.Atr_value); break;
case Elem_tid_textarea: hnde_val = Html_utl.Unescape_as_str(html_itm.Html_elem_atr_get_str(hnde_key, gplx.gfui.Gfui_html.Atr_value)); break;
case Elem_tid_input_checkbox: hnde_val = html_itm.Html_elem_atr_get_bool(hnde_key, "checked") ? "y" : "n"; break;
}
byte[] get_cmd = Props_get(eval_code);
Object get_val = Eval_run(Bry_.Add(get_cmd, Byte_ascii.Semic));
String get_str = Object_.Xto_str_strict_or_null_mark(get_val);
hnde_val = Scrub_tidy_trailing_nl_in_textarea(tidy_enabled, elem_tid, hnde_val);
get_str = Scrub_tidy_trailing_nl_in_textarea(tidy_enabled, elem_tid, get_str);
if (String_.Eq(get_str, hnde_val)) return;
try {app.Cfg_mgr().Set_by_app(String_.new_u8(get_cmd), hnde_val);}
catch (Exception e) {app.Usr_dlg().Warn_many("", "", "pref update failed: code=~{0} err=~{1}", String_.new_u8(eval_code), Err_.Message_gplx_brief(e));}
}
private Object Eval_run(byte[] cmd) {
try {return Eval(cmd);}
catch (Exception e) {Exc_.Noop(e); return null;}
}
private byte[] Parse_wikitext_to_html(byte[] src) {
Xowe_wiki wiki = app.Usere().Wiki(); // NOTE: this limits prefs to home_wiki only
Xop_root_tkn root = new Xop_root_tkn();
Xop_ctx ctx = Xop_ctx.new_(wiki); // NOTE: always create new ctx; do not reuse existing, else popup will clear out existing page's prefs; DATE:2015-04-29
wiki.Parser().Parse_text_to_wdom(root, ctx, ctx.Tkn_mkr(), src, 0);
return root.Data_mid();
}
public Object Eval(byte[] code) {return app.Gfs_mgr().Run_str(String_.new_a7(code));}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_exec_get)) return Props_get(m.ReadBry("v"));
else if (ctx.Match(k, Invk_save)) Props_set_and_reload();
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_exec_get = "exec_get", Invk_save = "save";
private static final byte Tid_prop = 0, Tid_prop_get = 1, Tid_prop_set = 2;
public static final byte[] Bry_prop = Bry_.new_a7("xowa_prop"), Bry_prop_get = Bry_.new_a7("xowa_prop_get"), Bry_prop_set = Bry_.new_a7("xowa_prop_set"), Bry_id = Bry_.new_a7("id");
public static byte Elem_tid_tid_of(Html_nde hnde) {
byte[] elem_name = Bry_.Mid(hnde.Src(), hnde.Name_bgn(), hnde.Name_end());
if (Bry_.Eq(elem_name, Nde_textarea)) return Elem_tid_textarea;
else if (Bry_.Eq(elem_name, Nde_select)) return Elem_tid_select;
else if (Bry_.Eq(elem_name, Nde_input)) {
byte[] input_type = hnde.Atrs_val_by_key_bry(Input_type);
if (input_type == null) return Elem_tid_input_text;// treat <input /> as <input type='text'/>
if (Bry_.Eq(input_type, Type_text)) return Elem_tid_input_text;
else if (Bry_.Eq(input_type, Type_checkbox)) return Elem_tid_input_checkbox;
else if (Bry_.Eq(input_type, Type_combo)) return Elem_tid_input_combo;
else if (Bry_.Eq(input_type, Type_xowa_io)) return Elem_tid_input_xowa_io;
else return Elem_tid_null;
}
else return Elem_tid_null;
} static final byte[] Input_type = Bry_.new_a7("type"), Nde_input = Bry_.new_a7("input"), Nde_textarea = Bry_.new_a7("textarea"), Nde_select = Bry_.new_a7("select"), Type_text = Bry_.new_a7("text"), Type_checkbox = Bry_.new_a7("checkbox"), Type_combo = Bry_.new_a7("xowa_combo"), Type_xowa_io = Bry_.new_a7("xowa_io");
public static String Scrub_tidy_trailing_nl_in_textarea(boolean tidy_enabled, byte elem_tid, String val) {
return // if tidy_enabled and text_area and ends with \n, then remove \n; DATE:2014-06-21
( tidy_enabled
&& elem_tid == Elem_tid_textarea
&& String_.Has_at_end(val, "\n")
)
? String_.MidByLen(val, 0, String_.Len(val) - 1)
: val
;
}
public static final byte Elem_tid_null = 0, Elem_tid_input_text = 1, Elem_tid_textarea = 2, Elem_tid_input_checkbox = 3, Elem_tid_select = 4, Elem_tid_input_combo = 5, Elem_tid_input_xowa_io = 6;
}
class Prefs_trg_mgr {
private Xoa_url_arg_hash arg_hash = new Xoa_url_arg_hash();
public byte[] Trg_type() {return trg_type;} private byte[] trg_type;
public byte[] Trg_val() {return trg_val;} private byte[] trg_val;
public void Init(Xoa_url url) {
arg_hash.Load(url);
trg_type = arg_hash.Get_val_bry_or(Prefs_trg_mgr.Arg_option_trg_type_bry, null);
trg_val = arg_hash.Get_val_bry_or(Prefs_trg_mgr.Arg_option_trg_val_bry, null);
}
public static final byte[] Arg_option_trg_type_bry = Bry_.new_a7("option_trg_type"), Arg_option_trg_val_bry = Bry_.new_a7("option_trg_val");
}

View File

@@ -0,0 +1,184 @@
/*
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.users.prefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import org.junit.*;
import gplx.gfui.*; import gplx.xowa.apps.*;
import gplx.xowa.gui.views.*;
public class Prefs_mgr_tst {
private Prefs_mgr_fxt fxt = new Prefs_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Get_basic_pass() {
fxt.Exec_get("<input xowa_prop='app.user.name'></input> text", "<input xowa_prop='app.user.name' id='xowa_prop_0' value='test_user'></input> text");
}
@Test public void Get_basic_fail() {
fxt.Exec_get("<input xowa_prop='fail.prop'></input>", "<input xowa_prop='fail.prop' id='xowa_prop_0' value='Error'></input>");
}
@Test public void Get_eval_pass() {
fxt.Exec_get("~{<>app.user.name;<>}", "test_user");
}
@Test public void Get_eval_fail() {
fxt.Exec_get_has("~{<>fail.prop;<>}", "~{<>fail.prop;<>}[err 0] key not found: key=fail");
}
@Test public void Set() {
fxt.Init_elem_atr_val("xowa_prop_0", "abc");
fxt.Test_set("<input xowa_prop='app.gui.html.auto_focus_id' id='xowa_prop_0'>abc</input>");
Tfds.Eq("abc", fxt.App().Gui_mgr().Html_mgr().Auto_focus_id());
}
@Test public void Get_checkbox() {
fxt.App().File_mgr().Wmf_mgr().Enabled_(true);
fxt.Exec_get("a <input type='checkbox' xowa_prop='app.files.download.enabled'></input> b", "a <input type='checkbox' xowa_prop='app.files.download.enabled' id='xowa_prop_0' checked='checked'></input> b");
fxt.App().File_mgr().Wmf_mgr().Enabled_(false);
fxt.Exec_get("a <input type='checkbox' xowa_prop='app.files.download.enabled'></input> b", "a <input type='checkbox' xowa_prop='app.files.download.enabled' id='xowa_prop_0'></input> b");
}
@Test public void Set_checkbox() {
fxt.Init_elem_atr_checked("xowa_prop_0", "true");
fxt.App().File_mgr().Wmf_mgr().Enabled_(false);
fxt.Test_set("<input type='checkbox' xowa_prop='app.files.download.enabled' checked='checked' id='xowa_prop_0'></input>");
Tfds.Eq(true, fxt.App().File_mgr().Wmf_mgr().Enabled());
fxt.Init_elem_atr_checked("xowa_prop_0", "false");
fxt.Test_set("<input type='checkbox' xowa_prop='app.files.download.enabled' id='xowa_prop_0'></input>");
Tfds.Eq(false, fxt.App().File_mgr().Wmf_mgr().Enabled());
}
@Test public void Get_textarea() {
fxt.Exec_get("<textarea xowa_prop='app.user.name'></textarea>", "<textarea xowa_prop='app.user.name' id='xowa_prop_0'>test_user</textarea>");
}
@Test public void Get_textarea_escaped() {
fxt.App().Api_root().Test_str_("<b>a</b>");
fxt.Exec_get("<textarea xowa_prop='app.api.test_str'></textarea>", "<textarea xowa_prop='app.api.test_str' id='xowa_prop_0'>&lt;b&gt;a&lt;/b&gt;</textarea>");
}
@Test public void Set_textarea() {
fxt.Init_elem_atr_val("xowa_prop_0", "abc");
fxt.Test_set("<textarea xowa_prop='app.gui.html.auto_focus_id' id='xowa_prop_0'>abc</textarea>");
Tfds.Eq("abc", fxt.App().Gui_mgr().Html_mgr().Auto_focus_id());
}
@Test public void Set_textarea_escaped() {
fxt.Init_elem_atr_val("xowa_prop_0", "&lt;b&gt;a&lt;/b&gt;");
fxt.Test_set("<textarea xowa_prop='app.gui.html.auto_focus_id' id='xowa_prop_0'>&lt;b&gt;a&lt;/b&gt;</textarea>");
Tfds.Eq("<b>a</b>", fxt.App().Gui_mgr().Html_mgr().Auto_focus_id());
}
@Test public void Get_select() {
fxt.Exec_get
( "<select xowa_prop='app.files.math.renderer' xowa_prop_list='app.files.math.renderer_list'></select>", String_.Concat_lines_nl
( "<select xowa_prop='app.files.math.renderer' xowa_prop_list='app.files.math.renderer_list' id='xowa_prop_0'>"
, " <option value='mathjax' selected='selected'>MathJax</option>"
, " <option value='latex'>LaTeX</option>"
, "</select>"
));
}
@Test public void Set_select() {
fxt.Init_elem_atr_val("xowa_prop_0", "mathjax");
fxt.Test_set("<select xowa_prop='app.files.math.renderer' xowa_prop_list='app.files.math.renderer_list'></select>");
Tfds.Eq(true, fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax());
fxt.Init_elem_atr_val("xowa_prop_0", "latex");
fxt.Test_set("<select xowa_prop='app.files.math.renderer' xowa_prop_list='app.files.math.renderer_list'></select>");
Tfds.Eq(false, fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax());
}
@Test public void Get_io_file() {
fxt.Exec_get
( "<input type='xowa_io' xowa_prop='app.fsys.apps.media' xowa_io_msg='Select program for Web Browser'></input>", String_.Concat
( "<input type='xowa_io' xowa_prop='app.fsys.apps.media' xowa_io_msg='Select program for Web Browser' id='xowa_prop_0' value=''></input>"
, "<button id='xowa_prop_0_io' class='options_button' onclick='xowa_io_select(\"file\", \"xowa_prop_0\", \"Select program for Web Browser\");'>...</button>"
));
}
@Test public void Scrub_tidy_trailing_nl_in_textarea() {
fxt.Test_Scrub_tidy_trailing_nl_in_textarea(Bool_.Y, Bool_.Y, "a\n", "a");
fxt.Test_Scrub_tidy_trailing_nl_in_textarea(Bool_.Y, Bool_.Y, "a\n\n", "a\n");
fxt.Test_Scrub_tidy_trailing_nl_in_textarea(Bool_.Y, Bool_.Y, "", "");
fxt.Test_Scrub_tidy_trailing_nl_in_textarea(Bool_.N, Bool_.N, "a\n", "a\n");
fxt.Test_Scrub_tidy_trailing_nl_in_textarea(Bool_.N, Bool_.Y, "a\n", "a\n");
fxt.Test_Scrub_tidy_trailing_nl_in_textarea(Bool_.Y, Bool_.N, "a\n", "a\n");
}
@Test public void Ref() {// PURPOSE: references were duplicating; DATE:2015-05-16
fxt.Parser_fxt().Test_html_full_str
( String_.Concat_lines_nl_skip_last
( "<xowa_cmd>"
, "app.user.prefs.exec_get("
, "<:['"
, "<ref name='a'/>"
, "<references>"
, "<ref name='a'>b</ref>"
, "']:>"
, ");"
, "</xowa_cmd>"
), String_.Concat_lines_nl_skip_last
( "<sup id=\"cite_ref-a_0-0\" class=\"reference\"><a href=\"#cite_note-a-0\">[1]</a></sup>"
, "<ol class=\"references\">"
, "<li id=\"cite_note-a-0\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-a_0-0\">^</a></span> <span class=\"reference-text\">b</span></li>"
, "</ol>"
)
);
// ( "<ref name='a'><references><ref name='a'>a1</ref></references>", String_.Concat
// ( "<input type='xowa_io' xowa_prop='app.fsys.apps.media' xowa_io_msg='Select program for Web Browser' id='xowa_prop_0' value=''></input>"
// , "<button id='xowa_prop_0_io' class='options_button' onclick='xowa_io_select(\"file\", \"xowa_prop_0\", \"Select program for Web Browser\");'>...</button>"
// ));
}
}
class Prefs_mgr_fxt {
public Xoae_app App() {return app;} private Xoae_app app;
private Prefs_mgr prefs_mgr; private Gfui_html_mok html_box;
public void Clear() {
if (app == null) {
GfsCore._.Clear(); // NOTE: clear GfsCore, else Props test will fail for mass run
Xoa_gfs_mgr.Msg_parser_init();
app = Xoa_app_fxt.app_();
prefs_mgr = new Prefs_mgr(app);
html_box = new Gfui_html_mok();
prefs_mgr.Html_box_mok_(html_box);
}
}
public Xop_fxt Parser_fxt() {return new Xop_fxt(app, app.Usere().Wiki());}
public Prefs_mgr_fxt Init_elem_atr_val(String elem_id, String atr_val) {
html_box.Html_elem_atr_add(elem_id, gplx.gfui.Gfui_html.Atr_value, atr_val);
return this;
}
public Prefs_mgr_fxt Init_elem_atr_checked(String elem_id, String v) {
html_box.Html_elem_atr_add(elem_id, "checked", v);
return this;
}
public Prefs_mgr_fxt Init_elem_atr_innerHtml(String elem_id, String v) {
html_box.Html_elem_atr_add(elem_id, gplx.gfui.Gfui_html.Atr_innerHTML, v);
return this;
}
public Prefs_mgr_fxt Exec_get(String src_str, String expd) {
String actl = String_.new_u8(prefs_mgr.Props_get(Bry_.new_u8(src_str)));
Tfds.Eq_str_lines(expd, actl);
return this;
}
public Prefs_mgr_fxt Exec_get_has(String src_str, String expd) {
String actl = String_.new_u8(prefs_mgr.Props_get(Bry_.new_u8(src_str)));
Tfds.Eq_true(String_.Has_at_bgn(actl, expd));
return this;
}
public Prefs_mgr_fxt Test_set(String src_str) {
prefs_mgr.Props_set(Bry_.new_u8(src_str));
return this;
}
public void Test_Scrub_tidy_trailing_nl_in_textarea(boolean tidy_enabled, boolean elem_is_textarea, String val, String expd) {
String actl = Prefs_mgr.Scrub_tidy_trailing_nl_in_textarea(tidy_enabled, elem_is_textarea ? Prefs_mgr.Elem_tid_textarea : Prefs_mgr.Elem_tid_input_text, val);
Tfds.Eq(expd, actl);
}
}
class Gfui_html_mok extends Xog_html_itm { private Hash_adp elem_atrs = Hash_adp_.new_();
public void Html_elem_atr_add(String elem_id, String atr_key, Object atr_val) {elem_atrs.Add_if_dupe_use_nth(elem_id + "." + atr_key, atr_val);}
@Override public String Html_elem_atr_get_str(String id, String atr_key) {
return (String)elem_atrs.Get_by(id + "." + atr_key);
}
@Override public boolean Html_elem_atr_get_bool(String id, String atr_key) {
return Bool_.parse_((String)elem_atrs.Get_by(id + "." + atr_key));
}
}

View File

@@ -0,0 +1,47 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.users.prefs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Prefs_rename_mgr {
private List_adp list = List_adp_.new_();
public Prefs_rename_mgr() {
List_add(list, "app.cfgs.get('app.gui.html.portal.wikis.visible', 'app').val", "app.cfgs.get('xowa.api.html.page.toggles.get(''offline-wikis'').visible', 'app').val");
}
public boolean Check(Io_url url) {
String cur_str = Io_mgr.I.LoadFilStr_args(url).MissingIgnored_().Exec();
boolean cur_str_changed = false;
int list_len = list.Count();
for (int i = 0; i < list_len; ++i) {
Prefs_rename_itm itm = (Prefs_rename_itm)list.Get_at(i);
if (String_.Has(cur_str, itm.Src())) {
cur_str_changed = true;
cur_str = String_.Replace(cur_str, itm.Src(), itm.Trg());
Gfo_usr_dlg_.I.Log_many("", "", "cfg.replace: src=~{src} trg = ~{trg}", itm.Src(), itm.Trg());
}
}
if (cur_str_changed)
Io_mgr.I.SaveFilStr(url, cur_str);
return cur_str_changed;
}
private static void List_add(List_adp list, String src, String trg) {list.Add(new Prefs_rename_itm(src, trg));}
public static final Prefs_rename_mgr _ = new Prefs_rename_mgr();
}
class Prefs_rename_itm {
public Prefs_rename_itm(String src, String trg) {this.src = src; this.trg = trg;}
public String Src() {return src;} private String src;
public String Trg() {return trg;} private String trg;
}

View File

@@ -0,0 +1,79 @@
/*
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.users.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
class Xofs_url_itm {
public boolean Tid_is_xowa() {return tid_is_xowa;} public void Tid_is_xowa_(boolean v) {tid_is_xowa = v;} private boolean tid_is_xowa = true;
public String Raw() {return raw;} public void Raw_(String v) {raw = v;} private String raw;
public String Url() {return url;} public void Url_(String v) {url = v;} private String url;
}
class Xofs_url_itm_parser {
private static final byte[] Xowa_fs_protocol = Bry_.new_a7("xowa-fs://");
private static final int Xowa_fa_protocol_len = Xowa_fs_protocol.length;
private Bry_bfr url_bfr = Bry_bfr.reset_(16);
private Hash_adp_bry names = Hash_adp_bry.cs_();
public byte Dir_spr() {return dir_spr;} public void Dir_spr_(byte v) {dir_spr = v;} private byte dir_spr = Op_sys.Cur().Fsys_dir_spr_byte();
public void Names_add(String key_str, String val_str) {
byte[] key_bry = Bry_.new_u8(key_str);
byte[] val_bry = Bry_.new_u8(val_str);
names.Add_if_dupe_use_nth(key_bry, val_bry);
}
public void Parse(Xofs_url_itm itm, String raw_str) {
itm.Raw_(raw_str);
byte[] raw = Bry_.new_u8(raw_str);
if (!Bry_.Has_at_bgn(raw, Xowa_fs_protocol)) { // raw does not start with "xowa-fs://"; mark as custom str and exit
itm.Tid_is_xowa_(false);
itm.Url_(raw_str);
return;
}
itm.Tid_is_xowa_(true);
url_bfr.Clear();
int raw_len = raw.length;
for (int i = Xowa_fa_protocol_len; i < raw_len; ++i) {
byte b = raw[i];
switch (b) {
case Byte_ascii.Slash: // "xowa-fs://" defines "/" as dir separator
url_bfr.Add_byte(dir_spr); // swap out to cur os dir_spr
break;
case Byte_ascii.Tilde: // "xowa-fs://" defines "~{" as swap symbol
int remaining = raw_len - i - 1; // -1
if (remaining > 0 && raw[i + 1] == Byte_ascii.Curly_bgn) { // "~{"
if (remaining > 2 && raw[i+2] == Byte_ascii.Tilde && raw[i+3] == Byte_ascii.Curly_bgn) { // "~{~{" -> "~{"
url_bfr.Add_byte(Byte_ascii.Tilde).Add_byte(Byte_ascii.Curly_bgn);
i += 3;
}
else {
int name_bgn = i + 2; // skip "~{"
int name_end = Bry_finder.Find_fwd(raw, Byte_ascii.Curly_end, name_bgn);
byte[] name = (byte[])names.Get_by_mid(raw, name_bgn, name_end);
if (name == null) throw Exc_.new_("name not found", "raw", raw_str, "name", String_.new_u8(raw, name_bgn, name_end));
url_bfr.Add(name);
i = name_end;
}
}
else {
url_bfr.Add_byte(b);
}
break;
default:
url_bfr.Add_byte(b);
break;
}
}
itm.Url_(url_bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,53 @@
/*
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.users.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import org.junit.*;
public class Xofs_url_itm_parser_tst {
@Before public void init() {fxt.Clear();} private Xofs_url_itm_parser_fxt fxt = new Xofs_url_itm_parser_fxt();
@Test public void Custom() {fxt.Test_parse_custom("/xowa/wiki/en.wikipedia.org/");}
@Test public void Lnx() {fxt.Init_dir_spr_lnx().Init_name("xowa", "/xowa") .Test_parse("xowa-fs://~{xowa}/bin/any/", "/xowa/bin/any/");}
@Test public void Wnt() {fxt.Init_dir_spr_wnt().Init_name("xowa", "C:\\xowa") .Test_parse("xowa-fs://~{xowa}/bin/any/", "C:\\xowa\\bin\\any\\");}
@Test public void Outliers() {
fxt.Init_name("xowa", "/xowa");
fxt.Test_parse("xowa-fs://ab" , "ab"); // no subst
fxt.Test_parse("xowa-fs://a~b" , "a~b"); // tilde
fxt.Test_parse("xowa-fs://a~{~{b" , "a~{b"); // escape
fxt.Test_parse("xowa-fs://ab~" , "ab~"); // eos
fxt.Test_parse("xowa-fs://ab~{~{" , "ab~{"); // eos
}
}
class Xofs_url_itm_parser_fxt {
private Xofs_url_itm_parser parser;
private Xofs_url_itm itm = new Xofs_url_itm();
public void Clear() {
parser = new Xofs_url_itm_parser();
}
public Xofs_url_itm_parser_fxt Init_name(String key, String val) {parser.Names_add(key, val); return this;}
public Xofs_url_itm_parser_fxt Init_dir_spr_lnx() {parser.Dir_spr_(Op_sys.Lnx.Fsys_dir_spr_byte()); return this;}
public Xofs_url_itm_parser_fxt Init_dir_spr_wnt() {parser.Dir_spr_(Op_sys.Wnt.Fsys_dir_spr_byte()); return this;}
public void Test_parse_custom(String raw) {
parser.Parse(itm, raw);
Tfds.Eq(Bool_.N, itm.Tid_is_xowa());
Tfds.Eq(raw, itm.Url());
}
public void Test_parse(String raw, String expd) {
parser.Parse(itm, raw);
Tfds.Eq(Bool_.Y, itm.Tid_is_xowa());
Tfds.Eq(expd, itm.Url());
}
}

View File

@@ -0,0 +1,104 @@
/*
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.users.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
class Xow_wiki_loader {
public void Load(String mount) {
/*
load mount
Xow_mount_links links = user.Load_links(mount_id);
load data
for (int i = 0; i < links_len; i++) {
switch (link_tid) {
case data:
wiki.Db_mgr().Root_url() = Get_data(rel_id);
break;
}
}
*/
}
}
class Xou_wiki_itm_source {
public static final int Tid_user = 1, Tid_wmf = 2, Tid_wikia = 3;
}
class Xou_wiki_itm_path_layout {
public static final int Tid_multiple = 1, Tid_root = 2;
}
class Xou_wiki_tbl {
public static final String Tbl_sql = String_.Concat_lines_nl
( "CREATE TABLE wiki_regy"
, "( wiki_id integer NOT NULL PRIMARY KEY" // user_generated;
, ", wiki_key varchar(255)" // unique; akin to domain; en.wikipedia.org
, ", wiki_source integer" // 0=user; 1=wmf; 2=wikia;
, ", wiki_ctg_type integer" //
, ", wiki_search_type integer" //
// , ", wiki_data_date varchar(8)" // 20140502
// , ", wiki_data_root varchar(255)" //
// , ", wiki_file_date varchar(8)" // 20140502
// , ", wiki_file_root varchar(255)" //
// , ", wiki_html_date varchar(8)" // 20140502
// , ", wiki_html_root varchar(255)" //
, ", wiki_misc varchar(255)" // 20140502
, ");"
);
public static final String Tbl_name = "user_wiki"
, Fld_dir_id = "dir_id", Fld_dir_name = "dir_name"
;
// private static final Db_idx_itm
// Idx_name = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS cache_dir__name ON cache_dir (dir_name);")
// ;
}
/*
( wf_id integer NOT NULL PRIMARY KEY -- 1,2,3, etc..; user-specified (not canonical)
, wf_key varchar(255) NOT NULL -- system key; EX: "enwiki.css.20140601" UNIQUE; SYSTEM-GENERATED; CUSTOMIZABLE
, wf_name varchar(255) NOT NULL -- ui name; EX: "English Wikipedia CSS as of 2014-06-01"; NOT UNIQUE; SYSTEM-GENERATED; CUSTOMIZABLE
, wf_data_domain varchar(255) NOT NULL -- domain; EX:en.wikipedia.org
, wf_data_date varchar(255) NOT NULL -- dump date; 20140502
, wf_data_source varchar(255) NOT NULL -- WMF;archive.org;XOWA;
, wf_url varchar(255) NOT NULL -- url location; EX: "xowa-fs://~{xowa}/wiki/en.wikipedia.org/en.wikipedia.org.xowa"
, wf_sort integer NOT NULL -- sort order; EX: "1", "2", "3", etc.. UNIQUE; SYSTEM-GENERATED; CUSTOMIZABLE
, wf_deleted integer NOT NULL -- deleted flag
/xowa
/bin
/data
/en.wikipedia.org
/ file
fasb.mount
/ fsdb.main
/ fsdb.user
/ html
xowa_common.css
xowa_wiki.css
/ imgs
/ wiki
en.wikipedia.org.xowa
en.wikipedia.org.000.xowa
/user
*/
class Xou_wiki_part {
public int Id() {return id;} public void Id_(int v) {id = v;} private int id;
public boolean Deleted() {return deleted;} public void Deleted_(boolean v) {deleted = v;} private boolean deleted;
public Xofs_url_itm Url() {return url;} private Xofs_url_itm url = new Xofs_url_itm();
public String Domain() {return domain;} public void Domain_(String v) {domain = v;} private String domain;
public String Version() {return version;} public void Version_(String v) {version = v;} private String version;
public String Source() {return source;} public void Source_(String v) {source = v;} private String source;
public DateAdp Make_date() {return make_date;} public void Make_date_(DateAdp v) {make_date = v;} private DateAdp make_date;
public String Misc() {return misc;} public void Misc_(String v) {misc = v;} private String misc;
}