diff --git a/core/doctype/documentation_tool/docs.css b/core/doctype/documentation_tool/docs.css
index 6d494c2d69..bd9d2ebaea 100644
--- a/core/doctype/documentation_tool/docs.css
+++ b/core/doctype/documentation_tool/docs.css
@@ -6,19 +6,22 @@ body {
line-height: 25px;
}
+img {
+ max-width: 100%;
+}
+
.container {
max-width: 767px;
}
-.navbar-inverse {
- background-color: #2980b9;
+.navbar {
+ background-color: #ffffff;
+ border-bottom: 1px solid #dddddd;
}
-.navbar-inverse .navbar-text,
-.navbar-inverse .navbar-brand,
-.navbar-inverse .navbar-nav > li > a
+.navbar .navbar-nav > li > a:hover
{
- color: #eeeeee;
+ color: #444444;
}
h1 {
@@ -61,3 +64,34 @@ blockquote p {
.erpnext-logo rect {
fill: #ffffff !important;
}
+
+.btn-default {
+ color: #ffffff;
+ background-color: #a7a9aa;
+ border-color: #a7a9aa;
+}
+
+.btn-default:hover,
+.btn-default:focus,
+.btn-default:active,
+.btn-default.active {
+ background-color: #9a9c9d;
+ border-color: #8d9091;
+}
+
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #a7a9aa;
+ border-color: #a7a9aa;
+}
+
diff --git a/core/doctype/documentation_tool/docs.html b/core/doctype/documentation_tool/docs.html
new file mode 100644
index 0000000000..772cb9c6b4
--- /dev/null
+++ b/core/doctype/documentation_tool/docs.html
@@ -0,0 +1,92 @@
+
+
+
+ "),
+ original_cur_frm = cur_frm;
doc = cur_frm.doc;
make_page = function(name, links) {
body.empty();
@@ -125,6 +97,7 @@ wn.docs.generate_all = function(logarea) {
},
callback: function(r) {
logarea.append("Wrote " + keys(wn.docs.to_write).length + " pages.");
+ cur_frm = original_cur_frm;
}
});
}
@@ -316,6 +289,9 @@ wn.docs.DocsPage = Class.extend({
else
page_icon = "file-text-alt";
}
+
+ if(page_icon.substr(0,5)==="icon-") page_icon = page_icon.substr(5);
+
var icon = $('
')
.appendTo(this.parent);
@@ -615,7 +591,7 @@ wn.docs.DocsPage = Class.extend({
}
wn.docs.to_write[this.namespace] = {
- title: wn.app.name + ": " + this.obj._label || wn.docs.get_short_name(this.namespace),
+ title: wn.app.name + ": " + (this.obj._label || wn.docs.get_short_name(this.namespace)),
content: html_beautify(this.parent.html())
}
}
diff --git a/core/doctype/documentation_tool/documentation_tool.py b/core/doctype/documentation_tool/documentation_tool.py
index d0bdb8dd7d..52ec0bd769 100644
--- a/core/doctype/documentation_tool/documentation_tool.py
+++ b/core/doctype/documentation_tool/documentation_tool.py
@@ -104,7 +104,7 @@ def inspect_object_and_update_docs(mydocs, obj):
if not mydocs.get("_intro"):
mydocs["_intro"] = getattr(obj, "__doc__", "")
-
+
for name in dir(obj):
try:
value = getattr(obj, name)
@@ -112,13 +112,19 @@ def inspect_object_and_update_docs(mydocs, obj):
value = None
if value:
- if inspect.ismethod(value) or (inspect.isfunction(value) and inspect.getmodule(value)==obj):
- mydocs[name] = {
- "_type": "function",
- "_args": inspect.getargspec(value)[0],
- "_help": getattr(value, "__doc__", ""),
- "_source": inspect.getsource(value)
- }
+ if (mydocs["_type"]=="module" and inspect.getmodule(value)==obj)\
+ or (mydocs["_type"]=="class" and getattr(value, "im_class", None)==obj):
+ if inspect.ismethod(value) or inspect.isfunction(value):
+ mydocs[name] = {
+ "_type": "function",
+ "_args": inspect.getargspec(value)[0],
+ "_help": getattr(value, "__doc__", ""),
+ "_source": inspect.getsource(value)
+ }
+ elif inspect.isclass(value):
+ if not mydocs.get("_toc"):
+ mydocs["_toc"] = []
+ mydocs["_toc"].append(obj.__name__ + "." + value.__name__)
def get_gh_url(path):
sep = "/lib/" if "/lib/" in path else "/app/"
@@ -149,14 +155,13 @@ def get_modules(for_module=None):
"_toc": [
prefix + ".doctype",
prefix + ".page",
- prefix + ".report",
prefix + ".py_modules"
],
"doctype": get_doctypes(m),
"page": get_pages(m),
#"report": {},
"py_modules": {
- "_label": "Independant Python Modules for " + m,
+ "_label": "Independent Python Modules for " + m,
"_toc": []
}
}
@@ -239,7 +244,7 @@ def get_doctypes(m):
mydocs = docs[d] = {
"_label": d,
- "_icon": "sitemap",
+ "_icon": meta[0].icon,
"_type": "doctype",
"_gh_source": get_gh_url(doc_path),
"_toc": [
@@ -273,7 +278,7 @@ def get_doctypes(m):
# model
modeldocs = mydocs["model"] = {
"_label": d + " Model",
- "_icon": "sitemap",
+ "_icon": meta[0].icon,
"_type": "model",
"_intro": "Properties and fields for " + d,
"_gh_source": get_gh_url(os.path.join(doc_path, scrub(d) + ".txt")),
@@ -291,7 +296,7 @@ def get_doctypes(m):
permission_docs = mydocs["permissions"] = {
"_label": d + " Permissions",
"_type": "permissions",
- "_icon": "shield",
+ "_icon": meta[0].icon,
"_gh_source": get_gh_url(os.path.join(doc_path, scrub(d) + ".txt")),
"_intro": "Standard Permissions for " + d + ". These can be changed by the user.",
"_permissions": [p for p in doclist if p.doctype=="DocPerm"],
@@ -314,12 +319,12 @@ def get_doctypes(m):
# client controller
if meta_p[0].fields.get("__js"):
- mydocs["_toc"].append(prefix + d + ".controller_client")
client_controller_path = os.path.join(doc_path, scrub(d) + ".js")
if(os.path.exists(client_controller_path)):
+ mydocs["_toc"].append(prefix + d + ".controller_client")
client_controller = mydocs["controller_client"] = {
"_label": d + " Client Controller",
- "_icon": "code",
+ "_icon": meta[0].icon,
"_type": "controller_client",
"_gh_source": get_gh_url(client_controller_path),
"_modified": get_timestamp(client_controller_path),
@@ -379,7 +384,10 @@ def prepare_docs():
def write_docs(data, build_sitemap=None, domain=None):
if webnotes.session.user != "Administrator":
raise webnotes.PermissionError
-
+
+ with open(os.path.join(os.path.dirname(__file__), "docs.html"), "r") as docshtml:
+ docs_template = docshtml.read()
+
data = json.loads(data)
template = Template(docs_template)
data["index"] = data["docs"]
@@ -416,99 +424,3 @@ sitemap_frame_xml = """
"""
sitemap_link_xml = """\n
%s%s"""
-
-
-docs_template = """
-
-
-
-
-
-
{{ title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-"""
diff --git a/public/js/wn/assets.js b/public/js/wn/assets.js
index e7b19737dc..efde25b5a2 100644
--- a/public/js/wn/assets.js
+++ b/public/js/wn/assets.js
@@ -111,34 +111,4 @@ wn.assets = {
wn.dom.set_style(txt);
}
}
-}
-
-wn.markdown = function(txt) {
- if(!wn.md2html) {
- wn.require('lib/js/lib/showdown.js');
- wn.md2html = new Showdown.converter();
- }
-
- while(txt.substr(0,1)==="\n") {
- txt = txt.substr(1);
- }
-
- // remove leading tab (if they exist in the first line)
- var whitespace_len = 0,
- first_line = txt.split("\n")[0];
-
- while([" ", "\n", "\t"].indexOf(first_line.substr(0,1))!== -1) {
- whitespace_len++;
- first_line = first_line.substr(1);
- }
-
- if(whitespace_len && whitespace_len != first_line.length) {
- var txt1 = [];
- $.each(txt.split("\n"), function(i, t) {
- txt1.push(t.substr(whitespace_len));
- })
- txt = txt1.join("\n");
- }
-
- return wn.md2html.makeHtml(txt);
-}
+}
\ No newline at end of file
diff --git a/public/js/wn/misc/tools.js b/public/js/wn/misc/tools.js
index de86361632..cccc5f6cd9 100644
--- a/public/js/wn/misc/tools.js
+++ b/public/js/wn/misc/tools.js
@@ -41,6 +41,37 @@ wn.tools.downloadify = function(data, roles, me) {
}
};
+wn.markdown = function(txt) {
+ if(!wn.md2html) {
+ wn.require('lib/js/lib/showdown.js');
+ wn.md2html = new Showdown.converter();
+ }
+
+ while(txt.substr(0,1)==="\n") {
+ txt = txt.substr(1);
+ }
+
+ // remove leading tab (if they exist in the first line)
+ var whitespace_len = 0,
+ first_line = txt.split("\n")[0];
+
+ while([" ", "\n", "\t"].indexOf(first_line.substr(0,1))!== -1) {
+ whitespace_len++;
+ first_line = first_line.substr(1);
+ }
+
+ if(whitespace_len && whitespace_len != first_line.length) {
+ var txt1 = [];
+ $.each(txt.split("\n"), function(i, t) {
+ txt1.push(t.substr(whitespace_len));
+ })
+ txt = txt1.join("\n");
+ }
+
+ return wn.md2html.makeHtml(txt);
+}
+
+
wn.tools.to_csv = function(data) {
var res = [];
$.each(data, function(i, row) {
diff --git a/public/js/wn/ui/dialog.js b/public/js/wn/ui/dialog.js
index 3b8edcbc7b..e43043a503 100644
--- a/public/js/wn/ui/dialog.js
+++ b/public/js/wn/ui/dialog.js
@@ -26,6 +26,18 @@ var cur_dialog;
wn.ui.open_dialogs = [];
wn.ui.Dialog = wn.ui.FieldGroup.extend({
+ _intro:' usage:\n\
+ \n\
+ var dialog = new wn.ui.Dialog({\n\
+ title: "Dialog Title",\n\
+ fields: [\n\
+ {fieldname:"field1", fieldtype:"Data", reqd:1, label: "Test 1"},\n\
+ {fieldname:"field2", fieldtype:"Link", reqd:1, label: "Test 1", options:"Some DocType"},\n\
+ {fieldname:"mybutton", fieldtype:"Button", reqd:1, label: "Submit"},\n\
+ ]\n\
+ })\n\
+ dialog.get_input("mybutton").click(function() { /* do something; */ dialog.hide(); });\n\
+ dialog.show()',
init: function(opts) {
this.display = false;
if(!opts.width) opts.width = 480;
diff --git a/public/js/wn/upload.js b/public/js/wn/upload.js
index a0e37f6748..57468abe8a 100644
--- a/public/js/wn/upload.js
+++ b/public/js/wn/upload.js
@@ -56,14 +56,15 @@ wn.upload = {
"method": "uploadfile",
args: args,
callback: function(r) {
- msgbox.hide();
+ if(!r._server_messages)
+ msgbox.hide();
if(r.exc) {
onerror(r);
return;
}
- callback(r.message, args.filename || args.file_url, r);
+ callback(r.message.fileid, r.message.filename, r);
$(document).trigger("upload_complete",
- [args.filename, args.file_url]);
+ [r.message.fileid, r.message.filename]);
}
});
}
diff --git a/webnotes/db.py b/webnotes/db.py
index 105e7bfa87..6909263e80 100644
--- a/webnotes/db.py
+++ b/webnotes/db.py
@@ -29,8 +29,6 @@ import webnotes
import conf
import datetime
-_toc = ["webnotes.db.Database"]
-
class Database:
"""
Open a database connection with the given parmeters, if use_default is True, use the
diff --git a/webnotes/model/mapper.py b/webnotes/model/mapper.py
index 53b02fdcc0..133bef2ee9 100644
--- a/webnotes/model/mapper.py
+++ b/webnotes/model/mapper.py
@@ -26,8 +26,8 @@ from webnotes import _
from webnotes.utils import cstr
from webnotes.model import default_fields
-def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=[], postprocess=None,
- ignore_permissions=False):
+def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=[],
+ postprocess=None, ignore_permissions=False):
if isinstance(target_doclist, basestring):
target_doclist = json.loads(target_doclist)
@@ -38,7 +38,7 @@ def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=[]
source_meta = webnotes.get_doctype(from_doctype)
target_meta = webnotes.get_doctype(table_maps[from_doctype]["doctype"])
-
+
# main
if target_doclist:
if isinstance(target_doclist[0], dict):
@@ -49,8 +49,11 @@ def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=[]
target_doc = webnotes.new_doc(table_maps[from_doctype]["doctype"])
map_doc(source.doc, target_doc, table_maps[source.doc.doctype], source_meta, target_meta)
- doclist = [target_doc]
-
+ if target_doclist:
+ target_doclist[0] = target_doc
+ else:
+ target_doclist = [target_doc]
+
# children
for source_d in source.doclist[1:]:
table_map = table_maps.get(source_d.doctype)
@@ -65,17 +68,20 @@ def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=[]
"fieldtype": "Table",
"options": target_doctype
})[0].fieldname
+
+ if table_map.get("add_if_empty") and row_exists_in_target(parentfield, target_doclist):
+ continue
target_d = webnotes.new_doc(target_doctype, target_doc, parentfield)
map_doc(source_d, target_d, table_map, source_meta, target_meta, source.doclist[0])
- doclist.append(target_d)
+ target_doclist.append(target_d)
- doclist = webnotes.doclist(doclist)
+ target_doclist = webnotes.doclist(target_doclist)
if postprocess:
- postprocess(source, doclist)
+ postprocess(source, target_doclist)
- return doclist
+ return target_doclist
def map_doc(source_doc, target_doc, table_map, source_meta, target_meta, source_parent=None):
no_copy_fields = set(\
@@ -122,3 +128,13 @@ def map_doc(source_doc, target_doc, table_map, source_meta, target_meta, source_
if "postprocess" in table_map:
table_map["postprocess"](source_doc, target_doc, source_parent)
+
+row_exists_for_parentfield = {}
+def row_exists_in_target(parentfield, target_doclist):
+ global row_exists_for_parentfield
+
+ if parentfield not in row_exists_for_parentfield:
+ row_exists_for_parentfield[parentfield] = True if \
+ webnotes.doclist(target_doclist).get({"parentfield": parentfield}) else False
+
+ return row_exists_for_parentfield[parentfield]
diff --git a/webnotes/utils/file_manager.py b/webnotes/utils/file_manager.py
index 439169ff3a..20dd9f516e 100644
--- a/webnotes/utils/file_manager.py
+++ b/webnotes/utils/file_manager.py
@@ -23,7 +23,7 @@
from __future__ import unicode_literals
import webnotes
import os, conf
-from webnotes.utils import cstr, get_path
+from webnotes.utils import cstr, get_path, cint
from webnotes import _
class MaxFileSizeReachedError(webnotes.ValidationError): pass
@@ -41,18 +41,16 @@ def upload():
# save
if filename:
- fid, fname = save_uploaded(dt, dn)
+ filedata = save_uploaded(dt, dn)
elif file_url:
- fid, fname = save_url(file_url, dt, dn)
+ filedata = save_url(file_url, dt, dn)
+
+ return {"fid": filedata.name, "filename": filedata.file_name or filedata.file_url }
- if fid:
- return fid
-
-def save_uploaded(dt, dn):
+def save_uploaded(dt, dn):
fname, content = get_uploaded_content()
if content:
- fid = save_file(fname, content, dt, dn)
- return fid, fname
+ return save_file(fname, content, dt, dn)
else:
raise Exception
@@ -69,7 +67,7 @@ def save_url(file_url, dt, dn):
})
f.ignore_permissions = True
f.insert();
- return f.doc.name, file_url
+ return f.doc
def get_uploaded_content():
# should not be unicode when reading a file, hence using webnotes.form
@@ -90,14 +88,25 @@ def save_file(fname, content, dt, dn):
temp_fname = write_file(content)
fname = scrub_file_name(fname)
fpath = os.path.join(files_path, fname)
+
+ fname_parts = fname.split(".", -1)
+ main = ".".join(fname_parts[:-1])
+ extn = fname_parts[-1]
+ versions = get_file_versions(files_path, main, extn)
- if os.path.exists(fpath):
- if cmp(fpath, temp_fname):
- # remove new file, already exists!
- os.remove(temp_fname)
- else:
+ if versions:
+ found_match = False
+ for version in versions:
+ if cmp(os.path.join(files_path, version), temp_fname):
+ # remove new file, already exists!
+ os.remove(temp_fname)
+ fname = version
+ found_match = True
+ break
+
+ if not found_match:
# get_new_version name
- fname = get_new_fname_based_on_version(files_path, fname)
+ fname = get_new_fname_based_on_version(files_path, main, extn, versions)
# rename
os.rename(temp_fname, os.path.join(files_path, fname))
@@ -115,24 +124,24 @@ def save_file(fname, content, dt, dn):
f.ignore_permissions = True
f.insert();
- return f.doc.name
+ return f.doc
-def get_new_fname_based_on_version(files_path, fname):
- # new version of the file is being uploaded, add a revision number?
- versions = filter(lambda f: f.startswith(fname), os.listdir(files_path))
+def get_file_versions(files_path, main, extn):
+ return filter(lambda f: f.startswith(main) and f.endswith(extn), os.listdir(files_path))
+def get_new_fname_based_on_version(files_path, main, extn, versions):
versions.sort()
if "-" in versions[-1]:
- version = int(versions[-1].split("-")[-1]) or 1
+ version = cint(versions[-1].split("-")[-1]) or 1
else:
version = 1
- new_fname = fname + "-" + str(version)
+ new_fname = main + "-" + str(version) + "." + extn
while os.path.exists(os.path.join(files_path, new_fname)):
version += 1
- new_fname = fname + "-" + str(version)
+ new_fname = main + "-" + str(version) + "." + extn
if version > 100:
- break # let there be an exception
+ webnotes.msgprint("Too many versions", raise_exception=True)
return new_fname
diff --git a/webnotes/widgets/form/utils.py b/webnotes/widgets/form/utils.py
index b3dbca2790..1b08b2b344 100644
--- a/webnotes/widgets/form/utils.py
+++ b/webnotes/widgets/form/utils.py
@@ -29,9 +29,7 @@ from webnotes import _
def remove_attach():
"""remove attachment"""
import webnotes.utils.file_manager
-
fid = webnotes.form_dict.get('fid')
-
webnotes.utils.file_manager.remove_file(fid)
@webnotes.whitelist()