");
+ Sys.println("Error : "+try Std.string(e) catch( e : Dynamic ) "???");
+ Sys.println(haxe.CallStack.toString(haxe.CallStack.exceptionStack()));
+ try {
+ if( cnx != null )
+ sugoi.db.Error.manager.get(0,false);
+ } catch( e : Dynamic ) {
+ Sys.println("Initializing Database...");
+ sys.db.Admin.initializeDatabase();
+ Sys.println("Done");
+ }
+ Sys.print("");
+ }
+ }
+
+ /**
+ * init template engine
+ * and db connexion
+ */
+ function init() {
+ maintain = App.config.getBool("maintain");
+ if( maintain ) {
+ view = new View();
+ setTemplate("maintain.mtt");
+ executeTemplate(false);
+ return false;
+ }
+ try {
+ var dbstr = App.config.get("database");
+ var dbreg = ~/([^:]+):\/\/([^:]+):([^@]*?)@([^:]+)(:[0-9]+)?\/(.*?)$/;
+ if( !dbreg.match(dbstr) )
+ throw "Configuration requires a valid database attribute, format is : mysql://user:password@host:port/dbname";
+ var port = dbreg.matched(5);
+ var dbparams = {
+ user:dbreg.matched(2),
+ pass:dbreg.matched(3),
+ host:dbreg.matched(4),
+ port:port == null ? 3306 : Std.parseInt(port.substr(1)),
+ database:dbreg.matched(6),
+ socket:null
+ };
+ cnx = sys.db.Mysql.connect(dbparams);
+ } catch( e : Dynamic ) {
+ errorHandler(e);
+ return false;
+ }
+ if( App.config.SQL_LOG )
+ cnx = new sugoi.tools.DebugConnection(cnx);
+ return true;
+ }
+
+ function cloneApp() {
+ // ensure that we have no variable initialized in app loop
+ var app = new App();
+ var bapp : BaseApp = app;
+ bapp.cnx = cnx;
+ bapp.view = new View();
+ App.current = app;
+ bapp.mainLoop();
+ }
+
+ function run() {
+
+ // Will close the connection
+ sys.db.Transaction.main(cnx, cloneApp, function(e) { var b : BaseApp = App.current; b.errorHandler(e); });
+ App.current = null;
+ }
+
+ function sendHeaders(){
+ Web.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
+ Web.setHeader("Pragma", "no-cache");
+ Web.setHeader("Expires", "-1");
+ Web.setHeader("P3P", "CP=\"ALL DSP COR NID CURa OUR STP PUR\"");
+ Web.setHeader("Content-Type", "text/html; Charset=UTF-8");
+ Web.setHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT");
+ }
+
+ static function main() {
+
+ /**
+ * this macro will parse the code and generate the allTexts.pot file
+ * which will be used as a template for translation files (*.po and *.mo)
+ */
+ #if i18n_parsing
+ if( false ) sugoi.i18n.GetText.parse(["src", "lang/master","js","common"], "www/lang/allTexts.pot");
+ #end
+
+ App.current = new App();
+ var a : BaseApp = App.current;
+
+ a.sendHeaders();
+
+ if( !a.init() ) {
+ a = null;
+ return;
+ }
+ a.run();
+ a = null;
+ #if neko
+ if ( App.config.getInt("cache", 0) == 1 ) {
+ neko.Web.cacheModule(App.main);
+ }
+ #end
+ }
+}
diff --git a/src/sugoi/BaseController.hx b/src/sugoi/BaseController.hx
new file mode 100644
index 0000000..f9d6b47
--- /dev/null
+++ b/src/sugoi/BaseController.hx
@@ -0,0 +1,95 @@
+package sugoi;
+import sugoi.db.File;
+import sugoi.Web;
+import sugoi.ControllerAction;
+
+@:autoBuild(sugoi.tools.Macros.buildController())
+class BaseController {
+
+ var app : App;
+ var view : View;
+
+ public function new() {
+ app = App.current;
+ view = app.view;
+ }
+
+ function getParam( v : String ) {
+ return app.params.get(v);
+ }
+
+ function checkToken():Bool {
+ var token = haxe.crypto.Md5.encode(app.session.sid + App.config.KEY.substr(0,6));
+ view.token = token;
+ return app.params.get("token") == token;
+ }
+
+ function isAdmin() {
+ return app.user != null && app.user.isAdmin();
+ }
+
+ public function Redirect( url : String ) {
+ return RedirectAction(url);
+ }
+
+ public function Error( url : String, ?text : String ) {
+ return ErrorAction(url, text);
+ }
+
+ public function Ok( url : String, ?text : String ) {
+ return OkAction(url, text);
+ }
+
+ /**
+ * User uploaded images are stored in the db.File table.
+ * When there is an attempt to display an image like /file/***.jpg
+ * the .htaccess in /file/ redirects to this handler to generate the file from the DB
+ * @param fname
+ */
+ function doFile( fname : String ) {
+
+ //get the file from DB
+ var fid = Std.parseInt(fname);
+ var f = File.manager.get(fid, false);
+ var ext = fname.substr( fname.lastIndexOf(".") );//.png
+ if( f == null ) {
+ Sys.print("404 - File not found '"+StringTools.htmlEscape(fname)+"' id #"+fid);
+ return;
+ }
+ if ( fname != File.makeSign(fid) + ext ){
+ Sys.print("404 - File signature do not match '"+fname+"' != '"+File.makeSign(fid)+ ext+"'");
+ return;
+ }
+ var path;
+ var ch;
+ try {
+ path = Web.getCwd()+"/file/"+File.makeSign(f.id)+ext;
+ ch = sys.io.File.write(path,true);
+ } catch( e : Dynamic ) {
+ Sys.sleep(0.1); // wait for another process to write ?
+ Web.redirect(Web.getURI()+"?retry=1");
+ return;
+ }
+ ch.write(f.data);
+ ch.close();
+
+ try {
+ // get mtime of current index.n
+ #if neko
+ var s = sys.FileSystem.stat(Web.getCwd() + "index.n");
+ #else
+ var s = sys.FileSystem.stat(Web.getCwd() + "index.php");
+ #end
+ var mtime = s.mtime.toString();
+
+ // set mtime of new file
+ var p = new sys.io.Process("touch",["-m","-d",mtime,path]);
+ p.exitCode();
+ }catch( e : Dynamic ){
+ }
+
+ Web.redirect(Web.getURI()+"?reload=1");
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/sugoi/BaseView.hx b/src/sugoi/BaseView.hx
new file mode 100644
index 0000000..6c63dc3
--- /dev/null
+++ b/src/sugoi/BaseView.hx
@@ -0,0 +1,163 @@
+package sugoi;
+
+import sugoi.db.Variable;
+import sugoi.db.File;
+
+class BaseView implements Dynamic {
+
+ var _vcache : Map"+s+""); + var json = cast haxe.Json.parse(s); + if (json.status != "OK") throw "Google geocoding API Error : " + s; + var r : GeoCodingData = cast json.results; + return r; + } + + + + public function onReverseData(s:String) { + + //var out : GeoCodingData = [{address_components:[],formatted_address:null,}]; +// + //var json = haxe.Json.parse(s); + //if(json.status != "OK") throw "Google geocoding API Error : " + s; + //var arr : Array