diff --git a/core/page/data_import_tool/data_import_tool.py b/core/page/data_import_tool/data_import_tool.py index 52a5a8803f..fdeb636b78 100644 --- a/core/page/data_import_tool/data_import_tool.py +++ b/core/page/data_import_tool/data_import_tool.py @@ -167,7 +167,12 @@ def get_template(): w.writerow([data_keys.data_separator]) def add_data(): - def add_data_row(row_group, dt, d, rowidx): + def add_data_row(row_group, dt, doc, rowidx): + d = doc.copy() + if all_doctypes: + d.name = '"'+ d.name+'"' + d.modified = '"'+ d.modified+'"' + if len(row_group) < rowidx + 1: row_group.append([""] * (len(columns) + 1)) row = row_group[rowidx] @@ -180,8 +185,6 @@ def get_template(): for doc in data: # add main table row_group = [] - if all_doctypes: - doc.modified = '"'+ doc.modified+'"' add_data_row(row_group, doctype, doc, 0) @@ -311,6 +314,11 @@ def upload(): d[fieldname] = flt(d[fieldname]) except IndexError, e: pass + + # scrub quotes from name and modified + for fieldname in ("name", "modified"): + if d.get(fieldname) and d[fieldname].startswith('"'): + d[fieldname] = d[fieldname][1:-1] if sum([0 if not val else 1 for val in d.values()]): d['doctype'] = dt @@ -385,7 +393,6 @@ def upload(): bean = webnotes.bean(doclist) if overwrite and bean.doc.modified: # remove the extra quotes added to preserve date formatting - bean.doc.modified = bean.doc.modified[1:-1] bean.save() ret.append('Updated row (#%d) %s' % (row_idx + 1, getlink(bean.doc.doctype, bean.doc.name))) else: diff --git a/public/build.json b/public/build.json index 3d4c8eacf7..35aba9ad01 100644 --- a/public/build.json +++ b/public/build.json @@ -135,14 +135,14 @@ }, { "public/js/slickgrid.min.js": [ - 'lib/public/js/lib/slickgrid/jquery.event.drag.min.js', - 'lib/public/js/lib/slickgrid/plugins/slick.cellrangedecorator.js', - 'lib/public/js/lib/slickgrid/plugins/slick.cellrangeselector.js', - 'lib/public/js/lib/slickgrid/plugins/slick.cellselectionmodel.js', - 'lib/public/js/lib/slickgrid/plugins/slick.cellexternalcopymanager.js', - 'lib/public/js/lib/slickgrid/slick.core.js', - 'lib/public/js/lib/slickgrid/slick.grid.js', - 'lib/public/js/lib/slickgrid/slick.dataview.js', + "lib/public/js/lib/slickgrid/jquery.event.drag.min.js", + "lib/public/js/lib/slickgrid/plugins/slick.cellrangedecorator.js", + "lib/public/js/lib/slickgrid/plugins/slick.cellrangeselector.js", + "lib/public/js/lib/slickgrid/plugins/slick.cellselectionmodel.js", + "lib/public/js/lib/slickgrid/plugins/slick.cellexternalcopymanager.js", + "lib/public/js/lib/slickgrid/slick.core.js", + "lib/public/js/lib/slickgrid/slick.grid.js", + "lib/public/js/lib/slickgrid/slick.dataview.js", ] } ] diff --git a/public/js/legacy/datetime.js b/public/js/legacy/datetime.js index f38c228fb5..ef6eeb8a69 100644 --- a/public/js/legacy/datetime.js +++ b/public/js/legacy/datetime.js @@ -238,7 +238,7 @@ function prettyDate(time){ if ( isNaN(day_diff) || day_diff < 0 ) return ''; - return day_diff == 0 && ( + return when = day_diff == 0 && ( diff < 60 && "just now" || diff < 120 && "1 minute ago" || diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" || @@ -249,20 +249,23 @@ function prettyDate(time){ day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago" || day_diff < 365 && Math.ceil( day_diff / 30) + " months ago" || "> " + Math.floor( day_diff / 365 ) + " year(s) ago"; + } -// If jQuery is included in the page, adds a jQuery plugin to handle it as well -if ( typeof jQuery != "undefined" ) - jQuery.fn.prettyDate = function(){ - return this.each(function(){ - var date = prettyDate(this.title); - if ( date ) - jQuery(this).text( date ); - }); - }; -var comment_when = prettyDate; +var comment_when = function(datetime) { + return '' + prettyDate(datetime) + ''; +}; wn.datetime.comment_when = prettyDate; +wn.datetime.refresh_when = function() { + if(jQuery) { + $(".wn-timestamp").each(function() { + $(this).html(prettyDate($(this).attr("data-timestamp"))); + }) + } +} + +setInterval(function() { wn.datetime.refresh_when() }, 60000); // refresh every minute // globals (deprecate) var date = dateutil = wn.datetime; diff --git a/public/js/wn/upload.js b/public/js/wn/upload.js index edbe1a3e52..23a7aed6f0 100644 --- a/public/js/wn/upload.js +++ b/public/js/wn/upload.js @@ -46,12 +46,10 @@ wn.upload = { }, upload_file: function(fileobj, args, callback, onerror) { if(!fileobj && !args.file_url) { - msgprint(_("Please attach a file or set a URL")); + msgprint(wn._("Please attach a file or set a URL")); return; } - - var _upload_file = function() { var msgbox = msgprint(wn._("Uploading...")); return wn.call({ diff --git a/webnotes/client.py b/webnotes/client.py index 5618ece582..df104a0a2a 100644 --- a/webnotes/client.py +++ b/webnotes/client.py @@ -67,7 +67,7 @@ def submit(doclist): doclistobj = webnotes.bean(doclist) doclistobj.submit() - + return [d.fields for d in doclist] @webnotes.whitelist() diff --git a/webnotes/db.py b/webnotes/db.py index 38f5e3951c..cf81d3129d 100644 --- a/webnotes/db.py +++ b/webnotes/db.py @@ -388,6 +388,9 @@ class Database: if field!="modified": self.set_value(dt, dn, "modified", modified or now()) + def set_in_doc(self, doc, field, val): + self.set(doc, field, val) + def set(self, doc, field, val): from webnotes.utils import now doc.modified = now() diff --git a/webnotes/model/doc.py b/webnotes/model/doc.py index 7318ad9d61..0289868cd5 100755 --- a/webnotes/model/doc.py +++ b/webnotes/model/doc.py @@ -386,15 +386,16 @@ class Document: self.set_idx() # if required, make new - if self.fields.get('__islocal') and (not res.get('issingle')): - r = self._insert(res.get('autoname'), res.get('istable'), res.get('name_case'), - make_autoname, keep_timestamps = keep_timestamps) - if r: - return r - - else: - if not res.get('issingle') and not webnotes.conn.exists(self.doctype, self.name): - webnotes.msgprint("""This document was updated before your change. Please refresh before saving.""", raise_exception=1) + if not res.get('issingle'): + if self.fields.get('__islocal'): + r = self._insert(res.get('autoname'), res.get('istable'), res.get('name_case'), + make_autoname, keep_timestamps = keep_timestamps) + if r: + return r + else: + if not webnotes.conn.exists(self.doctype, self.name): + webnotes.msgprint(webnotes._("Cannot update a non-exiting record, try inserting.") + ": " + self.doctype + " / " + self.name, + raise_exception=1) # save the values self._update_values(res.get('issingle'), diff --git a/webnotes/utils/file_manager.py b/webnotes/utils/file_manager.py index b4f5c69b6a..ed4e237cee 100644 --- a/webnotes/utils/file_manager.py +++ b/webnotes/utils/file_manager.py @@ -62,7 +62,7 @@ def get_uploaded_content(): return None, None def save_file(fname, content, dt, dn): - from filecmp import cmp + import filecmp files_path = get_files_path() file_size = check_max_file_size(content) @@ -78,7 +78,7 @@ def save_file(fname, content, dt, dn): if versions: found_match = False for version in versions: - if cmp(os.path.join(files_path, version), temp_fname): + if filecmp.cmp(os.path.join(files_path, version), temp_fname): # remove new file, already exists! os.remove(temp_fname) fname = version @@ -126,7 +126,7 @@ def get_new_fname_based_on_version(files_path, main, extn, versions): return new_fname -def scrub_file_name(fname): +def scrub_file_name(fname): if '\\' in fname: fname = fname.split('\\')[-1] if '/' in fname: diff --git a/webnotes/webutils.py b/webnotes/webutils.py index c8eae065eb..dc80871939 100644 --- a/webnotes/webutils.py +++ b/webnotes/webutils.py @@ -27,10 +27,7 @@ def render_page(page_name): """get page html""" page_name = scrub_page_name(page_name) html = '' - - if page_name=="index": - page_name = get_home_page() - + if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0): html = webnotes.cache().get_value("page:" + page_name) from_cache = True @@ -65,7 +62,13 @@ def build_page(page_name): page_options = sitemap.get(page_name) if not page_options: - raise PageNotFoundError + if page_name=="index": + # page not found, try home page + page_options = sitemap.get(get_home_page()) + if not page_options: + raise PageNotFoundError + else: + raise PageNotFoundError basepath = webnotes.utils.get_base_path() module = None diff --git a/website/css/website.css b/website/css/website.css index 4cd7ac7735..d82076aa15 100644 --- a/website/css/website.css +++ b/website/css/website.css @@ -141,6 +141,11 @@ div.web-footer { } } +.navbar { + box-shadow: none; + border-radius: 0px; +} + .panel-heading, .panel-body { padding-left: 15px; diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css index 7abdb4b89f..c306194afd 100644 --- a/website/doctype/style_settings/custom_template.css +++ b/website/doctype/style_settings/custom_template.css @@ -71,8 +71,6 @@ div.web-footer, div.web-footer a { } .navbar { - box-shadow: none; - border-radius: 0px; background-color: #{{ doc.top_bar_background}}; background-repeat: repeat-x; background-image: none; diff --git a/website/templates/base.html b/website/templates/base.html index aa45dfcfdf..c9f27acf94 100644 --- a/website/templates/base.html +++ b/website/templates/base.html @@ -12,8 +12,9 @@ - {% if meta_description -%} - {%- endif %} + {% block head %}{% endblock %} + {% if meta_description -%} + {%- endif %} {% block javascript -%} {% if javascript %}{% endif %} {%- endblock %} diff --git a/wnf.py b/wnf.py index 6edaa5ef61..962a52993f 100755 --- a/wnf.py +++ b/wnf.py @@ -282,6 +282,14 @@ def setup_options(): parser.add_option("--make_conf", default=False, action="store_true", help="Create new conf.py file") + # bean helpers + parser.add_option('--export_doclist', nargs=3, metavar="DOCTYPE NAME PATH", + help="""Export doclist as json to the given path, use '-' as name for Singles.""") + + parser.add_option('--import_doclist', nargs=1, metavar="PATH", + help="""Import (insert/update) doclist. If the argument is a directory, all files ending with .json are imported""") + + return parser.parse_args() def run(): @@ -511,6 +519,33 @@ def run(): from core.doctype.documentation_tool.documentation_tool import write_static write_static() + elif options.export_doclist: + import json + from webnotes.handler import json_handler + args = list(options.export_doclist) + if args[1]=="-": args[1] = args[0] + with open(args[2], "w") as outfile: + outfile.write(json.dumps([d.fields for d in \ + webnotes.bean(args[0], args[1]).doclist], default=json_handler, indent=1, sort_keys=True)) + + elif options.import_doclist: + import json + if os.path.isdir(options.import_doclist): + docs = [os.path.join(options.import_doclist, f) \ + for f in os.listdir(options.import_doclist) if f.endswith(".json")] + else: + docs = [options.import_doclist] + + for f in docs: + with open(f, "r") as infile: + doclist = json.loads(infile.read()) + if webnotes.conn.exists(doclist[0]["doctype"], doclist[0]["name"]): + b = webnotes.bean(doclist).save() + print "Updated: %s, %s" % (b.doc.doctype, b.doc.name) + else: + b = webnotes.bean(doclist).insert() + print "Inserted: %s, %s" % (b.doc.doctype, b.doc.name) + elif options.reset_perms: for d in webnotes.conn.sql_list("""select name from `tabDocType` where ifnull(istable, 0)=0 and ifnull(custom, 0)=0"""):