@@ -41,12 +41,21 @@ def init():
def respond():
import webnotes
import webnotes.webutils
+ import MySQLdb
+
try:
return webnotes.webutils.render(webnotes.form_dict.get('page'))
except webnotes.SessionStopped:
print "Content-type: text/html"
print
print session_stopped
+ except MySQLdb.ProgrammingError, e:
+ if e.args[0]==1146:
+ print "Content-type: text/html"
+ print
+ print session_stopped % {"app_name": webnotes.get_config().app_name}
+ else:
+ raise e
if __name__=="__main__":
init()
diff --git a/public/js/legacy/form.js b/public/js/legacy/form.js
index 14589883c4..09bb860aea 100644
--- a/public/js/legacy/form.js
+++ b/public/js/legacy/form.js
@@ -101,7 +101,7 @@ _f.Frm.prototype.setup = function() {
});
this.frm_head = this.toolbar;
- // create area for print fomrat
+ // create area for print format
this.setup_print_layout();
// 2 column layout
@@ -278,7 +278,7 @@ _f.Frm.prototype.set_footnote = function(txt) {
_f.Frm.prototype.add_custom_button = function(label, fn, icon) {
- this.appframe.add_button(label, fn, icon || "icon-arrow-right");
+ return this.appframe.add_button(label, fn, icon || "icon-arrow-right");
}
_f.Frm.prototype.clear_custom_buttons = function() {
this.toolbar.refresh()
diff --git a/public/js/legacy/print_format.js b/public/js/legacy/print_format.js
index a7521117b1..0bb902b12c 100644
--- a/public/js/legacy/print_format.js
+++ b/public/js/legacy/print_format.js
@@ -63,7 +63,7 @@ $.extend(_p, {
\
'},
]
- })
+ });
dialog.$wrapper.find(".btn-print").click(function() {
var args = dialog.get_values();
@@ -85,7 +85,7 @@ $.extend(_p, {
dialog.onshow = function() {
var $print = dialog.fields_dict.print_format.$input;
- $print.add_options(cur_frm.print_formats);
+ $print.empty().add_options(cur_frm.print_formats);
if(cur_frm.$print_view_select && cur_frm.$print_view_select.val())
$print.val(cur_frm.$print_view_select.val());
diff --git a/public/js/lib/markdown.js b/public/js/lib/markdown.js
new file mode 100644
index 0000000000..65ee602359
--- /dev/null
+++ b/public/js/lib/markdown.js
@@ -0,0 +1,62 @@
+//
+// showdown.js -- A javascript port of Markdown.
+//
+// Copyright (c) 2007 John Fraser.
+//
+// Original Markdown Copyright (c) 2004-2005 John Gruber
+//
+//
+// Redistributable under a BSD-style open source license.
+// See license.txt for more information.
+//
+// The full source distribution is at:
+//
+// A A L
+// T C A
+// T K B
+//
+//
+//
+//
+// Wherever possible, Showdown is a straight, line-by-line port
+// of the Perl version of Markdown.
+//
+// This is not a normal parser design; it's basically just a
+// series of string substitutions. It's hard to read and
+// maintain this way, but keeping Showdown close to the original
+// design makes it easier to port new features.
+//
+// More importantly, Showdown behaves like markdown.pl in most
+// edge cases. So web applications can do client-side preview
+// in Javascript, and then build identical HTML on the server.
+//
+// This port needs the new RegExp functionality of ECMA 262,
+// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers
+// should do fine. Even with the new regular expression features,
+// We do a lot of work to emulate Perl's regex functionality.
+// The tricky changes in this file mostly have the "attacklab:"
+// label. Major or self-explanatory changes don't.
+//
+// Smart diff tools like Araxis Merge will be able to match up
+// this file with markdown.pl in a useful way. A little tweaking
+// helps: in a copy of markdown.pl, replace "#" with "//" and
+// replace "$text" with "text". Be sure to ignore whitespace
+// and line endings.
+//
+//
+// Showdown usage:
+//
+// var text = "Markdown *rocks*.";
+//
+// var converter = new Showdown.converter();
+// var html = converter.makeHtml(text);
+//
+// alert(html);
+//
+// Note: move the sample code to the bottom of this
+// file before uncommenting it.
+//
+//
+// Showdown namespace
+//
+var Showdown={extensions:{}},forEach=Showdown.forEach=function(a,b){if(typeof a.forEach=="function")a.forEach(b);else{var c,d=a.length;for(c=0;c?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|(?=~0))/gm,function(a,d,e,f,g){return d=d.toLowerCase(),b[d]=G(e),f?f+g:(g&&(c[d]=g.replace(/"/g,""")),"")}),a=a.replace(/~0/,""),a},m=function(a){a=a.replace(/\n/g,"\n\n");var b="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del|style|section|header|footer|nav|article|aside",c="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside";return a=a.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,n),a=a.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?<\/\2>[ \t]*(?=\n+)\n)/gm,n),a=a.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,n),a=a.replace(/(\n\n[ ]{0,3}[ \t]*(?=\n{2,}))/g,n),a=a.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,n),a=a.replace(/\n\n/g,"\n"),a},n=function(a,b){var c=b;return c=c.replace(/\n\n/g,"\n"),c=c.replace(/^\n/,""),c=c.replace(/\n+$/g,""),c="\n\n~K"+(d.push(c)-1)+"K\n\n",c},o=function(a){a=v(a);var b=A("");return a=a.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,b),a=a.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,b),a=a.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,b),a=x(a),a=y(a),a=E(a),a=m(a),a=F(a),a},p=function(a){return a=B(a),a=q(a),a=H(a),a=t(a),a=r(a),a=I(a),a=G(a),a=D(a),a=a.replace(/ +\n/g," \n"),a},q=function(a){var b=/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi;return a=a.replace(b,function(a){var b=a.replace(/(.)<\/?code>(?=.)/g,"$1`");return b=N(b,"\\`*_"),b}),a},r=function(a){return a=a.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,s),a=a.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,s),a=a.replace(/(\[([^\[\]]+)\])()()()()()/g,s),a},s=function(a,d,e,f,g,h,i,j){j==undefined&&(j="");var k=d,l=e,m=f.toLowerCase(),n=g,o=j;if(n==""){m==""&&(m=l.toLowerCase().replace(/ ?\n/g," ")),n="#"+m;if(b[m]!=undefined)n=b[m],c[m]!=undefined&&(o=c[m]);else{if(!(k.search(/\(\s*\)$/m)>-1))return k;n=""}}n=N(n,"*_");var p='"+l+"",p},t=function(a){return a=a.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,u),a=a.replace(/(!\[(.*?)\]\s?\([ \t]*()(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,u),a},u=function(a,d,e,f,g,h,i,j){var k=d,l=e,m=f.toLowerCase(),n=g,o=j;o||(o="");if(n==""){m==""&&(m=l.toLowerCase().replace(/ ?\n/g," ")),n="#"+m;if(b[m]==undefined)return k;n=b[m],c[m]!=undefined&&(o=c[m])}l=l.replace(/"/g,"""),n=N(n,"*_");var p='",p},v=function(a){function b(a){return a.replace(/[^\w]/g,"").toLowerCase()}return a=a.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,function(a,c){return A('
').insertAfter(module_top); + $('
').css({"margin-top": "0px"}) + .insertAfter(module_top); } else { var list_group = $('
\- \
diff --git a/public/js/wn/views/query_report.js b/public/js/wn/views/query_report.js
index 318dd356d5..e1664969fb 100644
--- a/public/js/wn/views/query_report.js
+++ b/public/js/wn/views/query_report.js
@@ -227,15 +227,17 @@ wn.views.QueryReport = Class.extend({
},
make_data: function(result, columns) {
var me = this;
- this.data = $.map(result, function(row, row_idx) {
+ this.data = [];
+ for(var row_idx=0, l=result.length; row_idx < l; row_idx++) {
+ var row = result[row_idx];
var newrow = {};
- for(var i=1, j=me.columns.length; i
- #login_wrapper {
- width: 330px;
- margin: 70px auto;
- }
-
- #login_wrapper,
- #login_wrapper h3 {
- color: #333;
- }
-
- #login_wrapper a {
- color: #0088cc;
- }
-
- .layout-wrapper {
- background-color: #fff;
- padding: 10px;
- box-shadow: 1px 1px 3px 3px #ccc;
- font-size: 12px;
- min-height: 100px;
- border-radius: 5px;
- }
-
- #login_wrapper h3 {
- text-align: center;
- }
-
- .login-banner {
- margin-bottom: 20px;
- }
-
- .login-box td {
- padding: 8px;
- }
- .login-box td input {
- margin-bottom: 0px;
- }
- .login-footer {
- text-align: center;
- padding: 15px;
- }
-
\ No newline at end of file
diff --git a/templates/js/login.js b/templates/js/login.js
index 7f50c83540..155f8225fd 100644
--- a/templates/js/login.js
+++ b/templates/js/login.js
@@ -6,12 +6,9 @@ $(document).ready(function(wrapper) {
$('#login_btn').click(login.do_login);
- $('#password').keypress(function(ev){
- if(ev.which==13 && $('#password').val()) {
- $('form').submit(function() {
- login.do_login();
- return false;
- });
+ $('#pass').keypress(function(ev){
+ if(ev.which==13 && $('#pass').val()) {
+ $("#login_btn").click();
}
});
$(document).trigger('login_rendered');
@@ -41,7 +38,7 @@ login.do_login = function(){
} else {
args.cmd = "login"
args.usr = ($("#login_id").val() || "").trim();
- args.pwd = $("#password").val();
+ args.pwd = $("#pass").val();
if(!args.usr || !args.pwd) {
login.set_message("Both login and password required.");
@@ -85,7 +82,7 @@ login.show_login = function() {
$("#password-row").toggle(true);
$("#full-name-row, #login_message").toggle(false);
$("#login_btn").html("Login").removeClass("btn-success");
- $("#switch-view").html('Forgot Password?');
if(!disable_signup) {
diff --git a/templates/pages/login.html b/templates/pages/login.html
index 70762dcec4..26c44f7275 100644
--- a/templates/pages/login.html
+++ b/templates/pages/login.html
@@ -4,58 +4,56 @@
- {% include "lib/templates/css/login.css" %}
+
{% endblock %}
{% set title="Login" %}
{% block body %}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- Home |
- ERPNext
© {{ copyright }}
- {% endif %}
+
+
+ Home | ERPNext
© {{ copyright }}
+ {% endif %}
+
+
{% endblock %}
\ No newline at end of file
diff --git a/webnotes/__init__.py b/webnotes/__init__.py
index 3c6113b2a5..93bdf11a7b 100644
--- a/webnotes/__init__.py
+++ b/webnotes/__init__.py
@@ -479,6 +479,7 @@ def get_config():
def update_config(path):
with open(path, "r") as configfile:
this_config = json.loads(configfile.read())
+ _config.app_name = this_config.get("app_name")
_config.modules.update(this_config["modules"])
_config.web.pages.update(this_config["web"]["pages"])
_config.web.generators.update(this_config["web"]["generators"])
diff --git a/webnotes/auth.py b/webnotes/auth.py
index 76db23d55f..3521ef6b06 100644
--- a/webnotes/auth.py
+++ b/webnotes/auth.py
@@ -156,10 +156,12 @@ class LoginManager:
from startup import event_handlers
if hasattr(event_handlers, method):
getattr(event_handlers, method)(self)
- return
except ImportError, e:
pass
+ cp = webnotes.bean("Control Panel", "Control Panel")
+ cp.run_method(method)
+
def validate_ip_address(self):
"""check if IP Address is valid"""
ip_list = webnotes.conn.get_value('Profile', self.user, 'restrict_ip', ignore=True)
diff --git a/webnotes/db.py b/webnotes/db.py
index 7af2839490..6ae170aa1a 100644
--- a/webnotes/db.py
+++ b/webnotes/db.py
@@ -19,7 +19,8 @@ class Database:
def __init__(self, host=None, user=None, password=None, ac_name=None, use_default = 0):
self.host = host or 'localhost'
self.user = user or conf.db_name
-
+ self.in_transaction = False
+
if ac_name:
self.user = self.get_db_login(ac_name) or conf.db_name
@@ -430,14 +431,18 @@ class Database:
return webnotes.defaults.get_defaults(parent)
def begin(self):
- return # not required
+ if not self.in_transaction:
+ self.sql("start transaction")
+ self.in_transaction = True
def commit(self):
self.sql("commit")
+ self.in_transaction = False
def rollback(self):
self.sql("ROLLBACK")
self.transaction_writes = 0
+ self.in_transaction = False
def field_exists(self, dt, fn):
return self.sql("select name from tabDocField where fieldname=%s and parent=%s", (dt, fn))
diff --git a/webnotes/install_lib/install.py b/webnotes/install_lib/install.py
index 012b906395..2a35874345 100755
--- a/webnotes/install_lib/install.py
+++ b/webnotes/install_lib/install.py
@@ -31,7 +31,7 @@ class Installer:
def import_from_db(self, target, source_path='', password = 'admin', verbose=0):
"""
a very simplified version, just for the time being..will eventually be deprecated once the framework stabilizes.
- """
+ """
# delete user (if exists)
self.dbman.delete_user(target)
@@ -73,6 +73,7 @@ class Installer:
# update admin password
self.create_auth_table()
self.update_admin_password(password)
+
return target
def install_app(self):
diff --git a/webnotes/model/code.py b/webnotes/model/code.py
index c5d5638961..e1b9d4e1c3 100644
--- a/webnotes/model/code.py
+++ b/webnotes/model/code.py
@@ -83,9 +83,10 @@ def get_server_obj(doc, doclist = [], basedoctype = ''):
# custom?
custom_script = get_custom_server_script(doc.doctype)
+
if custom_script:
global custom_class
-
+
exec custom_class + custom_script.replace('\t',' ') in locals()
return CustomDocType(doc, doclist)
diff --git a/webnotes/utils/__init__.py b/webnotes/utils/__init__.py
index a6d8bd78ae..1ac874a7d5 100644
--- a/webnotes/utils/__init__.py
+++ b/webnotes/utils/__init__.py
@@ -8,6 +8,7 @@ import webnotes
user_time_zone = None
user_format = None
+current_date = None
no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable',
'Button', 'Image', 'Graph']
@@ -193,7 +194,10 @@ def convert_utc_to_user_timezone(utc_timestamp):
def now():
"""return current datetime as yyyy-mm-dd hh:mm:ss"""
- return now_datetime().strftime('%Y-%m-%d %H:%M:%S')
+ if current_date:
+ return getdate(current_date).strftime("%Y-%m-%d") + " " + now_datetime().strftime('%H:%M:%S')
+ else:
+ return now_datetime().strftime('%Y-%m-%d %H:%M:%S')
def nowdate():
"""return current date as yyyy-mm-dd"""
diff --git a/webnotes/utils/scheduler.py b/webnotes/utils/scheduler.py
index 7fe88ef2d7..f5db923717 100644
--- a/webnotes/utils/scheduler.py
+++ b/webnotes/utils/scheduler.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
"""
Scheduler will call the following events from the module
-`startup.schedule_handler`
+`startup.schedule_handler` and Control Panel (for server scripts)
execute_always
execute_daily
@@ -74,6 +74,12 @@ def trigger(method):
except Exception:
return log(method)
+
+ try:
+ cp = webnotes.bean("Control Panel", "Control Panel")
+ cp.run_method(method)
+ except Exception:
+ return log(method)
def log(method):
"""log error in patch_log"""
diff --git a/wnf.py b/wnf.py
index b7bb645bcc..4f29493067 100755
--- a/wnf.py
+++ b/wnf.py
@@ -398,12 +398,12 @@ def run():
inst.import_from_db(options.install_fresh, verbose = 1)
elif options.make_demo:
- import utilities.make_demo
- utilities.make_demo.make()
+ import utilities.demo.make_demo
+ utilities.demo.make_demo.make()
elif options.make_demo_fresh:
- import utilities.make_demo
- utilities.make_demo.make(True)
+ import utilities.demo.make_demo
+ utilities.demo.make_demo.make(True)
elif options.diff_ref_file is not None:
import webnotes.modules.diff
Login
- -- - +
Login
+- {% if copyright %} -
+ {% if copyright %} +