diff --git a/core/page/desktop/desktop.js b/core/page/desktop/desktop.js index a0e9e07441..7038d89761 100644 --- a/core/page/desktop/desktop.js +++ b/core/page/desktop/desktop.js @@ -88,12 +88,13 @@ wn.core.pages.desktop.show_pending_notifications = function() { && wn.boot.notification_info.open_count_module[module]!=null) { sum = wn.boot.notification_info.open_count_module[module]; } - var notifier = $("#module-count-" + wn.modules[module]._link); - if(notifier.length) { - notifier.toggle(sum ? true : false); - notifier.find(".circle-text").html(sum || ""); + if (wn.modules[module]) { + var notifier = $("#module-count-" + wn.modules[module]._link); + if(notifier.length) { + notifier.toggle(sum ? true : false); + notifier.find(".circle-text").html(sum || ""); + } } - }); } diff --git a/public/js/wn/form/control.js b/public/js/wn/form/control.js index 4419fbc3b1..1879a6d8c3 100644 --- a/public/js/wn/form/control.js +++ b/public/js/wn/form/control.js @@ -370,6 +370,9 @@ wn.ui.form.ControlDate = wn.ui.form.ControlData.extend({ set_datepicker: function() { this.datepicker_options.dateFormat = (wn.boot.sysdefaults.date_format || 'yyyy-mm-dd').replace("yyyy", "yy") + if(this.not_in_form && this.dialog_wrapper) { + this.$input.css("z-index", cint($(this.dialog_wrapper).zIndex())); + } this.$input.datepicker(this.datepicker_options); }, parse: function(value) { @@ -408,8 +411,12 @@ wn.ui.form.ControlTime = wn.ui.form.ControlData.extend({ wn.ui.form.ControlDatetime = wn.ui.form.ControlDate.extend({ set_datepicker: function() { this.datepicker_options.dateFormat = - (wn.boot.sysdefaults.date_format || 'yy-mm-dd').replace('yyyy','yy') + (wn.boot.sysdefaults.date_format || 'yy-mm-dd').replace('yyyy','yy'); this.datepicker_options.timeFormat = "hh:mm:ss"; + + if(this.not_in_form && this.dialog_wrapper) { + this.$input.css("z-index", cint($(this.dialog_wrapper).zIndex())); + } this.$input.datetimepicker(this.datepicker_options); }, diff --git a/public/js/wn/form/grid.js b/public/js/wn/form/grid.js index 292b1b075c..df17afd835 100644 --- a/public/js/wn/form/grid.js +++ b/public/js/wn/form/grid.js @@ -51,28 +51,29 @@ wn.ui.form.Grid = Class.extend({ if(!force && this.data_rows_are_same(data)) { // soft refresh this.header_row.refresh(); - $.each(this.grid_rows, function(i, g) { - g.refresh(); - }); + for(var i in this.grid_rows) { + this.grid_rows[i].refresh(); + } } else { // redraw this.wrapper.find(".grid-row").remove(); this.make_head(); this.grid_rows = []; this.grid_rows_by_docname = {}; - $.each(data || [], function(ri, d) { + for(var ri in data) { + var d = data[ri]; var grid_row = new wn.ui.form.GridRow({ parent: $rows, - parent_df: me.df, - docfields: me.docfields, + parent_df: this.df, + docfields: this.docfields, doc: d, - frm: me.frm, - grid: me + frm: this.frm, + grid: this }); - me.grid_rows.push(grid_row) - me.grid_rows_by_docname[d.name] = grid_row; - }); - + this.grid_rows.push(grid_row) + this.grid_rows_by_docname[d.name] = grid_row; + } + this.wrapper.find(".grid-add-row").toggle(this.is_editable()); if(this.is_editable()) { this.make_sortable($rows); @@ -183,9 +184,7 @@ wn.ui.form.GridRow = Class.extend({ return false; }); - this.form_panel = $('').appendTo(this.wrapper); - - $('
').appendTo(this.wrapper); + this.divider = $('
').appendTo(this.wrapper); this.set_row_index(); this.make_static_display(); @@ -220,6 +219,7 @@ wn.ui.form.GridRow = Class.extend({ this.doc = locals[this.doc.doctype][this.doc.name]; // re write columns + this.grid.static_display_template = null; this.make_static_display(); // refersh form fields @@ -230,76 +230,38 @@ wn.ui.form.GridRow = Class.extend({ } }, make_static_display: function() { - var me = this, - total_colsize = 1; - me.row.empty(); - col = $('
' + (me.doc ? me.doc.idx : "#")+ '
') - .appendTo(me.row); + var me = this; + this.make_static_display_template(); + this.row.empty(); + $('
' + (this.doc ? this.doc.idx : "#")+ '
') + .appendTo(this.row); - $.each(me.docfields, function(ci, df) { - if(!df.hidden && df.in_list_view && me.grid.frm.get_perm(df.permlevel, READ) - && !in_list(["Section Break", "Column Break"], df.fieldtype)) { - var colsize = 2, - txt = me.doc ? - wn.format(me.doc[df.fieldname], df, null, me.doc) : - wn._(df.label); - switch(df.fieldtype) { - case "Text": - case "Small Text": - colsize = 3; - break; - case "Check": - colsize = 1; - break; - case "Select": - txt = wn._(txt) - } - total_colsize += colsize - if(total_colsize > 11) - return false; - $col = $('
') - .html(txt) - .attr("data-fieldname", df.fieldname) - .data("df", df) - .appendTo(me.row) - - if(["Text", "Small Text"].indexOf(df.fieldtype)!==-1) { - $col.addClass("grid-overflow-no-ellipsis"); - } else { - $col.addClass("grid-overflow-ellipsis"); - } - - if(in_list(["Int", "Currency", "Float"], df.fieldtype)) - $col.addClass("text-right"); + for(var ci in this.static_display_template) { + var df = this.static_display_template[ci][0]; + var colsize = this.static_display_template[ci][1]; + var txt = this.doc ? + wn.format(this.doc[df.fieldname], df, null, this.doc) : + wn._(df.label); + if(df.fieldtype === "Select") { + txt = wn._(txt); } - - }); + var add_class = (["Text", "Small Text"].indexOf(df.fieldtype)===-1) ? + " grid-overflow-ellipsis" : " grid-overflow-no-ellipsis"; + add_class += (["Int", "Currency", "Float"].indexOf(df.fieldtype)!==-1) ? + " text-right": ""; - // redistribute if total-col size is less than 12 - var passes = 0; - while(total_colsize < 11 && passes < 10) { - me.row.find(".col").each(function() { - var $col = $(this); - if(!$col.hasClass("col-xs-1") - && !in_list(["Int", "Currency", "Float"], $col.data("df").fieldtype)) { - for(var i=2; i<12; i++) { - if($col.hasClass("col-xs-" + i)) { - $col.removeClass("col-xs-" + i).addClass("col-xs-" + (i+1)); - total_colsize++; - break; - } - } - } - if(total_colsize >= 11) - return false; - }); - passes++; + $col = $('
') + .html(txt) + .attr("data-fieldname", df.fieldname) + .data("df", df) + .appendTo(this.row) } + // TODO find a better solution // append button column - if(me.doc && this.grid.is_editable()) { - if(!me.grid.$row_actions) { - me.grid.$row_actions = $('
\ \ @@ -307,11 +269,12 @@ wn.ui.form.GridRow = Class.extend({ \
'); } - $col = me.grid.$row_actions.clone().appendTo(me.row); + $col = this.grid.$row_actions.clone().appendTo(this.row); if($col.width() < 50) { - $col.remove(); + $col.toggle(false); } else { + $col.toggle(true); $col.find(".grid-insert-row").click(function() { me.insert(); return false; }); $col.find(".grid-delete-row").click(function() { me.remove(); return false; }); } @@ -319,6 +282,49 @@ wn.ui.form.GridRow = Class.extend({ $(this.frm.wrapper).trigger("grid-row-render", [this]); }, + make_static_display_template: function() { + if(this.static_display_template) return; + + var total_colsize = 1; + this.static_display_template = []; + for(var ci in this.docfields) { + var df = this.docfields[ci]; + if(!df.hidden && df.in_list_view && this.grid.frm.get_perm(df.permlevel, READ) + && !in_list(["Section Break", "Column Break"], df.fieldtype)) { + var colsize = 2; + switch(df.fieldtype) { + case "Text": + case "Small Text": + colsize = 3; + break; + case "Check": + colsize = 1; + break; + } + total_colsize += colsize + if(total_colsize > 11) + return false; + this.static_display_template.push([df, colsize]); + } + } + + // redistribute if total-col size is less than 12 + var passes = 0; + while(total_colsize < 11 && passes < 10) { + for(var i in this.static_display_template) { + var df = this.static_display_template[i][0]; + var colsize = this.static_display_template[i][1]; + if(colsize>1 && colsize<12 && ["Int", "Currency", "Float"].indexOf(df.fieldtype)===-1) { + this.static_display_template[i][1] += 1; + total_colsize++; + } + + if(total_colsize >= 11) + break; + } + passes++; + } + }, toggle_view: function(show, callback) { if(!this.doc) return this; @@ -349,10 +355,15 @@ wn.ui.form.GridRow = Class.extend({ } this.wrapper.toggleClass("grid-row-open", this.show); - - this.show && this.render_form() - this.show && this.row.toggle(false); - + + if(this.show) { + if(!this.form_panel) { + this.form_panel = $('') + .insertBefore(this.divider); + } + this.render_form(); + this.row.toggle(false); + } this.form_panel.toggle(this.show); if(me.show) { if(me.frm.doc.docstatus===0) diff --git a/webnotes/db.py b/webnotes/db.py index ad09b1299f..bb73040767 100644 --- a/webnotes/db.py +++ b/webnotes/db.py @@ -155,7 +155,7 @@ class Database: if query[:6].lower() in ['update', 'insert']: self.transaction_writes += 1 - if self.transaction_writes > 10000: + if not webnotes.in_test and self.transaction_writes > 10000: if self.auto_commit_on_many_writes: webnotes.conn.commit() webnotes.conn.begin() diff --git a/webnotes/memc.py b/webnotes/memc.py index 42909f4e55..b230c36632 100644 --- a/webnotes/memc.py +++ b/webnotes/memc.py @@ -18,7 +18,7 @@ class MClient(memcache.Client): return builder() val = self.get(self.n(key)) - if val==None and builder: + if not val and builder: val = builder() self.set_value(key, val) return val diff --git a/webnotes/model/bean.py b/webnotes/model/bean.py index 7c4f395c62..18f85596a2 100644 --- a/webnotes/model/bean.py +++ b/webnotes/model/bean.py @@ -213,6 +213,8 @@ class Bean: d.parent = self.doc.name if not d.idx: d.idx = idx_map.setdefault(d.parentfield, 0) + 1 + else: + d.idx = cint(d.idx) if is_local: # if parent is new, all children should be new d.fields["__islocal"] = 1 @@ -220,18 +222,18 @@ class Bean: idx_map[d.parentfield] = d.idx - def run_method(self, method): + def run_method(self, method, *args, **kwargs): self.make_controller() if hasattr(self.controller, method): - getattr(self.controller, method)() + getattr(self.controller, method)(*args, **kwargs) if hasattr(self.controller, 'custom_' + method): - getattr(self.controller, 'custom_' + method)() + getattr(self.controller, 'custom_' + method)(*args, **kwargs) notify(self.controller, method) self.set_doclist(self.controller.doclist) - + def get_method(self, method): self.make_controller() return getattr(self.controller, method, None) diff --git a/webnotes/utils/file_manager.py b/webnotes/utils/file_manager.py index acb8901cf8..9eb11244d4 100644 --- a/webnotes/utils/file_manager.py +++ b/webnotes/utils/file_manager.py @@ -74,7 +74,7 @@ def save_file(fname, content, dt, dn): file_size = check_max_file_size(content) temp_fname = write_file(content, files_path) fname = scrub_file_name(fname) - fpath = os.path.join(files_path, fname) + fpath = os.path.join(files_path, fname).encode("utf-8") fname_parts = fname.split(".", -1) main = ".".join(fname_parts[:-1]) @@ -96,10 +96,10 @@ def save_file(fname, content, dt, dn): fname = get_new_fname_based_on_version(files_path, main, extn, versions) # rename - os.rename(temp_fname, os.path.join(files_path, fname)) + os.rename(temp_fname, fpath) else: # rename new file - os.rename(temp_fname, os.path.join(files_path, fname)) + os.rename(temp_fname, fpath) f = webnotes.bean({ "doctype": "File Data", @@ -124,7 +124,7 @@ def get_new_fname_based_on_version(files_path, main, extn, versions): version = 1 new_fname = main + "-" + str(version) + "." + extn - while os.path.exists(os.path.join(files_path, new_fname)): + while os.path.exists(os.path.join(files_path, new_fname).encode("utf-8")): version += 1 new_fname = main + "-" + str(version) + "." + extn if version > 100: diff --git a/webnotes/webutils.py b/webnotes/webutils.py index 3ae7c93996..c66d350904 100644 --- a/webnotes/webutils.py +++ b/webnotes/webutils.py @@ -117,6 +117,12 @@ def build_sitemap(): sitemap = {} config = webnotes.cache().get_value("website_sitemap_config", build_website_sitemap_config) sitemap.update(config["pages"]) + + # pages + for p in config["pages"].values(): + if p.get("controller"): + module = webnotes.get_module(p["controller"]) + p["no_cache"] = getattr(module, "no_cache", False) # generators for g in config["generators"].values(): @@ -134,6 +140,7 @@ def build_sitemap(): `tab%s` %s""" % (page_name_field, module.doctype, condition)): opts = g.copy() opts["doctype"] = module.doctype + opts["no_cache"] = getattr(module, "no_cache", False) opts["page_name"] = page_name if page_name_field != "page_name": opts["page_name_field"] = page_name_field @@ -181,7 +188,7 @@ def build_website_sitemap_config(): return options - for path, folders, files in os.walk(basepath): + for path, folders, files in os.walk(basepath, followlinks=True): if os.path.basename(path)=="pages" and os.path.basename(os.path.dirname(path))=="templates": for fname in files: if fname.split(".")[-1] in ("html", "xml"): @@ -263,10 +270,13 @@ def clear_cache(page_name=None): else: cache = webnotes.cache() for p in get_all_pages(): - cache.delete_value("page:" + p) + if p is not None: + cache.delete_value("page:" + p) + cache.delete_value("page:index") cache.delete_value("website_sitemap") cache.delete_value("website_sitemap_config") + def get_website_sitemap(): return webnotes.cache().get_value("website_sitemap", build_sitemap) @@ -275,7 +285,9 @@ def get_all_pages(): def delete_page_cache(page_name): if page_name: - webnotes.cache().delete_value("page:" + page_name) + cache = webnotes.cache() + cache.delete_value("page:" + page_name) + cache.delete_value("website_sitemap") def get_hex_shade(color, percent): def p(c): @@ -337,7 +349,7 @@ def page_name(title): """make page name from title""" import re name = title.lower() - name = re.sub('[~!@#$%^&*()<>,."\']', '', name) + name = re.sub('[~!@#$%^&*+()<>,."\']', '', name) name = re.sub('[:/]', '-', name) name = '-'.join(name.split()) diff --git a/website/sitemap.py b/website/sitemap.py new file mode 100644 index 0000000000..d1b9267977 --- /dev/null +++ b/website/sitemap.py @@ -0,0 +1,30 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. +# MIT License. See license.txt + +from __future__ import unicode_literals +import urllib +import webnotes +import webnotes.webutils +from webnotes.utils import nowdate + +def generate(domain): + """generate the sitemap XML""" + + frame_xml = """ + %s + """ + + link_xml = """\n%s%s""" + + site_map = "" + if domain: + today = nowdate() + + for page_name, page_options in webnotes.webutils.get_website_sitemap().items(): + if page_options.get("no_cache"): + continue + + url = urllib.basejoin(domain, urllib.quote(page_name.encode("utf-8"))) + site_map += link_xml % (url, today) + + return frame_xml % site_map diff --git a/wnf.py b/wnf.py index fce904c27a..7467a48fde 100755 --- a/wnf.py +++ b/wnf.py @@ -327,4 +327,4 @@ def search_replace_with_prompt(fpath, txt1, txt2, force=False): print colored('Updated', 'green') if __name__=="__main__": - main() + main() \ No newline at end of file