1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Source: Restore broken commit

This commit is contained in:
gnosygnu
2017-02-06 22:14:55 -05:00
parent 938beac9f9
commit 3bfeb94b43
4380 changed files with 328018 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
/*
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.gfs.*; import gplx.xowa.wikis.*;
public class Xou_fsys_mgr implements Gfo_invk {
private Io_url app_root_dir; private Io_url wiki_root_dir; private Io_url cur_root;
public Xou_fsys_mgr(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");
}
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_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 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 Gfo_invk_.Rv_unhandled;
} private static final String Invk_root_dir = "root_dir";
}

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.*;
import gplx.xowa.users.data.*;
import gplx.xowa.users.history.*;
import gplx.xowa.files.caches.*;
public interface Xou_user {
String Key();
int Gender();
Xou_db_mgr User_db_mgr();
Xou_history_mgr History_mgr();
Xow_wiki Wikii();
}

View File

@@ -0,0 +1,67 @@
/*
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.*; import gplx.xowa.langs.cases.*; import gplx.xowa.wikis.*;
import gplx.xowa.wikis.nss.*;
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 = app.Fsys_mgr().Home_wiki_dir();
Xol_lang_itm lang = app.Lang_mgr().Get_by_or_new(Xol_lang_itm_.Key_en);
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.Instance.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.wbases.Wdata_wiki_mgr.Ns_property, gplx.xowa.xtns.wbases.Wdata_wiki_mgr.Ns_property_name)
.Add_new(730, "Data").Add_new(731, "Data talk")
.Add_new(Xow_ns_.Tid__module, Xow_ns_.Key__module).Add_new(Xow_ns_.Tid__module_talk, Xow_ns_.Key__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 Gfo_invk {
private final Ordered_hash regy = Ordered_hash_.New();
private final Xoae_app app;
public Xou_user_mgr(Xoae_app app, Xoue_user user) {this.app = app; this.Add(user);}
public void Add(Xoue_user itm) {regy.Add(itm.Key(), itm);}
private Xoue_user GetByKey(String key) {return (Xoue_user)regy.Get_by(key);}
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 Gfo_invk_.Rv_unhandled;
} private static final String Invk_get = "get";
}

View File

@@ -0,0 +1,44 @@
/*
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 final Xou_user_fxt fxt = new Xou_user_fxt();
@Test public void Available_from_fsys() {
Io_mgr.Instance.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.Make__app__edit();
public String Make_xwiki(boolean offline, String name) {return String_.Concat_with_str("|", Yn.To_str(offline), name);}
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,121 @@
/*
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.envs.*;
import gplx.dbs.*; import gplx.core.brys.fmtrs.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*;
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, Gfo_evt_mgr_owner, Gfo_invk {
public Xoue_user(Xoae_app app, Io_url user_dir) {
this.app = app; this.key = user_dir.NameOnly();
this.ev_mgr = new Gfo_evt_mgr(this);
this.fsys_mgr = new Xou_fsys_mgr(user_dir);
this.user_db_mgr = new Xou_db_mgr(app);
this.history_mgr = new Xou_history_mgr(fsys_mgr.App_data_history_fil());
}
public Gfo_evt_mgr Evt_mgr() {return ev_mgr;} private final Gfo_evt_mgr 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 this.Wiki();}
public int Gender() {return Xol_gender_.Tid_unknown;}
public Xoae_app Appe() {return app;} private final Xoae_app app;
public Xol_lang_itm Lang() {if (lang == null) {lang = app.Lang_mgr().Get_by_or_new(app.Sys_cfg().Lang()); lang.Init_by_load();} return lang;} private Xol_lang_itm lang;
public void Lang_(Xol_lang_itm 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
Gfo_evt_mgr_.Pub_val(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 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.Instance.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() {
gplx.xowa.guis.views.Xog_startup_win_.Shutdown(app, app.Gui_mgr().Browser_win().Win_box()); // save window position
history_mgr.Save(app);
if (app.Gui_mgr().Browser_win().Tab_mgr().Page_load_mode_is_url())
Io_mgr.Instance.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().Load_page_by_ttl(bookmarks_ttl);
byte[] new_data = Bry_.Add(bookmarks_page.Db().Text().Text_bry(), 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_a7("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, "name")) return key; //throw Err_.new_unhandled(k); // OBSOLETE: used to return key
else return Gfo_invk_.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";
public static final String Key_xowa_user = "anonymous";
public static final String Evt_lang_changed = "lang_changed";
public void Available_from_fsys() {
Io_url[] dirs = Io_mgr.Instance.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)) continue; // ignore "#dump"
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_.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_by_atrs(wiki_name, wiki_name);
}
}

View File

@@ -0,0 +1,42 @@
/*
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.users.history.*;
import gplx.xowa.files.*; import gplx.xowa.files.caches.*;
import gplx.xowa.wikis.*; import gplx.xowa.wikis.domains.*;
import gplx.xowa.langs.genders.*;
public class Xouv_user implements Xou_user {
private Xoa_wiki_mgr wiki_mgr;
public Xouv_user(Xoa_app app, String key, Io_url user_dir) {
this.key = key;
this.fsys_mgr = new Xou_fsys_mgr(user_dir);
this.history_mgr = new Xou_history_mgr(fsys_mgr.App_data_history_fil());
}
public String Key() {return key;} private String key;
public Xou_fsys_mgr Fsys_mgr() {return fsys_mgr;} private final Xou_fsys_mgr fsys_mgr;
public Xou_history_mgr History_mgr() {return history_mgr;} private final Xou_history_mgr history_mgr;
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_or_make_init_y(Xow_domain_itm_.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,127 @@
/*
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.core.brys.fmtrs.*; import gplx.core.errs.*;
import gplx.langs.jsons.*; import gplx.langs.htmls.*;
import gplx.xowa.users.data.*; import gplx.xowa.users.bmks.*;
import gplx.xowa.htmls.bridges.*; import gplx.xowa.htmls.bridges.dbuis.*; import gplx.xowa.htmls.bridges.dbuis.tbls.*; import gplx.xowa.htmls.bridges.dbuis.fmtrs.*;
public class Dbui_tbl_itm__bmk implements Dbui_tbl_itm {
private final Xoa_app app; private final Xoud_bmk_itm_tbl tbl;
private final Dbui_tbl_fmtr tbl_fmtr = new Dbui_tbl_fmtr();
private final Dbui_cells_fmtr cells_fmtr = new Dbui_cells_fmtr(); private final Dbui_val_fmtr edit_val_fmtr = Dbui_val_fmtr_.new_edit(); private final Dbui_val_fmtr view_val_fmtr = Dbui_val_fmtr_.new_view();
private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(255);
private final Bridge_msg_bldr msg_bldr;
public Dbui_tbl_itm__bmk(Xoa_app app, Xoud_bmk_itm_tbl tbl) {this.app = app; this.tbl = tbl; this.msg_bldr = app.Html__bridge_mgr().Msg_bldr();}
public byte[] Key() {return key;} private static final byte[] key = Bry_.new_a7("bmk");
public Dbui_btn_itm[] View_btns() {return view_btns;}
public Dbui_btn_itm[] Edit_btns() {return edit_btns;}
public Dbui_col_itm[] Cols() {return cols;}
public void Reg(Bridge_cmd_mgr bridge_mgr) {
Dbui_cmd_mgr dbui_mgr = Dbui_cmd_mgr.Instance;
dbui_mgr.Init_by_bridge(bridge_mgr);
dbui_mgr.Add(this);
}
public void Select(Bry_bfr bfr, int owner) {
Xoud_bmk_itm_row[] db_rows = tbl.Select_grp(owner);
Xow_wiki usr_wiki = app.User().Wikii();
byte[] option_link = usr_wiki.Html__lnki_bldr().Href_(Bry_.new_a7("home"), usr_wiki.Ttl_parse(Bry_.new_a7("Options/Bookmarks"))).Img_16x16(gplx.xowa.htmls.core.htmls.utls.Xoh_img_path.Img_option).Bld_to_bry();// HOME
byte[] delete_confirm_msg = app.Api_root().Usr().Bookmarks().Delete_confirm() ? Msg__delete_confirm : Bry_.Empty;
tbl_fmtr.Write(bfr, this, option_link, delete_confirm_msg, To_ui_rows(db_rows));
} private static final byte[] Msg__delete_confirm = Bry_.new_a7(" data-dbui-delete_confirm_msg='Are you sure you want to delete this bookmark?'");
public String Del(byte[] row_id, byte[] row_pkey) {
Xoud_bmk_itm_row db_row = Get_db_row(row_pkey); if (db_row == null) return Fail_missing_row(row_pkey);
tbl.Delete(db_row.Id());
return msg_bldr.To_json_str__empty();
}
public String Edit(byte[] row_id, byte[] row_pkey) {
Xoud_bmk_itm_row db_row = Get_db_row(row_pkey); if (db_row == null) return Fail_missing_row(row_pkey);
Dbui_row_itm ui_row = Get_ui_row(db_row);
return Write_cells(edit_val_fmtr, edit_btns, row_id, ui_row);
}
public String Save(byte[] row_id, byte[] row_pkey, Dbui_val_hash vals) {
Xoud_bmk_itm_row db_row = Get_db_row(row_pkey); if (db_row == null) return Fail_missing_row(row_pkey);
byte[] new_name = vals.Get_val_as_bry("name");
byte[] new_url_bry = vals.Get_val_as_bry("url");
byte[] new_comment = vals.Get_val_as_bry("comment");
Xoa_url new_url = app.User().Wikii().Utl__url_parser().Parse(new_url_bry);
if (new_url.Page_bry() == null) return msg_bldr.Clear().Notify_fail_(Err_msg.To_str("Url is invalid", "url", new_url.Raw())).To_json_str();
tbl.Update(db_row.Id(), db_row.Owner(), db_row.Sort(), new_name, new_url.Wiki_bry(), new_url_bry, new_comment);
Dbui_row_itm ui_row = Get_ui_row(row_pkey, new_name, new_url_bry, new_comment);
return Write_cells(view_val_fmtr, view_btns, row_id, ui_row);
}
public String Reorder(byte[][] pkeys, int owner) {
Xoud_bmk_itm_row[] db_rows = tbl.Select_grp(Xoud_bmk_mgr.Owner_root);
int len = db_rows.length; if (len != pkeys.length) return msg_bldr.Clear().Notify_fail_(Err_msg.To_str("Rows have changed")).Notify_hint_("Please reload the page").To_json_str();
for (int i = 0; i < len; ++i) {
int old_pkey = db_rows[i].Id();
int new_pkey = Bry_.To_int_or_neg1(pkeys[i]);
if (old_pkey == new_pkey) continue; // order hasn't changed; EX: 5 in list; 4th moved to 5th; 1 through 3 will have same sort order;
tbl.Update_sort(new_pkey, i);
}
return msg_bldr.To_json_str__empty();
}
public Dbui_row_itm[] To_ui_rows(Xoud_bmk_itm_row[] db_rows) {
int len = db_rows.length;
Dbui_row_itm[] rv = new Dbui_row_itm[len];
for (int i = 0; i < len; ++i)
rv[i] = Get_ui_row(db_rows[i]);
return rv;
}
private String Write_cells(Dbui_val_fmtr val_fmtr, Dbui_btn_itm[] btns, byte[] row_id, Dbui_row_itm row) {
cells_fmtr.Ctor(val_fmtr, btns);
cells_fmtr.Init(row_id, row);
cells_fmtr.Bfr_arg__add(tmp_bfr);
return app.Html__bridge_mgr().Msg_bldr().Clear().Data("html", tmp_bfr.To_bry_and_clear()).To_json_str();
}
private Xoud_bmk_itm_row Get_db_row(byte[] pkey) {
int bmk_id = Bry_.To_int(pkey);
return tbl.Select_or_null(bmk_id);
}
private Dbui_row_itm Get_ui_row(Xoud_bmk_itm_row row) {return Get_ui_row(Int_.To_bry(row.Id()), row.Name(), row.Url(), row.Comment());}
private Dbui_row_itm Get_ui_row(byte[] pkey, byte[] name, byte[] url, byte[] comment) {
Dbui_val_itm[] vals = new Dbui_val_itm[3];
vals[0] = new Dbui_val_itm(name, Gfh_utl.Escape_html_as_bry(tmp_bfr, name));
vals[1] = new Dbui_val_itm(url, url_fmtr.Bld_bry_many(tmp_bfr, Gfh_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, url)));
vals[2] = new Dbui_val_itm(comment, Gfh_utl.Escape_html_as_bry(comment));
return new Dbui_row_itm(this, pkey, vals);
}
private String Fail_missing_row(byte[] row_pkey) {
return msg_bldr.Clear().Notify_fail_(Err_msg.To_str("Item has been deleted", "key", row_pkey)).Notify_hint_("Please reload the page").To_json_str();
}
private static final Dbui_col_itm[] cols = new Dbui_col_itm[]
{ new Dbui_col_itm(Dbui_col_itm.Type_id_str , 150, "name" , "Name")
, new Dbui_col_itm(Dbui_col_itm.Type_id_str , 300, "url" , "Url")
, new Dbui_col_itm(Dbui_col_itm.Type_id_text , 300, "comment" , "Comment")
};
private static final Dbui_btn_itm[] view_btns = new Dbui_btn_itm[]
{ new Dbui_btn_itm("rows__edit" , "edit.png" , "edit")
, new Dbui_btn_itm("rows__delete" , "delete.png" , "delete")
};
private static final Dbui_btn_itm[] edit_btns = new Dbui_btn_itm[]
{ new Dbui_btn_itm("rows__save" , "save.png" , "save")
, new Dbui_btn_itm("rows__cancel" , "cancel.png" , "cancel")
};
private static final Bry_fmtr url_fmtr = Bry_fmtr.new_("<a href='/site/~{url}'>~{url}</a>", "url");
public static Dbui_tbl_itm__bmk get_or_new(Xoa_app app, Xoud_bmk_itm_tbl db_tbl) {
if (I == null) {
I = new Dbui_tbl_itm__bmk(app, db_tbl);
I.Reg(app.Html__bridge_mgr().Cmd_mgr());
}
return I;
} private static Dbui_tbl_itm__bmk I;
}

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 Rls_able {
private final String tbl_name = "bmk_dir"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
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.Meta_tbl_create(Dbmeta_tbl_itm.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,106 @@
/*
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 Rls_able {
private final String tbl_name = "bmk_itm"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_id, fld_owner, fld_sort, fld_name, fld_wiki, fld_url, fld_comment;
private Db_stmt stmt_update_sort;
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" , 1024);
fld_comment = flds.Add_str("itm_comment" , 4096);
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.Meta_tbl_create(Dbmeta_tbl_itm.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 Update_sort(int id, int sort) {
if (stmt_update_sort == null) stmt_update_sort = conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_sort);
stmt_update_sort.Clear().Val_int(fld_sort, sort).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();}
}
public Xoud_bmk_itm_row Select_or_null(int id) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_id).Crt_int(fld_id, id).Exec_select__rls_manual();
try {
return rdr.Move_next() ? new_row(rdr) : null;
}
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() {
stmt_update_sort = null;
}
}

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.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.To_bry(Bool_.Y, Bool_.Y), Bry_.Empty);
}
public static final int Owner_root = -1;
}

View File

@@ -0,0 +1,37 @@
/*
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.core.primitives.*;
import gplx.xowa.htmls.bridges.dbuis.tbls.*;
import gplx.xowa.users.data.*; import gplx.xowa.specials.*;
import gplx.xowa.wikis.pages.*;
public class Xows_bmk_page implements Xow_special_page {
public Xow_special_meta Special__meta() {return Xow_special_meta_.Itm__bookmarks;}
public void Special__gen(Xow_wiki wikii, Xoa_page pagei, Xoa_url url, Xoa_ttl ttl) {
Xowe_wiki wiki = (Xowe_wiki)wikii; Xoae_page page = (Xoae_page)pagei;
Xoa_app app = wiki.App();
Dbui_tbl_itm__bmk ui_tbl = Dbui_tbl_itm__bmk.get_or_new(app, app.User().User_db_mgr().Bmk_mgr().Tbl__itm());
page.Html_data().Head_mgr().Itm__dbui().Init(app).Enabled_y_();
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001();
ui_tbl.Select(bfr, Xoud_bmk_mgr.Owner_root);
Xopage_html_data page_data = new Xopage_html_data(this.Special__meta().Display_ttl(), bfr.To_bry_and_rls());
page_data.Apply(page);
}
public Xow_special_page Special__clone() {return this;}
}

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.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xocfg_meta_itm {
public Xocfg_meta_itm(String key, String type, String dflt, String version) {
this.key = key; this.type = type; this.dflt = dflt; this.version = version;
}
public String Key() {return key;} private final String key;
public String Type() {return type;} private String type;
public String Dflt() {return dflt;} private String dflt;
public String Version() {return version;} private String version;
}

View File

@@ -0,0 +1,40 @@
/*
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.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*;
public class Xocfg_meta_tbl implements Rls_able {
private final String tbl_name; public final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_key, fld_type, fld_dflt, fld_version;
private final Db_conn conn;
public Xocfg_meta_tbl(Db_conn conn) {
this.conn = conn;
tbl_name = Tbl_name;
fld_key = flds.Add_str_pkey ("cfg_key" , 1024); // EX: "xowa.net.web_enabled"
fld_type = flds.Add_str ("cfg_type" , 255); // EX: "yn"
fld_dflt = flds.Add_str ("cfg_dflt" , 1024); // EX: "n"
fld_version = flds.Add_str ("cfg_version" , 16); // EX: "v1.1.1.1"
}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
public void Insert(String key, String type, String dflt, String version) {
Db_stmt stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear().Val_str(fld_key, key).Val_str(fld_type, type).Val_str(fld_dflt, dflt).Val_str(fld_version, version)
.Exec_insert();
}
public void Rls() {}
public static final String Tbl_name = "cfg_meta";
}

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.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xou_cfg_itm {
public Xou_cfg_itm(int usr, String ctx, String key, String val) {
this.usr = usr; this.ctx = ctx; this.key = key; this.val = val;
this.uid = Xou_cfg_mgr.Bld_uid(usr, ctx, key);
}
public String Uid() {return uid;} private final String uid;
public int Usr() {return usr;} private final int usr;
public String Ctx() {return ctx;} private final String ctx;
public String Key() {return key;} private final String key;
public String Val() {return val;} private String val;
public void Val_(String v) {this.val = v;}
}

View File

@@ -0,0 +1,73 @@
/*
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.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*;
public class Xou_cfg_mgr {
private Xou_cfg_tbl tbl;
private final Hash_adp hash = Hash_adp_.New();
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
public void Init_by_app(Db_conn conn) {
tbl = new Xou_cfg_tbl(conn);
tbl.Conn().Meta_tbl_assert(tbl);
this.Reg(tbl.Select_by_usr_ctx(Usr__anonymous, Ctx__app));
}
public String Get_app_str_or(String key, String or) { // NOTE: app-level is always loaded at start; don't check db
synchronized (hash) { // LOCK:app-level
String uid = Bld_uid(tmp_bfr, Usr__anonymous, Ctx__app, key);
Xou_cfg_itm itm = (Xou_cfg_itm)hash.Get_by(uid);
return itm == null ? or : itm.Val();
}
}
public void Set_app_bry(String key, byte[] val) {this.Set_app_str(key, String_.new_u8(val));}
public void Set_app_str(String key, String val) {
synchronized (hash) { // LOCK:app-level
// update val in reg
String uid = Bld_uid(tmp_bfr, Usr__anonymous, Ctx__app, key);
boolean insert = false;
Xou_cfg_itm itm = (Xou_cfg_itm)hash.Get_by(uid);
if (itm == null) {
itm = new Xou_cfg_itm(Usr__anonymous, Ctx__app, key, val);
hash.Add(uid, itm);
insert = true;
}
itm.Val_(val);
// save to db
tbl.Upsert(insert, itm.Usr(), itm.Ctx(), itm.Key(), itm.Val());
}
}
private void Reg(Xou_cfg_itm[] itms) {
synchronized (hash) { // LOCK:app-level
for (Xou_cfg_itm itm : itms)
hash.Add(itm.Uid(), itm);
}
}
private static final int Usr__anonymous = 1;
private static final String Ctx__app = "app";
public static String Bld_uid(int usr, String ctx, String key) {
return String_.Concat(Int_.To_str(usr), "|", ctx, "|", key);
}
private static String Bld_uid(Bry_bfr tmp_bfr, int usr, String ctx, String key) {
tmp_bfr.Add_int_variable(usr).Add_byte_pipe();
tmp_bfr.Add_str_a7(ctx).Add_byte_pipe();
tmp_bfr.Add_str_u8(key);
return tmp_bfr.To_str_and_clear();
}
}

View File

@@ -0,0 +1,70 @@
/*
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.cfgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.dbs.*;
public class Xou_cfg_tbl implements Db_tbl {
public final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_key, fld_usr, fld_ctx, fld_val;
public Xou_cfg_tbl(Db_conn conn) {
this.conn = conn;
this.fld_usr = flds.Add_int ("cfg_usr"); // EX: 1=anonymous; others will require usr_regy
this.fld_ctx = flds.Add_str ("cfg_ctx", 1024); // EX: "app"; "en.w"
this.fld_key = flds.Add_str ("cfg_key", 1024); // EX: "xowa.net.web_enabled"
this.fld_val = flds.Add_str ("cfg_val", 4096); // EX: "y"
conn.Rls_reg(this);
}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public String Tbl_name() {return tbl_name;} private final String tbl_name = "user_cfg";
public void Create_tbl() {
conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds
, Dbmeta_idx_itm.new_normal_by_tbl(tbl_name, fld_key, fld_key)
));
}
public void Upsert(boolean insert, int usr, String ctx, String key, String val) {
if (insert)
Insert(usr, ctx, key, val);
else
Update(usr, ctx, key, val);
}
private void Insert(int usr, String ctx, String key, String val) {
Db_stmt stmt = conn.Stmt_insert(tbl_name, flds);
stmt.Clear().Val_int(fld_usr, usr).Val_str(fld_ctx, ctx).Val_str(fld_key, key).Val_str(fld_val, val).Exec_insert();
stmt.Rls();
}
private void Update(int usr, String ctx, String key, String val) {
Db_stmt stmt = conn.Stmt_update(tbl_name, String_.Ary(fld_usr, fld_ctx, fld_key), fld_val);
stmt.Clear().Val_str(fld_val, val).Crt_int(fld_usr, usr).Crt_str(fld_ctx, ctx).Crt_str(fld_key, key).Exec_update();
stmt.Rls();
}
public Xou_cfg_itm[] Select_by_usr_ctx(int usr, String ctx) {
List_adp list = List_adp_.New();
Db_stmt stmt_select = conn.Stmt_select(tbl_name, flds, fld_usr, fld_ctx);
Db_rdr rdr = stmt_select.Clear().Crt_int(fld_usr, usr).Crt_str(fld_ctx, ctx).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
list.Add(Make_itm(rdr));
}
} finally {rdr.Rls();}
return (Xou_cfg_itm[])list.To_ary_and_clear(Xou_cfg_itm.class);
}
public void Rls() {}
private Xou_cfg_itm Make_itm(Db_rdr rdr) {
return new Xou_cfg_itm(rdr.Read_int(fld_usr), rdr.Read_str(fld_ctx), rdr.Read_str(fld_key), rdr.Read_str(fld_val));
}
}

View File

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

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.core.threads.*; import gplx.dbs.*; import gplx.dbs.metas.updates.*; import gplx.dbs.metas.*;
import gplx.xowa.files.caches.*;
import gplx.xowa.users.cfgs.*; import gplx.xowa.users.bmks.*; import gplx.xowa.users.history.*;
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 Db_conn Conn() {return conn;} private Db_conn conn;
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 Xou_cfg_mgr Cfg() {return cfg;} private final Xou_cfg_mgr cfg = new Xou_cfg_mgr();
public void Init_by_app(boolean drd, Io_url db_url) {
Db_conn_bldr_data db_conn_bldr = Db_conn_bldr.Instance.Get_or_new(db_url);
this.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);
cfg.Init_by_app(conn);
// this.history_mgr.Conn_(conn, created);
if (drd) {
this.Init_site_mgr();
// history_mgr.Conn_(user_conn, created);
}
}
private boolean init_site_mgr;
public void Init_site_mgr() {
if (init_site_mgr) return; init_site_mgr = true;
cfg_mgr.Conn_ (conn, !conn.Meta_tbl_exists(Xoud_cfg_mgr.Tbl_name));
site_mgr.Conn_(conn, !conn.Meta_tbl_exists(Xoud_site_tbl.Tbl_name));
}
}

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.*; import gplx.dbs.cfgs.*;
public class Xoud_cfg_mgr {
public Db_cfg_tbl Tbl() {return tbl;} private Db_cfg_tbl tbl;
public static final String Tbl_name = "user_opt";
public void Conn_(Db_conn new_conn, boolean created) {
tbl = new Db_cfg_tbl(new_conn, Tbl_name);
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 Upsert_int(String grp, String key, int val) {
int exists = Select_int_or(grp, key, Int_.Min_value);
if (exists == Int_.Min_value)
Insert_int(grp, key, val);
else
Update_int(grp, key, val);
}
public void Upsert_str(String grp, String key, String val) {
String exists = Select_str_or(grp, key, null);
if (exists == null)
Insert_str(grp, key, val);
else
Update_str(grp, key, val);
}
public void Update_str(String grp, String key, String val) {Update_bry(grp, key, Bry_.new_u8(val));}
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 Update_int(String grp, String key, int val) {tbl.Update_int(grp, key, val);}
public void Insert_str(String grp, String key, String val) {Insert_bry(grp, key, Bry_.new_u8(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,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.Upsert_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,85 @@
/*
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.domains.*;
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_stub_.Get_by_id(lang_id).Key());
String type_str = type_id == Lang_id_wildcard ? "*" : String_.new_u8(Xow_domain_tid_.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_.Instance;
list.Clear();
int pos = 0; int src_len = src.length;
while (pos < src_len) {
int comma_pos = Bry_find_.Find_fwd(src, Byte_ascii.Comma, pos, src_len); if (comma_pos == Bry_find_.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_find_.Find_fwd(src, Byte_ascii.Dot, bgn, end); if (lang_dot == Bry_find_.Not_found) return Warn("scope.parse.missing_lang_dot: src=~{0}", src, bgn, end);
int lang_id = Int_.Min_value;
if (lang_dot == 1 && src[bgn] == Byte_ascii.Star)
lang_id = Xoud_opt_scope.Lang_id_wildcard;
else {
Xol_lang_stub lang_itm = Xol_lang_stub_.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_tid_.Tid__wikipedia)
.Add_str_int("d" , Xow_domain_tid_.Tid__wiktionary)
.Add_str_int("s" , Xow_domain_tid_.Tid__wikisource)
.Add_str_int("v" , Xow_domain_tid_.Tid__wikivoyage)
.Add_str_int("q" , Xow_domain_tid_.Tid__wikiquote)
.Add_str_int("b" , Xow_domain_tid_.Tid__wikibooks)
.Add_str_int("u" , Xow_domain_tid_.Tid__wikiversity)
.Add_str_int("n" , Xow_domain_tid_.Tid__wikinews)
.Add_str_int("*" , Xoud_opt_scope.Type_id_wildcard)
.Add_str_int("xowa" , Xow_domain_tid_.Tid__home)
.Add_str_int("wd" , Xow_domain_tid_.Tid__wikidata)
.Add_str_int("c" , Xow_domain_tid_.Tid__commons)
.Add_str_int("species" , Xow_domain_tid_.Tid__species)
.Add_str_int("meta" , Xow_domain_tid_.Tid__meta)
.Add_str_int("mw" , Xow_domain_tid_.Tid__mediawiki)
.Add_str_int("wmf" , Xow_domain_tid_.Tid__wmfblog)
;
private static final Xoud_opt_scope[] Ary_app = new Xoud_opt_scope[] {Xoud_opt_scope.App};
}

View File

@@ -0,0 +1,52 @@
/*
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.domains.*;
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_stub_.Id_en, Xow_domain_tid_.Tid__wikipedia));
fxt.Test_parse("en.*" , fxt.Make(Xol_lang_stub_.Id_en, Xoud_opt_scope.Type_id_wildcard));
fxt.Test_parse("*.w" , fxt.Make(Xoud_opt_scope.Lang_id_wildcard, Xow_domain_tid_.Tid__wikipedia));
fxt.Test_parse("<any>" , Xoud_opt_scope.App);
fxt.Test_parse("en.w,fr.d" , fxt.Make(Xol_lang_stub_.Id_en, Xow_domain_tid_.Tid__wikipedia), fxt.Make(Xol_lang_stub_.Id_fr, Xow_domain_tid_.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_.New__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.To_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.Meta_tbl_create(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,41 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.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 Xoud_site_row Select_by_domain(byte[] domain) {return tbl.Select_by_domain(domain);}
public void Delete_by_domain(byte[] domain) {tbl.Delete_by_domain(domain);}
public void Import(String domain, String name, String path, String date, String xtn) { // insert or update wiki
Xoud_site_row itm = tbl.Select_by_domain(Bry_.new_u8(domain));
if (itm == null)
tbl.Insert(id_mgr.Get_next_and_save("xowa.user.site"), 0, domain, name, path, date, xtn);
else
tbl.Update(itm.Id(), 0, domain, name, path, date, xtn);
}
public void Update(Xoud_site_row row) {
tbl.Update(row.Id(), row.Priority(), row.Domain(), row.Name(), row.Path(), row.Date(), row.Xtn());
}
}

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_site_row {
public Xoud_site_row(int id, int priority, String domain, String name, String path, String date, String xtn) {
this.id = id; this.priority = priority; this.domain = domain; this.name = name; this.path = path; this.date = date; 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 Date() {return date;} private String date; public void Date_(String v) {this.date = v;}
public String Xtn() {return xtn;} private String xtn;
}

View File

@@ -0,0 +1,91 @@
/*
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 Rls_able {
public static final String Tbl_name = "user_site";
private final String tbl_name = Tbl_name; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_site_id, fld_site_priority, fld_site_domain, fld_site_name, fld_site_path, fld_site_xtn, fld_site_date;
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_date = conn.Meta_fld_append_if_missing(tbl_name, flds, Dbmeta_fld_itm.new_str("site_date", 255).Default_("")); // EX: 2016-06-10
fld_site_xtn = flds.Add_text("site_xtn");
conn.Rls_reg(this);
}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
public void Rls() {}
public void Insert(int site_id, int priority, String domain, String name, String path, String date, String xtn) {
Db_stmt stmt = conn.Stmt_insert(tbl_name, flds);
Exec_stmt(stmt, Bool_.N, site_id, priority, domain, name, path, date, xtn);
}
public void Update(int site_id, int priority, String domain, String name, String path, String date, String xtn) {
Db_stmt stmt = conn.Stmt_update_exclude(tbl_name, flds, fld_site_id);
Exec_stmt(stmt, Bool_.Y, site_id, priority, domain, name, path, date, xtn);
}
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 void Delete_by_domain(byte[] domain) {
conn.Stmt_delete(tbl_name, fld_site_domain).Crt_bry_as_str(fld_site_domain, domain).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_site(rdr));
return (Xoud_site_row[])rv.To_ary_and_clear(Xoud_site_row.class);
}
finally {rdr.Rls();}
}
public Xoud_site_row Select_by_domain(byte[] domain) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, fld_site_domain).Crt_bry_as_str(fld_site_domain, domain).Exec_select__rls_auto();
try {return rdr.Move_next() ? New_site(rdr) : null;} // NOTE: old versions allowed multiple wikis with same domain; only return 1st
finally {rdr.Rls();}
}
private void Exec_stmt(Db_stmt stmt, boolean update, int site_id, int priority, String domain, String name, String path, String date, String xtn) {
if (!update)
stmt.Val_int(fld_site_id, 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_date, date).Val_str(fld_site_xtn, xtn);
if (update)
stmt.Crt_int(fld_site_id, site_id);
if (update)
stmt.Exec_update();
else
stmt.Exec_insert();
}
private Xoud_site_row New_site(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_date)
, 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_.Min_value) {
rv = tbl.Select_id_next();
tbl.Insert(rv, name);
}
return rv;
}
}
class Xoud_user_tbl {
private String tbl_name = "user_user_regy"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
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) {
Dbmeta_tbl_itm meta = Dbmeta_tbl_itm.New(tbl_name, flds
, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "name", fld_name)
);
conn.Meta_tbl_create(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_.Min_value;
}
finally {rdr.Rls();}
}
public int Select_id_next() {
int rv = 1;
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Dbmeta_fld_itm.Str_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,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 gplx.core.brys.fmtrs.*; import gplx.core.errs.*;
import gplx.langs.jsons.*; import gplx.langs.htmls.*;
import gplx.xowa.users.data.*; import gplx.xowa.users.bmks.*;
import gplx.xowa.htmls.bridges.*; import gplx.xowa.htmls.bridges.dbuis.*; import gplx.xowa.htmls.bridges.dbuis.tbls.*; import gplx.xowa.htmls.bridges.dbuis.fmtrs.*;
public class Dbui_tbl_itm__history implements Dbui_tbl_itm {
private final Xoa_app app; private final Xoud_history_tbl tbl;
private final Dbui_tbl_fmtr tbl_fmtr = new Dbui_tbl_fmtr();
private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(255);
private final Bridge_msg_bldr msg_bldr;
public Dbui_tbl_itm__history(Xoa_app app, Xoud_history_tbl tbl) {this.app = app; this.tbl = tbl; this.msg_bldr = app.Html__bridge_mgr().Msg_bldr();}
public byte[] Key() {return key;} private static final byte[] key = Bry_.new_a7("history");
public Dbui_btn_itm[] View_btns() {return view_btns;}
public Dbui_btn_itm[] Edit_btns() {return Dbui_btn_itm.Ary_empty;}
public Dbui_col_itm[] Cols() {return cols;}
public void Reg(Bridge_cmd_mgr bridge_mgr) {
Dbui_cmd_mgr dbui_mgr = Dbui_cmd_mgr.Instance;
dbui_mgr.Init_by_bridge(bridge_mgr);
dbui_mgr.Add(this);
}
private final List_adp select_list = List_adp_.New();
public void Select(Bry_bfr bfr, int top) {
tbl.Select_by_top(select_list, 100);
Xoud_history_row[] db_rows = (Xoud_history_row[])select_list.To_ary_and_clear(Xoud_history_row.class);
Xow_wiki usr_wiki = app.User().Wikii();
byte[] option_link = usr_wiki.Html__lnki_bldr().Href_(Bry_.new_a7("home"), usr_wiki.Ttl_parse(Bry_.new_a7("Options/PageHistory"))).Img_16x16(gplx.xowa.htmls.core.htmls.utls.Xoh_img_path.Img_option).Bld_to_bry();// HOME
byte[] delete_confirm_msg = app.Api_root().Usr().Bookmarks().Delete_confirm() ? Msg__delete_confirm : Bry_.Empty;
tbl_fmtr.Write(bfr, this, option_link, delete_confirm_msg, To_ui_rows(db_rows));
} private static final byte[] Msg__delete_confirm = Bry_.new_a7(" data-dbui-delete_confirm_msg='Are you sure you want to delete this row?'");
public String Del(byte[] row_id, byte[] row_pkey) {
Xoud_history_row db_row = Get_db_row(row_pkey); if (db_row == null) return Fail_missing_row(row_pkey);
tbl.Delete(db_row.Id());
return msg_bldr.To_json_str__empty();
}
public String Edit(byte[] row_id, byte[] row_pkey) {throw Err_.new_unimplemented();}
public String Save(byte[] row_id, byte[] row_pkey, Dbui_val_hash vals) {throw Err_.new_unimplemented();}
public String Reorder(byte[][] pkeys, int owner) {throw Err_.new_unimplemented();}
public Dbui_row_itm[] To_ui_rows(Xoud_history_row[] db_rows) {
int len = db_rows.length;
Dbui_row_itm[] rv = new Dbui_row_itm[len];
for (int i = 0; i < len; ++i)
rv[i] = Get_ui_row(db_rows[i]);
return rv;
}
private Xoud_history_row Get_db_row(byte[] pkey) {
int id = Bry_.To_int(pkey);
return tbl.Select_or_null(id);
}
private Dbui_row_itm Get_ui_row(Xoud_history_row row) {return Get_ui_row(Int_.To_bry(row.Id()), row.Wiki(), row.Url(), row.Count(), row.Time());}
private Dbui_row_itm Get_ui_row(byte[] pkey, byte[] wiki, byte[] url, int count, DateAdp time) {
Dbui_val_itm[] vals = new Dbui_val_itm[4];
vals[0] = new Dbui_val_itm(url, url_fmtr.Bld_bry_many(tmp_bfr, Gfh_utl.Escape_for_atr_val_as_bry(tmp_bfr, Byte_ascii.Apos, url)));
vals[1] = new Dbui_val_itm(wiki, wiki);
byte[] count_bry = Int_.To_bry(count);
vals[2] = new Dbui_val_itm(count_bry, count_bry);
byte[] time_bry = Bry_.new_u8(time.XtoStr_fmt_yyyy_MM_dd_HH_mm_ss());
vals[3] = new Dbui_val_itm(time_bry, time_bry);
return new Dbui_row_itm(this, pkey, vals);
}
private String Fail_missing_row(byte[] row_pkey) {
return msg_bldr.Clear().Notify_fail_(Err_msg.To_str("Item has been deleted", "key", row_pkey)).Notify_hint_("Please reload the page").To_json_str();
}
private static final Dbui_col_itm[] cols = new Dbui_col_itm[]
{ new Dbui_col_itm(Dbui_col_itm.Type_id_str , 300, "page" , "Page")
, new Dbui_col_itm(Dbui_col_itm.Type_id_str , 150, "wiki" , "Wiki")
, new Dbui_col_itm(Dbui_col_itm.Type_id_int , 80, "views" , "Views")
, new Dbui_col_itm(Dbui_col_itm.Type_id_datetime, 100, "time" , "Time")
};
private static final Dbui_btn_itm[] view_btns = new Dbui_btn_itm[]
{ new Dbui_btn_itm("rows__delete" , "delete.png" , "delete")
};
private static final Bry_fmtr url_fmtr = Bry_fmtr.new_("<a href='/site/~{url}'>~{url}</a>", "url");
public static Dbui_tbl_itm__history get_or_new(Xoa_app app, Xoud_history_tbl db_tbl) {
if (I == null) {
I = new Dbui_tbl_itm__history(app, db_tbl);
I.Reg(app.Html__bridge_mgr().Cmd_mgr());
}
return I;
} private static Dbui_tbl_itm__history I;
}

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 Gfo_invk {
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 Gfo_invk_.Rv_unhandled;
return this;
} private static final String Invk_enabled_ = "enabled_";
}

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.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.brys.fmtrs.*;
import gplx.xowa.specials.*;
public class Xou_history_html implements gplx.core.brys.Bfr_arg, Xow_special_page {
public Xow_special_meta Special__meta() {return Xow_special_meta_.Itm__page_history;}
public void Special__gen(Xow_wiki wikii, Xoa_page pagei, Xoa_url url, Xoa_ttl ttl) {
Xowe_wiki wiki = (Xowe_wiki)wikii; Xoae_page page = (Xoae_page)pagei;
this.app = wiki.Appe(); this.mgr = app.Usere().History_mgr();
mgr.Sort();
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001();
html_grp.Bld_bfr_many(bfr, this);
page.Db().Text().Text_bry_(bfr.To_bry_and_rls());
}
public void Bfr_arg__add(Bry_bfr bfr) {
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");
public Xow_special_page Special__clone() {return this;}
}

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.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.core.primitives.*;
public class Xou_history_itm {
private Xou_history_itm() {}
public Xou_history_itm(byte[] wiki, byte[] page) {
// remove "\n" from page for Category b/c it breaks the csv_parser; DATE:2016-10-12
int nl_pos = Bry_find_.Find_fwd(page, Byte_ascii.Nl);
if (nl_pos != Bry_find_.Not_found) {
page = Bry_.Mid(page, 0, nl_pos);
}
this.wiki = wiki;
this.page = page;
this.key = key_(wiki, page);
this.view_bgn = Datetime_now.Get();
}
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 Err_.new_unhandled(idx);
}
}
public void Tally() {
view_end = view_count == 0 ? view_bgn : Datetime_now.Get();
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 = Byte_ascii.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,167 @@
/*
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.core.net.*; import gplx.core.net.qargs.*; import gplx.xowa.htmls.hrefs.*;
public class Xou_history_mgr implements Gfo_invk {
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;
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
private boolean log_all = false;
public Xou_history_mgr(Io_url history_fil) {
this.history_fil = history_fil;
}
public void Init_by_app(Xoa_app app) {
app.Cfg().Bind_many_app(this, Cfg__enabled, Cfg__log_all);
}
public boolean Enabled() {return enabled;} private boolean enabled = true;
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_.Bry__wiki, 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;
if (page.Redirect_trail().Itms__len() > 0) // page was redirected; add src ttl to history, not trg; EX: UK -> United Kingdom; add "UK"; DATE:2014-02-28
page_ttl = page.Redirect_trail().Itms__get_at_0th_or_null().Ttl().Page_db();
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.Qargs_ary().length > 0)
page_ttl = Bry_.Add(page_ttl, url.Qargs_mgr().To_bry());
}
Add(page.Wiki().App(), url, ttl, page_ttl);
}
public void Add(Xoa_app app, Xoa_url url, Xoa_ttl ttl, byte[] page_ttl) {
if (gplx.xowa.users.history.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(), To_full_db_w_qargs(url, ttl));
itms.Add(key, itm);
}
if (log_all)
Io_mgr.Instance.AppendFilStr(history_fil.GenNewNameAndExt("log_all.csv"), String_.Format("{0}|{1}|{2}\n", Datetime_now.Get().XtoStr_fmt_iso_8561_w_tz(), itm.Wiki(), itm.Page()));
itm.Tally();
}
private byte[] To_full_db_w_qargs(Xoa_url url, Xoa_ttl ttl) {
byte[] page = Xoa_ttl.Replace_spaces(ttl.Full_txt_wo_qarg());
tmp_bfr.Add(page);
Gfo_qarg_mgr_old qarg_mgr = url.Qargs_mgr();
qarg_mgr.To_bry(tmp_bfr, gplx.langs.htmls.encoders.Gfo_url_encoder_.Href, Bool_.N);
return tmp_bfr.To_bry_and_clear();
}
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.Instance.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.Instance.SaveFilBry(app.Usere().Fsys_mgr().App_data_history_fil(), ary);
}
public Ordered_hash Archive(Xoae_app app) {
// sort all itms; other init
itms.Sort_by(sorter);
Ordered_hash current_itms = Ordered_hash_.New_bry();
Ordered_hash archive_itms = Ordered_hash_.New_bry();
// iterate over all itms
int itms_len = itms.Count();
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; // if < cutoff, add to current file; else add to archive
itms_hash.Add_if_dupe_use_nth(itm.Key(), itm); // NOTE: dupes should not exist, but if they do, ignore it; else app won't close on first time; DATE:2016-07-14
}
// save archive
byte[] ary = Xou_history_itm_srl.Save(archive_itms);
Io_url url = app.Usere().Fsys_mgr().App_data_history_fil().GenNewNameOnly(Datetime_now.Get().XtoStr_fmt_yyyyMMdd_HHmmss_fff());
Io_mgr.Instance.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 if (ctx.Match(k, Cfg__enabled)) enabled = m.ReadYn("v");
else if (ctx.Match(k, Cfg__log_all)) log_all = m.ReadYn("v");
else return Gfo_invk_.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");
private static final String Cfg__enabled = "xowa.app.page_history.enabled", Cfg__log_all = "xowa.app.page_history.log_all";
}
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.New_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 Err_.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.To_bry();
}
}

View File

@@ -0,0 +1,100 @@
/*
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() {
Datetime_now.Manual_y_(); // NOTE: each DateTime_.Now() advances clock by 1 min; adding a new Datetime_now.Get() 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");
}
@Test public void Remove_nl() {
fxt.Clear();
fxt.Add_many("Category:A?pagefrom=B\nB");
fxt.List_tst("Category:A?pagefrom=B");
}
}
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.Make__app__edit();
wiki = Xoa_app_fxt.Make__wiki__edit(app);
under = app.Usere().History_mgr();
}
Io_mgr.Instance.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.New_test(wiki, ttl);
page.Db().Page().Modified_on_(Datetime_now.Get());
byte[] url_bry = ttl_bry;
if (arg_str != null) url_bry = Bry_.Add(url_bry, Bry_.new_u8(arg_str));
Xoa_url url = wiki.Utl__url_parser().Parse(url_bry);
page.Url_(url); // 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) {Gfo_invk_.Invk_by_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.Instance.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.core.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,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.history; 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 Gfo_invk {
private Xoud_history_tbl history_tbl;
public void Conn_(Db_conn conn, boolean created) {
this.history_tbl = new Xoud_history_tbl(conn);
if (!conn.Meta_tbl_exists(history_tbl.Tbl_name())) 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 = Datetime_now.Get();
// if (row == null)
// history_tbl.Insert(wiki, page, qarg, time, 1);
// else
// history_tbl.Update(wiki, page, qarg, time, row.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 Gfo_invk_.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_is_special()
&& ( Bry_.Eq(page_db, gplx.xowa.users.history.Xou_history_mgr.Ttl_name) // do not add XowaPageHistory to history
|| Bry_.Eq(page_db, Xow_special_meta_.Itm__popup_history.Key_bry())
|| Bry_.Eq(page_db, Xow_special_meta_.Itm__default_tab.Key_bry())
|| Bry_.Eq(page_db, Xow_special_meta_.Itm__page_history.Key_bry())
)
);
}
}

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.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
public class Xoud_history_row {
public Xoud_history_row(int id, byte[] wiki, byte[] url, DateAdp time, int count) {
this.id = id;
this.wiki = wiki; this.url = url;
this.time = time; this.count = count;
}
public int Id() {return id;} private final int id;
public byte[] Wiki() {return wiki;} private final byte[] wiki;
public byte[] Url() {return url;} private final byte[] url;
public DateAdp Time() {return time;} private final DateAdp time;
public int Count() {return count;} private final int count;
}

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.history; import gplx.*; import gplx.xowa.*; import gplx.xowa.users.*;
import gplx.xowa.specials.*;
public class Xoud_history_special implements Xow_special_page {
public Xow_special_meta Special__meta() {return Xow_special_meta_.Itm__page_history;}
public void Special__gen(Xow_wiki wikii, Xoa_page pagei, Xoa_url url, Xoa_ttl ttl) {
Xowe_wiki wiki = (Xowe_wiki)wikii; Xoae_page page = (Xoae_page)pagei;
Xoa_app app = wiki.App();
Dbui_tbl_itm__history ui_tbl = Dbui_tbl_itm__history.get_or_new(app, app.User().User_db_mgr().Db_file().Tbl__history());
page.Html_data().Head_mgr().Itm__dbui().Init(app).Enabled_y_();
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_m001();
ui_tbl.Select(bfr, 100);
page.Db().Html().Html_bry_(bfr.To_bry_and_rls());
}
public Xow_special_page Special__clone() {return this;}
}

View File

@@ -0,0 +1,96 @@
/*
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.dbs.*; import gplx.dbs.qrys.*; import gplx.dbs.metas.*; import gplx.dbs.metas.updates.*;
public class Xoud_history_tbl implements Rls_able {
private final String tbl_name = "user_history"; private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final String fld_id, fld_wiki, fld_url, 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_id = flds.Add_int_pkey_autonum("hist_id");
fld_wiki = flds.Add_str("hist_wiki", 255);
fld_url = flds.Add_str("hist_url", 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 String Tbl_name() {return tbl_name;}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "pkey", fld_wiki, fld_url)));}
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(byte[] wiki, byte[] url, DateAdp time, int count) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_bry_as_str(fld_wiki, wiki)
.Val_bry_as_str(fld_url , url)
.Val_str(fld_time, time.XtoStr_fmt_iso_8561())
.Val_int(fld_count, count)
.Exec_insert();
}
public void Update(int id, DateAdp time, int count) {
if (stmt_update == null) stmt_update = conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_time, fld_count);
stmt_update.Clear()
.Val_str(fld_time, time.XtoStr_fmt_iso_8561())
.Val_int(fld_count, count)
.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_history_row Select_or_null(int id) {
if (stmt_select_by_page == null) stmt_select_by_page = conn.Stmt_select(tbl_name, flds, fld_id);
Db_rdr rdr = stmt_select_by_page.Clear().Crt_int(fld_id, id).Exec_select__rls_manual();
try {
return rdr.Move_next() ? new_row(rdr) : 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_.To_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_int(fld_id)
, rdr.Read_bry_by_str(fld_wiki)
, rdr.Read_bry_by_str(fld_url)
, rdr.Read_date_by_str(fld_time)
, rdr.Read_int(fld_count)
);
}
}

View File

@@ -0,0 +1,80 @@
/*
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 gplx.core.envs.*;
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_find_.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 Err_.new_wo_type("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.To_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.*; import gplx.core.envs.*;
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,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.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_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;
}