@@ -167,7 +167,12 @@ def get_template(): | |||||
w.writerow([data_keys.data_separator]) | w.writerow([data_keys.data_separator]) | ||||
def add_data(): | 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: | if len(row_group) < rowidx + 1: | ||||
row_group.append([""] * (len(columns) + 1)) | row_group.append([""] * (len(columns) + 1)) | ||||
row = row_group[rowidx] | row = row_group[rowidx] | ||||
@@ -180,8 +185,6 @@ def get_template(): | |||||
for doc in data: | for doc in data: | ||||
# add main table | # add main table | ||||
row_group = [] | row_group = [] | ||||
if all_doctypes: | |||||
doc.modified = '"'+ doc.modified+'"' | |||||
add_data_row(row_group, doctype, doc, 0) | add_data_row(row_group, doctype, doc, 0) | ||||
@@ -311,6 +314,11 @@ def upload(): | |||||
d[fieldname] = flt(d[fieldname]) | d[fieldname] = flt(d[fieldname]) | ||||
except IndexError, e: | except IndexError, e: | ||||
pass | 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()]): | if sum([0 if not val else 1 for val in d.values()]): | ||||
d['doctype'] = dt | d['doctype'] = dt | ||||
@@ -385,7 +393,6 @@ def upload(): | |||||
bean = webnotes.bean(doclist) | bean = webnotes.bean(doclist) | ||||
if overwrite and bean.doc.modified: | if overwrite and bean.doc.modified: | ||||
# remove the extra quotes added to preserve date formatting | # remove the extra quotes added to preserve date formatting | ||||
bean.doc.modified = bean.doc.modified[1:-1] | |||||
bean.save() | bean.save() | ||||
ret.append('Updated row (#%d) %s' % (row_idx + 1, getlink(bean.doc.doctype, bean.doc.name))) | ret.append('Updated row (#%d) %s' % (row_idx + 1, getlink(bean.doc.doctype, bean.doc.name))) | ||||
else: | else: | ||||
@@ -135,14 +135,14 @@ | |||||
}, | }, | ||||
{ | { | ||||
"public/js/slickgrid.min.js": [ | "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", | |||||
] | ] | ||||
} | } | ||||
] | ] | ||||
@@ -238,7 +238,7 @@ function prettyDate(time){ | |||||
if ( isNaN(day_diff) || day_diff < 0 ) | if ( isNaN(day_diff) || day_diff < 0 ) | ||||
return ''; | return ''; | ||||
return day_diff == 0 && ( | |||||
return when = day_diff == 0 && ( | |||||
diff < 60 && "just now" || | diff < 60 && "just now" || | ||||
diff < 120 && "1 minute ago" || | diff < 120 && "1 minute ago" || | ||||
diff < 3600 && Math.floor( diff / 60 ) + " minutes 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 < 31 && Math.ceil( day_diff / 7 ) + " weeks ago" || | ||||
day_diff < 365 && Math.ceil( day_diff / 30) + " months ago" || | day_diff < 365 && Math.ceil( day_diff / 30) + " months ago" || | ||||
"> " + Math.floor( day_diff / 365 ) + " year(s) 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 '<span class="wn-timestamp" data-timestamp="'+datetime+'">' + prettyDate(datetime) + '</span>'; | |||||
}; | |||||
wn.datetime.comment_when = prettyDate; | 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) | // globals (deprecate) | ||||
var date = dateutil = wn.datetime; | var date = dateutil = wn.datetime; | ||||
@@ -46,12 +46,10 @@ wn.upload = { | |||||
}, | }, | ||||
upload_file: function(fileobj, args, callback, onerror) { | upload_file: function(fileobj, args, callback, onerror) { | ||||
if(!fileobj && !args.file_url) { | 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; | return; | ||||
} | } | ||||
var _upload_file = function() { | var _upload_file = function() { | ||||
var msgbox = msgprint(wn._("Uploading...")); | var msgbox = msgprint(wn._("Uploading...")); | ||||
return wn.call({ | return wn.call({ | ||||
@@ -67,7 +67,7 @@ def submit(doclist): | |||||
doclistobj = webnotes.bean(doclist) | doclistobj = webnotes.bean(doclist) | ||||
doclistobj.submit() | doclistobj.submit() | ||||
return [d.fields for d in doclist] | return [d.fields for d in doclist] | ||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
@@ -388,6 +388,9 @@ class Database: | |||||
if field!="modified": | if field!="modified": | ||||
self.set_value(dt, dn, "modified", modified or now()) | 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): | def set(self, doc, field, val): | ||||
from webnotes.utils import now | from webnotes.utils import now | ||||
doc.modified = now() | doc.modified = now() | ||||
@@ -386,15 +386,16 @@ class Document: | |||||
self.set_idx() | self.set_idx() | ||||
# if required, make new | # 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 | # save the values | ||||
self._update_values(res.get('issingle'), | self._update_values(res.get('issingle'), | ||||
@@ -62,7 +62,7 @@ def get_uploaded_content(): | |||||
return None, None | return None, None | ||||
def save_file(fname, content, dt, dn): | def save_file(fname, content, dt, dn): | ||||
from filecmp import cmp | |||||
import filecmp | |||||
files_path = get_files_path() | files_path = get_files_path() | ||||
file_size = check_max_file_size(content) | file_size = check_max_file_size(content) | ||||
@@ -78,7 +78,7 @@ def save_file(fname, content, dt, dn): | |||||
if versions: | if versions: | ||||
found_match = False | found_match = False | ||||
for version in versions: | 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! | # remove new file, already exists! | ||||
os.remove(temp_fname) | os.remove(temp_fname) | ||||
fname = version | fname = version | ||||
@@ -126,7 +126,7 @@ def get_new_fname_based_on_version(files_path, main, extn, versions): | |||||
return new_fname | return new_fname | ||||
def scrub_file_name(fname): | |||||
def scrub_file_name(fname): | |||||
if '\\' in fname: | if '\\' in fname: | ||||
fname = fname.split('\\')[-1] | fname = fname.split('\\')[-1] | ||||
if '/' in fname: | if '/' in fname: | ||||
@@ -27,10 +27,7 @@ def render_page(page_name): | |||||
"""get page html""" | """get page html""" | ||||
page_name = scrub_page_name(page_name) | page_name = scrub_page_name(page_name) | ||||
html = '' | html = '' | ||||
if page_name=="index": | |||||
page_name = get_home_page() | |||||
if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0): | if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0): | ||||
html = webnotes.cache().get_value("page:" + page_name) | html = webnotes.cache().get_value("page:" + page_name) | ||||
from_cache = True | from_cache = True | ||||
@@ -65,7 +62,13 @@ def build_page(page_name): | |||||
page_options = sitemap.get(page_name) | page_options = sitemap.get(page_name) | ||||
if not page_options: | 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() | basepath = webnotes.utils.get_base_path() | ||||
module = None | module = None | ||||
@@ -141,6 +141,11 @@ div.web-footer { | |||||
} | } | ||||
} | } | ||||
.navbar { | |||||
box-shadow: none; | |||||
border-radius: 0px; | |||||
} | |||||
.panel-heading, | .panel-heading, | ||||
.panel-body { | .panel-body { | ||||
padding-left: 15px; | padding-left: 15px; | ||||
@@ -71,8 +71,6 @@ div.web-footer, div.web-footer a { | |||||
} | } | ||||
.navbar { | .navbar { | ||||
box-shadow: none; | |||||
border-radius: 0px; | |||||
background-color: #{{ doc.top_bar_background}}; | background-color: #{{ doc.top_bar_background}}; | ||||
background-repeat: repeat-x; | background-repeat: repeat-x; | ||||
background-image: none; | background-image: none; | ||||
@@ -12,8 +12,9 @@ | |||||
<link type="text/css" rel="stylesheet" href="css/wn-web.css"> | <link type="text/css" rel="stylesheet" href="css/wn-web.css"> | ||||
<link rel="shortcut icon" href="{{ favicon }}" type="image/x-icon"> | <link rel="shortcut icon" href="{{ favicon }}" type="image/x-icon"> | ||||
<link rel="icon" href="{{ favicon }}" type="image/x-icon"> | <link rel="icon" href="{{ favicon }}" type="image/x-icon"> | ||||
{% if meta_description -%}<meta name="description" content="{{ meta_description }}"> | |||||
{%- endif %} | |||||
{% block head %}{% endblock %} | |||||
{% if meta_description -%} | |||||
<meta name="description" content="{{ meta_description }}">{%- endif %} | |||||
{% block javascript -%} | {% block javascript -%} | ||||
{% if javascript %}<script>{{ javascript }}</script>{% endif %} | {% if javascript %}<script>{{ javascript }}</script>{% endif %} | ||||
{%- endblock %} | {%- endblock %} | ||||
@@ -282,6 +282,14 @@ def setup_options(): | |||||
parser.add_option("--make_conf", default=False, action="store_true", | parser.add_option("--make_conf", default=False, action="store_true", | ||||
help="Create new conf.py file") | 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() | return parser.parse_args() | ||||
def run(): | def run(): | ||||
@@ -511,6 +519,33 @@ def run(): | |||||
from core.doctype.documentation_tool.documentation_tool import write_static | from core.doctype.documentation_tool.documentation_tool import write_static | ||||
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: | elif options.reset_perms: | ||||
for d in webnotes.conn.sql_list("""select name from `tabDocType` | for d in webnotes.conn.sql_list("""select name from `tabDocType` | ||||
where ifnull(istable, 0)=0 and ifnull(custom, 0)=0"""): | where ifnull(istable, 0)=0 and ifnull(custom, 0)=0"""): | ||||