Merge branch 'responsive' of github.com:webnotes/wnframework into responsive
This commit is contained in:
commit
c8a6481d1f
12 changed files with 268 additions and 219 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
92
core/doctype/documentation_tool/docs.html
Normal file
92
core/doctype/documentation_tool/docs.html
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ title }}</title>
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta name="generator" content="wnframework">
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="js/prism.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="css/bootstrap.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/font-awesome.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/prism.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="container">
|
||||
<button type="button" class="navbar-toggle"
|
||||
data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
<object data="img/splash.svg" class="erpnext-logo"
|
||||
type="image/svg+xml"></object> erpnext</a>
|
||||
<div class="nav-collapse collapse navbar-responsive-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="docs.user.html">User</a></li>
|
||||
<li><a href="docs.dev.html">Developer</a></li>
|
||||
<li><a href="docs.download.html">Download</a></li>
|
||||
<li><a href="docs.community.html">Community</a></li>
|
||||
<li><a href="docs.blog.html">Blog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container" style=" margin-top: 70px;">
|
||||
<!-- div class="logo" style="margin-bottom: 15px; height: 71px;">
|
||||
<a href="docs.html">
|
||||
<img src="img/erpnext-2013.png" style="width: 71px; margin-top: -10px;" />
|
||||
</a>
|
||||
<span style="font-size: 37px; color: #888; display: inline-block;
|
||||
margin-left: 8px;">erpnext</span>
|
||||
</div -->
|
||||
<div class="content row">
|
||||
<div class="col col-lg-12">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<hr />
|
||||
<div class="footer text-muted" style="font-size: 80%;">
|
||||
<div class="content row">
|
||||
<div class="col col-lg-12">
|
||||
© <a href="https://erpnext.com">Web Notes Technologies Pvt Ltd.</a><br>
|
||||
ERPNext is an <a href="https://github.com/webnotes/erpnext" target="_blank">
|
||||
open source project</a>. Code licensed under the
|
||||
<a href="https://www.gnu.org/licenses/gpl.html">GNU/GPL License</a>.
|
||||
Documentation Licensed under <a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA-3.0</a>.<br>
|
||||
<a href="docs.user.help.html">Get Help</a> / <a href="https://erpnext.com/contact">Get in touch</a> /
|
||||
<a href="https://erpnext.com">Buy Hosting or Support Services</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p> </p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("[data-toggle]").on("click", function() {
|
||||
$("[data-target='"+ $(this).attr("data-toggle") +"']").toggle();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
$(".dropdown-toggle").dropdown();
|
||||
</script>
|
||||
<!-- script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-8911157-9']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,32 +1,3 @@
|
|||
/*
|
||||
|
||||
Todo:
|
||||
- make global toc
|
||||
- static pages in markdown (in sources folder)
|
||||
- web interface
|
||||
- building an application
|
||||
- customizing an application
|
||||
- generating web pages
|
||||
|
||||
- help / comments in markdown
|
||||
- pages
|
||||
- doctype
|
||||
- links
|
||||
- properties
|
||||
- methods
|
||||
- events (server, client)
|
||||
|
||||
Documentation API
|
||||
|
||||
Every module (namespace) / class will have a page
|
||||
- _toc
|
||||
- _path
|
||||
- _label
|
||||
- _intro
|
||||
- _type (class, function, module, doctype etc)
|
||||
- [list of functions / objects / classes]
|
||||
*/
|
||||
|
||||
wn.require("lib/public/js/lib/beautify-html.js");
|
||||
|
||||
cur_frm.cscript.onload = function(doc) {
|
||||
|
|
@ -50,6 +21,7 @@ wn.docs.generate_all = function(logarea) {
|
|||
wn.docs.to_write = {};
|
||||
var pages = [],
|
||||
body = $("<div class='docs'>"),
|
||||
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 = $('<h1 class="pull-right text-muted"><i class="icon-'+
|
||||
page_icon +'"></i></h1>')
|
||||
.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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = """<?xml version="1.0" encoding="UTF-8"?>
|
|||
</urlset>"""
|
||||
|
||||
sitemap_link_xml = """\n<url><loc>%s</loc><lastmod>%s</lastmod></url>"""
|
||||
|
||||
|
||||
docs_template = """
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ title }}</title>
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta name="generator" content="wnframework">
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="js/prism.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="css/bootstrap.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/font-awesome.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/prism.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="navbar navbar-fixed-top navbar-inverse">
|
||||
<div class="container">
|
||||
<button type="button" class="navbar-toggle"
|
||||
data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">
|
||||
<object data="img/splash.svg" class="erpnext-logo"
|
||||
type="image/svg+xml"></object> erpnext</a>
|
||||
<div class="nav-collapse collapse navbar-responsive-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="docs.user.html">User</a></li>
|
||||
<li><a href="docs.dev.html">Developer</a></li>
|
||||
<li><a href="docs.download.html">Download</a></li>
|
||||
<li><a href="docs.community.html">Community</a></li>
|
||||
<li><a href="docs.blog.html">Blog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container" style=" margin-top: 70px;">
|
||||
<!-- div class="logo" style="margin-bottom: 15px; height: 71px;">
|
||||
<a href="docs.html">
|
||||
<img src="img/erpnext-2013.png" style="width: 71px; margin-top: -10px;" />
|
||||
</a>
|
||||
<span style="font-size: 37px; color: #888; display: inline-block;
|
||||
margin-left: 8px;">erpnext</span>
|
||||
</div -->
|
||||
<div class="content row">
|
||||
<div class="col col-lg-12">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<hr />
|
||||
<div class="footer text-muted" style="font-size: 80%;">
|
||||
<div class="content row">
|
||||
<div class="col col-lg-12">
|
||||
© <a href="https://erpnext.com">Web Notes Technologies Pvt Ltd.</a><br>
|
||||
ERPNext is an <a href="https://github.com/webnotes/erpnext" target="_blank">
|
||||
open source project</a>. Code licensed under the
|
||||
<a href="https://www.gnu.org/licenses/gpl.html">GNU/GPL License</a>.
|
||||
Documentation Licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.<br>
|
||||
<a href="docs.user.help.html">Get Help</a> / <a href="https://erpnext.com/contact">Get in touch</a> /
|
||||
<a href="https://erpnext.com">Buy Hosting or Support Services</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p> </p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("[data-toggle]").on("click", function() {
|
||||
$("[data-target='"+ $(this).attr("data-toggle") +"']").toggle();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
$(".dropdown-toggle").dropdown();
|
||||
</script>
|
||||
<!-- script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-8911157-9']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script -->
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue