diff --git a/build.json b/build.json
index 484106348a..61da74ca4f 100644
--- a/build.json
+++ b/build.json
@@ -99,6 +99,7 @@
"lib/js/legacy/utils/msgprint.js",
"lib/js/wn/ui/appframe.js",
"lib/js/wn/ui/dialog.js",
+ "lib/js/wn/ui/button.js",
"lib/js/legacy/widgets/dialog.js",
"lib/js/legacy/webpage/page_header.js",
"lib/js/legacy/webpage/spinner.js",
@@ -132,6 +133,7 @@
"lib/js/wn/ui/button.js",
"lib/js/wn/ui/search.js",
"lib/js/wn/ui/tree.js",
+ "lib/js/wn/upload.js",
"lib/js/wn/misc/about.js",
"lib/js/wn/views/doclistview.js",
"lib/js/wn/views/formview.js",
@@ -146,7 +148,6 @@
"lib/js/legacy/webpage/spinner.js",
"lib/js/legacy/webpage/error_console.js",
"lib/js/legacy/webpage/loaders.js",
- "lib/js/legacy/webpage/uploader.js",
"lib/js/legacy/wn/page_layout.js",
"lib/js/legacy/wn/widgets/page_sidebar.js",
"lib/js/legacy/wn/widgets/footer.js",
diff --git a/css/legacy/body.css b/css/legacy/body.css
index 774b523005..13247062e3 100644
--- a/css/legacy/body.css
+++ b/css/legacy/body.css
@@ -92,6 +92,7 @@ li {
}
hr {
+ clear: both;
margin: 18px 0;
border: 0;
border-top: 1px solid #e5e5e5;
diff --git a/css/ui/list.css b/css/ui/list.css
index 29f7b80eb7..4d3f837412 100644
--- a/css/ui/list.css
+++ b/css/ui/list.css
@@ -125,7 +125,7 @@ div.stat-item {
margin-bottom: 7px;
background-color: #fff;
height: 18px;
- border: 2px solid #aaa;
+ border: 1px solid #aaa;
border-radius: 9px;
overflow: hidden;
}
diff --git a/js/core.min.js b/js/core.min.js
index 5e48b64859..765d3dc3e1 100644
--- a/js/core.min.js
+++ b/js/core.min.js
@@ -31,7 +31,8 @@ var l=items.length;for(var i=0;i Download a template for importing a table. \
+ Attach .csv file to import data Date Format: Dates must be in format "YYYY-MM-DD", for example, \
+ 31st Jan 2012 must be "2012-01-31" Importing non-English data: While uploading non English files ensure that the encoding is UTF-8. Microsoft Excel Users:\
+
').insertAfter(ele);}}
-$.fn.done_working=function(){var ele=this.get(0);ele.disabled=0;if(ele.loading_img){$(ele.loading_img).toggle(false);};}})(jQuery);
+$.fn.done_working=function(){var ele=this.get(0);$(ele).attr('disabled',null);if(ele.loading_img){$(ele.loading_img).toggle(false);};}})(jQuery);
/*
* lib/js/wn/model.js
*/
diff --git a/js/legacy/model/local_data.js b/js/legacy/model/local_data.js
index 2b3b3fe4ea..6b6fcccfc6 100644
--- a/js/legacy/model/local_data.js
+++ b/js/legacy/model/local_data.js
@@ -256,12 +256,11 @@ LocalDB.no_copy_list = ['amended_from','amendment_date','cancel_reason'];
LocalDB.copy=function(dt, dn, from_amend) {
var newdoc = LocalDB.create(dt);
for(var key in locals[dt][dn]) {
- if(key!=='name' && key.substr(0,2)!='__') { // dont copy name and blank fields
- locals[dt][newdoc][key] = locals[dt][dn][key];
- }
+ // dont copy name and blank fields
var df = get_field(dt, key);
- if(df && ((!from_amend && cint(df.no_copy)==1) || in_list(LocalDB.no_copy_list, df.fieldname))) { // blank out 'No Copy'
- locals[dt][newdoc][key]='';
+ if(key!=='name' && key.substr(0,2)!='__' &&
+ !(df && ((!from_amend && cint(df.no_copy)==1) || in_list(LocalDB.no_copy_list, df.fieldname)))) {
+ locals[dt][newdoc][key] = locals[dt][dn][key];
}
}
return locals[dt][newdoc];
diff --git a/js/legacy/report.compressed.js b/js/legacy/report.compressed.js
deleted file mode 100644
index c33ce6ca84..0000000000
--- a/js/legacy/report.compressed.js
+++ /dev/null
@@ -1,237 +0,0 @@
-
-/*
- * lib/js/legacy/widgets/report_builder/report_builder.js
- */
-_r.ReportContainer=function(){if(user=='Guest'){msgprint("Not Allowed");return;}
-var page=wn.container.add_page("Report Builder");this.wrapper=$a(page,'div','layout-wrapper',{padding:'0px'});this.appframe=new wn.ui.AppFrame(this.wrapper);this.appframe.$titlebar.append('');this.rb_area=$a(this.wrapper,'div','',{padding:'15px'});var me=this;this.rb_dict={};var run_fn=function(){if(me.cur_rb){me.cur_rb.dt.start_rec=1;me.cur_rb.dt.run();}}
-var runbtn=this.appframe.add_button('Run',run_fn,'icon-refresh');this.appframe.add_button('Export',function(){me.cur_rb&&me.cur_rb.dt.do_export();},'icon-download-alt');this.appframe.add_button('Print',function(){me.cur_rb&&me.cur_rb.dt.do_print();},'icon-print');this.appframe.add_button('Calc',function(){me.cur_rb&&me.cur_rb.dt.do_calc();},'icon-plus');if(has_common(['Administrator','System Manager'],user_roles)){var savebtn=this.appframe.add_button('Save',function(){if(me.cur_rb)me.cur_rb.save_criteria();});var fn=function(){if(me.cur_rb){if(!me.cur_rb.current_loaded){msgprint("error:You must save the report before you can set Advanced features");return;}
-loaddoc('Search Criteria',me.cur_rb.sc_dict[me.cur_rb.current_loaded]);}};var advancedbtn=this.appframe.add_button('Advanced Settings',fn,'icon-cog');}
-this.set_dt=function(dt,onload){my_onload=function(f){if(!f.forbidden){me.cur_rb=f;me.cur_rb.mytabs.items['Result'].expand();if(onload)onload(f);}}
-if(me.cur_rb)
-me.cur_rb.hide();if(me.rb_dict[dt]){me.rb_dict[dt].show(my_onload);}else{me.rb_dict[dt]=new _r.ReportBuilder(me.rb_area,dt,my_onload);}}}
-_r.ReportBuilder=function(parent,doctype,onload){this.menuitems={};this.has_primary_filters=false;this.doctype=doctype;this.forbidden=0;this.filter_fields=[];this.filter_fields_dict={};var me=this;this.fn_list=['beforetableprint','beforerowprint','afterrowprint','aftertableprint','customize_filters','get_query'];this.wrapper=$a(parent,'div','finder_wrapper');this.make_tabs();this.current_loaded=null;this.setup_doctype(onload);this.hide=function(){$dh(me.wrapper);}
-this.show=function(my_onload){$ds(me.wrapper);this.set_main_title('Report: '+get_doctype_label(me.doctype));if(my_onload)my_onload(me);}}
-_r.ReportBuilder.prototype.make_tabs=function(){this.tab_wrapper=$a(this.wrapper,'div','finder_tab_area');this.mytabs=new TabbedPage(this.tab_wrapper);this.mytabs.add_item('Result',null,null,1);this.mytabs.add_item('More Filters',null,null,1);this.mytabs.add_item('Select Columns',null,null,1);this.mytabs.tabs=this.mytabs.items;}
-_r.ReportBuilder.prototype.make_body=function(){this.set_main_title('Report: '+get_doctype_label(this.doctype));var me=this;this.make_save_criteria();this.column_picker=new _r.ReportColumnPicker(this);this.report_filters=new _r.ReportFilters(this);}
-_r.ReportBuilder.prototype.make_save_criteria=function(){var me=this;this.sc_list=[];this.sc_dict={};for(var n in locals['Search Criteria']){var d=locals['Search Criteria'][n];if(d.doc_type==this.doctype){this.sc_list[this.sc_list.length]=d.criteria_name;this.sc_dict[d.criteria_name]=n;}}}
-_r.ReportBuilder.prototype.save_criteria=function(save_as){var overwrite=0;if(this.current_loaded&&(!save_as)){var overwrite=confirm('Do you want to overwrite the saved criteria "'+this.current_loaded+'"');if(overwrite){var doc=locals['Search Criteria'][this.sc_dict[this.current_loaded]];var criteria_name=this.current_loaded;}}
-if(!overwrite){var criteria_name=prompt('Select a name for the criteria:','');if(!criteria_name)
-return;var dn=createLocal('Search Criteria');var doc=locals['Search Criteria'][dn];doc.criteria_name=criteria_name;doc.doc_type=this.doctype;}
-var cl=[];var fl={};var t=this.column_picker.get_selected();for(var i=0;i
Please click on 'Export' to open in a spreadsheet");return;}
-_r.rb_con.cur_rb.mytabs.items['Result'].expand();}
-var me=this;this._get_query();if(this.set_data){this.show_result(this.set_data);this.set_data=null;return;}
-$ds(this.fetching_tag);if($.browser.mozilla)this.clear_all();var args={'query':me.query,'report_name':'_r.DataTable','show_deleted':1,'sc_id':me.search_criteria?me.search_criteria.name:'','filter_values':me.filter_vals?docstring(me.filter_vals):'','roles':'["'+user_roles.join('","')+'"]'}
-if(this.is_simple)args.is_simple=1;$c('webnotes.widgets.query_builder.runquery',args,function(r,rt){$dh(me.fetching_tag);me.show_result(r,rt);});}
-_r.DataTable.prototype.clear_all=function(){if(this.htab&&this.htab.parentNode){this.htab.parentNode.removeChild(this.htab);delete this.htab;}
-if(this.tab&&this.tab.parentNode){this.tab.parentNode.removeChild(this.tab);delete this.tab;}
-$dh(this.no_data_tag);}
-_r.DataTable.prototype.has_data=function(){if(this.htab&&this.htab.rows.length)return 1;else return 0;}
-_r.DataTable.prototype.show_result=function(r,rt){var me=this;this.clear_all();this.rset=eval(r.values);if(this.rset&&this.rset.length){if(this.has_headings){this.htab=$a(this.hwrapper,'table');$y(this.twrapper,{top:'25px',borderTop:'0px'});}
-this.tab=$a(this.twrapper,'table');this.colwidths=eval(r.colwidths);this.coltypes=eval(r.coltypes);this.coloptions=eval(r.coloptions);this.colnames=eval(r.colnames);$y(this.tab,{tableLayout:'fixed'});if(this.beforetableprint)this.beforetableprint(this);if(this.has_headings)this.make_head_tab(this.colnames);var start=this.start_rec;var rset_len=this.rset.length;if(rset_len>1000){msgprint("Showing only 1000 records out of "+rset_len+". Use 'Export' to see all records");rset_len=1000;}
-for(var vi=0;vi
')
.insertAfter(ele);
@@ -153,7 +154,7 @@ wn.dom.set_box_shadow = function(ele, spread) {
}
$.fn.done_working = function() {
var ele = this.get(0);
- ele.disabled = 0;
+ $(ele).attr('disabled', null);
if(ele.loading_img) {
$(ele.loading_img).toggle(false);
};
diff --git a/js/wn/request.js b/js/wn/request.js
index 79b34682f3..c65b25f8ac 100644
--- a/js/wn/request.js
+++ b/js/wn/request.js
@@ -29,7 +29,7 @@ wn.request.url = 'index.cgi';
wn.request.prepare = function(opts) {
// btn indicator
if(opts.btn) $(opts.btn).set_working();
-
+
// navbar indicator
if(opts.show_spinner) set_loading();
diff --git a/js/wn/ui/button.js b/js/wn/ui/button.js
index 30cced8e01..98b2cb1da3 100644
--- a/js/wn/ui/button.js
+++ b/js/wn/ui/button.js
@@ -30,7 +30,6 @@ wn.ui.Button = function(args) {
// ajax loading
me.loading_img = wn.dom.add(me.btn.args.parent,'img','',{margin:'0px 4px -2px 4px', display:'none'});
me.loading_img.src= 'images/lib/ui/button-load.gif';
- if(args.is_ajax) wn.dom.css(me.btn,{marginRight:'24px'});
// label
me.btn.innerHTML = args.label;
@@ -53,17 +52,11 @@ wn.ui.Button = function(args) {
set_working: function() {
me.btn.disabled = 'disabled';
- if(me.btn.args.is_ajax) {
- $(me.btn).css('margin-right', '0px');
- }
$(me.loading_img).css('display','inline');
},
done_working: function() {
me.btn.disabled = false;
- if(me.btn.args.is_ajax) {
- $(me.btn).css('margin-right', '24px');
- }
$(me.loading_img).toggle(false);
}
});
diff --git a/js/wn/ui/dialog.js b/js/wn/ui/dialog.js
index d33a38f9aa..bde93b6737 100644
--- a/js/wn/ui/dialog.js
+++ b/js/wn/ui/dialog.js
@@ -137,10 +137,8 @@ wn.widgets.Dialog = function(opts) {
this.set_postion = function() {
// place it at the center
- var d = get_screen_dims();
-
- this.wrapper.style.left = ((d.w - cint(this.wrapper.style.width))/2) + 'px';
- this.wrapper.style.top = (get_scroll_top() + 60) + 'px';
+ this.wrapper.style.left = (($(window).width() - cint(this.wrapper.style.width))/2) + 'px';
+ this.wrapper.style.top = ($(window).scrollTop() + 60) + 'px';
// place it on top
top_index++;
diff --git a/js/wn/ui/toolbar.min.js b/js/wn/ui/toolbar.min.js
index b1fab980b8..c114e5847c 100644
--- a/js/wn/ui/toolbar.min.js
+++ b/js/wn/ui/toolbar.min.js
@@ -16,7 +16,7 @@ wn.ui.toolbar.Search=wn.ui.toolbar.SelectorDialog.extend({init:function(){this._
/*
* lib/js/wn/ui/toolbar/report.js
*/
-wn.ui.toolbar.Report=wn.ui.toolbar.SelectorDialog.extend({init:function(){this._super({title:"Start Report For",execute:function(val){loadreport(val,null,null,null,1);},});this.set_values(profile.can_get_report.join(',').split(','));}});
+wn.ui.toolbar.Report=wn.ui.toolbar.SelectorDialog.extend({init:function(){this._super({title:"Start Report For",execute:function(val){wn.set_route('Report2',val);},});this.set_values(profile.can_get_report.join(',').split(','));}});
/*
* lib/js/wn/ui/toolbar/recent.js
*/
diff --git a/js/wn/ui/toolbar/report.js b/js/wn/ui/toolbar/report.js
index 5e43faf6e4..21b9c5b73d 100644
--- a/js/wn/ui/toolbar/report.js
+++ b/js/wn/ui/toolbar/report.js
@@ -25,7 +25,7 @@ wn.ui.toolbar.Report = wn.ui.toolbar.SelectorDialog.extend({
this._super({
title: "Start Report For",
execute: function(val) {
- loadreport(val, null, null, null, 1);
+ wn.set_route('Report2', val);
},
});
diff --git a/js/wn/upload.js b/js/wn/upload.js
new file mode 100644
index 0000000000..bfbf0f68c4
--- /dev/null
+++ b/js/wn/upload.js
@@ -0,0 +1,34 @@
+// parent, args, callback
+wn.upload = {
+ make: function(opts) {
+ var id = wn.dom.set_unique_id();
+ $(opts.parent).append(repl('\
+ ', {
+ id: id,
+ action: wn.request.url
+ }));
+
+ opts.args.cmd = 'uploadfile';
+ opts.args._id = id;
+
+ // add request parameters
+ for(key in opts.args) {
+ if(opts.args[key]) {
+ $('')
+ .attr('name', key)
+ .attr('value', opts.args[key])
+ .appendTo($(opts.parent).find('form'));
+ }
+ }
+
+ $('#' + id).get(0).callback = opts.callback
+ },
+ callback: function(id, file_id, args) {
+ $('#' + id).get(0).callback(file_id, args);
+ }
+}
\ No newline at end of file
diff --git a/js/wn/views/reportview.js b/js/wn/views/reportview.js
index 0b2e094a63..3d6a2c4d60 100644
--- a/js/wn/views/reportview.js
+++ b/js/wn/views/reportview.js
@@ -64,36 +64,59 @@ wn.views.reportview2 = {
} else {
var route = wn.get_route();
if(route[1]) {
- new wn.views.ReportView(route[1], route[2]);
+ new wn.views.ReportViewPage(route[1], route[2]);
} else {
- new wn.views.ReportHome();
+ wn.set_route('404');
}
}
}
}
-wn.views.ReportView = wn.ui.Listing.extend({
+wn.views.ReportViewPage = Class.extend({
init: function(doctype, docname) {
- var me = this;
+ this.doctype = doctype;
+ this.docname = docname;
this.page_name = wn.get_route_str();
+ this.make_page();
+
+ var me = this;
+ wn.model.with_doctype(doctype, function() {
+ me.make_report_view();
+ if(docname) {
+ wn.model.with_doc('Report', docname, function(r) {
+ me.reportview.set_columns_and_filters(JSON.parse(locals['Report'][docname].json));
+ me.reportview.run();
+ });
+ } else {
+ me.reportview.run();
+ }
+ });
+
+ },
+ make_page: function() {
+ this.page = wn.container.add_page(this.page_name);
+ wn.ui.make_app_page({parent:this.page,
+ single_column:true});
+ wn.container.change_to(this.page_name);
+ },
+ make_report_view: function() {
+ // add breadcrumbs
+ wn.views.breadcrumbs($('').appendTo(this.page.appframe.$titlebar),
+ locals.DocType[this.doctype].module);
+
+ this.reportview = new wn.views.ReportView(this.doctype, this.docname, this.page)
+ }
+})
+
+wn.views.ReportView = wn.ui.Listing.extend({
+ init: function(doctype, docname, page) {
+ var me = this;
this.import_slickgrid();
this.doctype = doctype;
this.docname = docname;
+ this.page = page;
this.tab_name = '`tab'+doctype+'`';
-
- // list of [column_name, table_name]
- this.make_page();
- wn.model.with_doctype(doctype, function() {
- me.setup();
- if(docname) {
- wn.model.with_doc('Report', docname, function(r) {
- me.set_columns_and_filters(JSON.parse(locals['Report'][docname].json));
- me.run();
- });
- } else {
- me.run();
- }
- });
+ this.setup();
},
import_slickgrid: function() {
wn.require('js/lib/slickgrid/slick.grid.css');
@@ -103,12 +126,7 @@ wn.views.ReportView = wn.ui.Listing.extend({
wn.require('js/lib/slickgrid/slick.grid.js');
wn.dom.set_style('.slick-cell { font-size: 12px; }');
},
- make_page: function() {
- this.page = wn.container.add_page(this.page_name);
- wn.ui.make_app_page({parent:this.page,
- single_column:true});
- wn.container.change_to(this.page_name);
- },
+
set_init_columns: function() {
// pre-select mandatory columns
var columns = [['name'], ['owner']];
@@ -121,8 +139,6 @@ wn.views.ReportView = wn.ui.Listing.extend({
},
setup: function() {
var me = this;
- wn.views.breadcrumbs($('').appendTo(this.page.appframe.$titlebar),
- locals.DocType[this.doctype].module);
this.make({
title: 'Report: ' + (this.docname ? (this.doctype + ' - ' + this.docname) : this.doctype),
appframe: this.page.appframe,
@@ -203,9 +219,7 @@ wn.views.ReportView = wn.ui.Listing.extend({
name: (docfield ? docfield.label : toTitle(c[0])),
width: (docfield ? cint(docfield.width) : 120) || 120
}
-
- console.log(docfield && docfield.width);
-
+
if(c[0]=='name') {
coldef.formatter = function(row, cell, value, columnDef, dataContext) {
return repl("%(name)s", {
diff --git a/py/core/doctype/custom_field/custom_field.txt b/py/core/doctype/custom_field/custom_field.txt
index da76634a83..370b6a7f0a 100644
--- a/py/core/doctype/custom_field/custom_field.txt
+++ b/py/core/doctype/custom_field/custom_field.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:35:35',
+ 'creation': '2012-03-27 14:35:36',
'docstatus': 0,
- 'modified': '2012-03-27 14:35:35',
+ 'modified': '2012-03-27 14:35:36',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -173,7 +173,7 @@
'no_copy': 0,
'oldfieldname': u'fieldtype',
'oldfieldtype': u'Select',
- 'options': u'\nButton\nCheck\nColumn Break\nCurrency\nData\nDate\nFloat\nHTML\nInt\nLink\nRead Only\nSection Break\nSelect\nSmall Text\nText\nText Editor\nTime',
+ 'options': u'\nButton\nCheck\nColumn Break\nCurrency\nData\nDate\nFloat\nHTML\nInt\nLink\nRead Only\nSection Break\nSelect\nSmall Text\nText\nText Editor\nTime\nTable',
'permlevel': 0,
'reqd': 1,
'search_index': 0,
diff --git a/py/core/doctype/doctype/doctype.py b/py/core/doctype/doctype/doctype.py
index ff3e766f3c..44d1a47581 100644
--- a/py/core/doctype/doctype/doctype.py
+++ b/py/core/doctype/doctype/doctype.py
@@ -75,6 +75,7 @@ class DocType:
fieldnames = {}
illegal = ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$']
for d in self.doclist:
+ if not d.permlevel: d.permlevel = 0
if d.parent and d.fieldtype and d.parent == self.doc.name:
# check if not double
if d.fieldname:
diff --git a/py/core/doctype/doctype_mapper/doctype_mapper.py b/py/core/doctype/doctype_mapper/doctype_mapper.py
index 8af627fd35..acca86f58f 100644
--- a/py/core/doctype/doctype_mapper/doctype_mapper.py
+++ b/py/core/doctype/doctype_mapper/doctype_mapper.py
@@ -25,7 +25,7 @@ import webnotes
from webnotes.utils import cint, cstr, default_fields, flt, formatdate, get_defaults, getdate, now, nowdate, replace_newlines, set_default
from webnotes.model import db_exists, default_fields
-from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
+from webnotes.model.doc import Document, addchild, getchildren, make_autoname
from webnotes.model.doclist import getlist
from webnotes.model.code import get_obj
from webnotes import session, form, msgprint, errprint
diff --git a/py/core/doctype/file_data/file_data.py b/py/core/doctype/file_data/file_data.py
index 5c09bf182c..2a0491bf3d 100644
--- a/py/core/doctype/file_data/file_data.py
+++ b/py/core/doctype/file_data/file_data.py
@@ -40,6 +40,8 @@ class DocType():
if not '.' in self.doc.file_name:
raise Exception, 'file name must have extension (.)'
+ self.doc.file_name = self.doc.file_name.replace('-', '')
+
parts = self.doc.file_name.split('.')
same = webnotes.conn.sql("""select name from `tabFile Data`
diff --git a/py/core/doctype/print_format/print_format.js b/py/core/doctype/print_format/print_format.js
new file mode 100644
index 0000000000..c3544405c5
--- /dev/null
+++ b/py/core/doctype/print_format/print_format.js
@@ -0,0 +1,5 @@
+cur_frm.cscript.refresh = function(doc, dt, dn) {
+ if (doc.standard == 'Yes') {
+ set_field_permlevel('html', 1);
+ }
+}
\ No newline at end of file
diff --git a/py/core/doctype/print_format/print_format.txt b/py/core/doctype/print_format/print_format.txt
index fe311f91c5..2cd7b6aa9b 100644
--- a/py/core/doctype/print_format/print_format.txt
+++ b/py/core/doctype/print_format/print_format.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-04-02 16:01:07',
+ 'creation': '2012-05-15 12:14:24',
'docstatus': 0,
- 'modified': '2012-05-03 09:55:18',
+ 'modified': '2012-05-16 13:29:26',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -49,25 +49,17 @@
'name': '__common__',
'parent': u'Print Format',
'parentfield': u'fields',
- 'parenttype': u'DocType',
- 'permlevel': 0
+ 'parenttype': u'DocType'
},
# These values are common for all DocPerm
{
- 'cancel': 0,
- 'create': 1,
'doctype': u'DocPerm',
- 'execute': 0,
'name': '__common__',
'parent': u'Print Format',
'parentfield': u'permissions',
'parenttype': u'DocType',
- 'permlevel': 0,
- 'read': 1,
- 'role': u'Administrator',
- 'submit': 0,
- 'write': 1
+ 'read': 1
},
# DocType, Print Format
@@ -78,7 +70,41 @@
# DocPerm
{
- 'doctype': u'DocPerm'
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'System Manager',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'cancel': 0,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'execute': 0,
+ 'permlevel': 0,
+ 'role': u'Administrator',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'System Manager'
+ },
+
+ # DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'Administrator',
+ 'write': 1
},
# DocField
@@ -94,6 +120,7 @@
'oldfieldname': u'module',
'oldfieldtype': u'Select',
'options': u'link:Module Def',
+ 'permlevel': 0,
'print_hide': 0,
'report_hide': 0,
'reqd': 1,
@@ -109,6 +136,7 @@
'in_filter': 1,
'label': u'DocType',
'options': u'link:DocType',
+ 'permlevel': 0,
'reqd': 0,
'search_index': 0
},
@@ -116,16 +144,19 @@
# DocField
{
'allow_on_submit': 0,
+ 'colour': u'White:FFF',
+ 'default': u'No',
'doctype': u'DocField',
'fieldname': u'standard',
'fieldtype': u'Select',
'hidden': 0,
'in_filter': 1,
'label': u'Standard',
- 'no_copy': 0,
+ 'no_copy': 1,
'oldfieldname': u'standard',
'oldfieldtype': u'Select',
- 'options': u'\nYes\nNo',
+ 'options': u'No\nYes',
+ 'permlevel': 1,
'print_hide': 0,
'report_hide': 0,
'reqd': 1,
@@ -145,6 +176,7 @@
'oldfieldname': u'html',
'oldfieldtype': u'Text Editor',
'options': u'HTML',
+ 'permlevel': 0,
'print_hide': 0,
'report_hide': 0,
'reqd': 0,
diff --git a/py/core/page/data_import_tool/__init__.py b/py/core/page/data_import_tool/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/py/core/page/data_import_tool/data_import_tool.css b/py/core/page/data_import_tool/data_import_tool.css
new file mode 100644
index 0000000000..2216e542c6
--- /dev/null
+++ b/py/core/page/data_import_tool/data_import_tool.css
@@ -0,0 +1,5 @@
+.float-column {
+ width: 40%;
+ float: left;
+ margin-right: 9%;
+}
\ No newline at end of file
diff --git a/py/core/page/data_import_tool/data_import_tool.html b/py/core/page/data_import_tool/data_import_tool.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/py/core/page/data_import_tool/data_import_tool.js b/py/core/page/data_import_tool/data_import_tool.js
new file mode 100644
index 0000000000..b10285d7c4
--- /dev/null
+++ b/py/core/page/data_import_tool/data_import_tool.js
@@ -0,0 +1,130 @@
+wn.pages['data-import-tool'].onload = function(wrapper) {
+ wrapper.app_page = wn.ui.make_app_page({
+ parent: wrapper,
+ title: "Data Import Tool"
+ });
+
+ $(wrapper).find('.layout-main-section').append('1. Download Template
\
+
\
+ \
+ Download with data\
+
\
+ 2. Import Data
\
+
\
+ \
+ ');
+
+ $(wrapper).find('.layout-side-section').append('Help
\
+ \
+
\
+
\
+ Save as type: Text Documents (*.txt)
\
+ Encoding: UTF-8\
+
').html(v).appendTo('#dit-output');
+ if(v.substr(0,5)=='Error') {
+ $p.css('color', 'red');
+ }
+ if(v.substr(0,8)=='Inserted') {
+ $p.css('color', 'green');
+ }
+ if(v.substr(0,7)=='Updated') {
+ $p.css('color', 'green');
+ }
+ });
+
+ }
+ });
+
+ // add overwrite option
+ $(' Overwrite
')
+ .insertBefore('#dit-upload-area form input[type="submit"]')
+
+ // rename button
+ $('#dit-upload-area form input[type="submit"]')
+ .attr('value', 'Upload and Import')
+ .click(function() {
+ $('#dit-output').html('Performing hardcore import process....')
+ });
+}
\ No newline at end of file
diff --git a/py/core/page/data_import_tool/data_import_tool.py b/py/core/page/data_import_tool/data_import_tool.py
new file mode 100644
index 0000000000..9814ec44db
--- /dev/null
+++ b/py/core/page/data_import_tool/data_import_tool.py
@@ -0,0 +1,223 @@
+import webnotes
+
+@webnotes.whitelist()
+def get_doctypes():
+ return [r[0] for r in webnotes.conn.sql("""select name from `tabDocType`
+ where document_type = 'Master'""")]
+
+@webnotes.whitelist()
+def get_doctype_options():
+ import webnotes
+ doctype = webnotes.form_dict['doctype']
+ import webnotes.model.doctype
+ return [doctype] + filter(None, map(lambda d: \
+ d.doctype=='DocField' and d.fieldtype=='Table' and d.options or None,
+ webnotes.model.doctype.get(doctype, form=0)))
+
+data_separator = '----Start entering data below this line----'
+
+doctype_dl = None
+
+@webnotes.whitelist(allow_roles=['System Manager', 'Administrator'])
+def get_template():
+ import webnotes, csv
+ from cStringIO import StringIO
+ import webnotes.model.doctype
+ global doctype_dl
+
+ doctype = webnotes.form_dict['doctype']
+ parentdoctype = webnotes.form_dict.get('parent_doctype')
+
+ doctype_dl = webnotes.model.doctype.get(doctype)
+ tablecolumns = [f[0] for f in webnotes.conn.sql('desc `tab%s`' % doctype)]
+
+ def getinforow(docfield):
+ """make info comment"""
+ if docfield.fieldtype == 'Select':
+ if docfield.options.startswith('link:'):
+ return 'Valid %s' % docfield.options[5:]
+ else:
+ return 'One of: %s' % ', '.join(filter(None, docfield.options.split('\n')))
+ if docfield.fieldtype == 'Link':
+ return 'Valid %s' % docfield.options
+ if docfield.fieldtype in ('Int'):
+ return 'Integer'
+ else:
+ return ''
+
+ tobj = StringIO()
+ w = csv.writer(tobj)
+ key = 'name'
+
+ w.writerow(['Upload Template for: %s' % doctype])
+
+ if parentdoctype != doctype:
+ w.writerow(['This is a child table for: %s' % parentdoctype])
+ key = 'parent'
+ else:
+ w.writerow([''])
+
+ w.writerow(['----'])
+
+ fieldrow = ['Column Name:', key]
+ mandatoryrow = ['Mandatory:', 'Yes']
+ typerow = ['Type:', 'Data (text)']
+ inforow = ['Info:', 'ID']
+ columns = [key]
+
+ def append_row(t, mandatory):
+ docfield = getdocfield(t)
+ if docfield and ((mandatory and docfield.reqd) or (not mandatory and not docfield.reqd)) \
+ and (t not in ('parenttype', 'trash_reason')):
+ fieldrow.append(t)
+ mandatoryrow.append(docfield.reqd and 'Yes' or 'No')
+ typerow.append(docfield.fieldtype)
+ inforow.append(getinforow(docfield))
+ columns.append(t)
+
+ # get all mandatory fields
+ for t in tablecolumns:
+ append_row(t, True)
+
+ # all non mandatory fields
+ for t in tablecolumns:
+ append_row(t, False)
+
+ w.writerow(fieldrow)
+ w.writerow(mandatoryrow)
+ w.writerow(typerow)
+ w.writerow(inforow)
+
+ w.writerow([data_separator])
+
+ if webnotes.form_dict.get('with_data')=='Yes':
+ data = webnotes.conn.sql("""select * from `tab%s` where docstatus<2""" % doctype, as_dict=1)
+ for d in data:
+ row = ['']
+ for c in columns:
+ val = d.get(c, '')
+ if type(val) is unicode:
+ val = val.encode('utf-8')
+ row.append(val)
+ w.writerow(row)
+
+ # write out response as a type csv
+ webnotes.response['result'] = tobj.getvalue()
+ webnotes.response['type'] = 'csv'
+ webnotes.response['doctype'] = doctype
+
+def getdocfield(fieldname):
+ """get docfield from doclist of doctype"""
+ l = [d for d in doctype_dl if d.doctype=='DocField' and d.fieldname==fieldname]
+ return l and l[0] or None
+
+@webnotes.whitelist(allow_roles=['System Manager', 'Administrator'])
+def upload():
+ """upload data"""
+ import csv
+ global doctype_dl
+ from webnotes.utils.file_manager import get_uploaded_content
+ import webnotes.model.doctype
+ from webnotes.model.doc import Document
+
+ fname, fcontent = get_uploaded_content()
+ overwrite = webnotes.form_dict.get('overwrite')
+
+ ret, rows = [], []
+ try:
+ reader = csv.reader(fcontent.splitlines())
+ # decode everything
+ for row in reader:
+ rows.append([unicode(c.strip(), 'utf-8') for c in row])
+ except Exception, e:
+ webnotes.msgprint("Not a valid Comma Separated Value (CSV File)")
+ raise e
+
+
+ # doctype
+ doctype = rows[0][0].split(':')[1].strip()
+ doctype_dl = webnotes.model.doctype.get(doctype, form=0)
+
+ parentdoctype = None
+ if len(rows[1]) > 0 and ':' in rows[1][0]:
+ parentdoctype = rows[1][0].split(':')[1].strip()
+
+ # columns
+ columns = rows[3][1:]
+
+ if parentdoctype and overwrite:
+ delete_child_rows(rows, doctype)
+
+ for row in rows[8:]:
+ d = dict(zip(columns, row[1:]))
+ d['doctype'] = doctype
+
+ try:
+ check_record(d, parentdoctype)
+ if parentdoctype:
+ # child doc
+ doc = Document(doctype)
+ doc.fields.update(d)
+ doc.save()
+ ret.append('Inserted row for %s at #%s' % (getlink(parentdoctype, doc.parent),
+ str(doc.idx)))
+ else:
+ ret.append(import_doc(d, doctype, overwrite))
+ except Exception, e:
+ ret.append('Error for ' + row[1] + ': ' + str(e))
+ webnotes.errprint(webnotes.getTraceback())
+ return ret
+
+def check_record(d, parentdoctype):
+ """check for mandatory, select options, dates. these should ideally be in doclist"""
+ if parentdoctype and not d.get('parent'):
+ raise Exception, "parent is required."
+
+ for key in d:
+ docfield = getdocfield(key)
+ val = d[key]
+ if docfield:
+ if docfield.reqd and (val=='' or val==None):
+ raise Exception, "%s is mandatory." % key
+
+ if docfield.fieldtype=='Select':
+ if docfield.options.startswith('link:'):
+ if val:
+ link_doctype = docfield.options.split(':')[1]
+ if not webnotes.conn.exists(link_doctype, val):
+ raise Exception, "%s must be a valid %s" % (key, link_doctype)
+ else:
+ if val not in docfield.options.split('\n'):
+ raise Exception, "%s must be one of:" % key
+
+ if docfield.fieldtype=='Date' and val:
+ import datetime
+ datetime.datetime.strptime(val, '%Y-%m-%d')
+
+def getlink(doctype, name):
+ return '%(name)s' % locals()
+
+def delete_child_rows(rows, doctype):
+ """delete child rows for all parents"""
+ import webnotes
+ for p in list(set([r[1] for r in rows[8:]])):
+ webnotes.conn.sql("""delete from `tab%s` where parent=%s""" % (doctype, '%s'), p)
+
+def import_doc(d, doctype, overwrite):
+ """import main (non child) document"""
+ import webnotes
+ from webnotes.model.doc import Document
+ from webnotes.model.doclist import DocList
+
+ if webnotes.conn.exists(doctype, d['name']):
+ if overwrite:
+ doc = Document(doctype, d['name'])
+ doc.fields.update(d)
+ DocList([doc]).save()
+ return 'Updated ' + getlink(doctype, d['name'])
+ else:
+ return 'Ignored ' + getlink(doctype, d['name']) + ' (exists)'
+ else:
+ d['__islocal'] = 1
+ DocList([Document(fielddata = d)]).save()
+ return 'Inserted ' + getlink(doctype, d['name'])
\ No newline at end of file
diff --git a/py/core/page/data_import_tool/data_import_tool.txt b/py/core/page/data_import_tool/data_import_tool.txt
new file mode 100644
index 0000000000..b6bfad2208
--- /dev/null
+++ b/py/core/page/data_import_tool/data_import_tool.txt
@@ -0,0 +1,29 @@
+# Page, data-import-tool
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-05-10 10:06:00',
+ 'docstatus': 0,
+ 'modified': '2012-05-10 10:06:00',
+ 'modified_by': u'Administrator',
+ 'owner': u'Administrator'
+ },
+
+ # These values are common for all Page
+ {
+ 'doctype': 'Page',
+ 'module': u'Core',
+ 'name': '__common__',
+ 'page_name': u'Data Import Tool',
+ 'standard': u'Yes',
+ 'title': u'Data Import Tool',
+ 'web_page': u'No'
+ },
+
+ # Page, data-import-tool
+ {
+ 'doctype': 'Page',
+ 'name': u'data-import-tool'
+ }
+]
\ No newline at end of file
diff --git a/py/webnotes/__init__.py b/py/webnotes/__init__.py
index 265afae3ca..822e9e3fef 100644
--- a/py/webnotes/__init__.py
+++ b/py/webnotes/__init__.py
@@ -95,7 +95,7 @@ def msgprint(msg, small=0, raise_exception=0, as_table=False):
message_log.append((small and '__small:' or '')+cstr(msg or ''))
if raise_exception:
- raise ValidationError
+ raise ValidationError, msg
def is_apache_user():
import os
@@ -190,12 +190,14 @@ def get_db_password(db_name):
whitelisted = []
guest_methods = []
-def whitelist(allow_guest=False):
+def whitelist(allow_guest=False, allow_roles=[]):
"""
decorator for whitelisting a function
Note: if the function is allowed to be accessed by a guest user,
it must explicitly be marked as allow_guest=True
+
+ for specific roles, set allow_roles = ['Administrator'] etc.
"""
def innerfn(fn):
global whitelisted, guest_methods
@@ -204,6 +206,17 @@ def whitelist(allow_guest=False):
if allow_guest:
guest_methods.append(fn)
+ if allow_roles:
+ roles = get_roles()
+ allowed = False
+ for role in allow_roles:
+ if role in roles:
+ allowed = True
+ break
+
+ if not allowed:
+ raise PermissionError, "Method not allowed"
+
return fn
return innerfn
diff --git a/py/webnotes/cms/make.py b/py/webnotes/cms/make.py
index c14105ffd2..ecd1d4af91 100644
--- a/py/webnotes/cms/make.py
+++ b/py/webnotes/cms/make.py
@@ -5,6 +5,7 @@ make index, wn.js, wn.css pages
def make():
import os
import webnotes
+ # TODO: why is jinja2 imported?
from jinja2 import Template
import webnotes.cms
diff --git a/py/webnotes/db.py b/py/webnotes/db.py
index cb9f40e746..1422739dd4 100644
--- a/py/webnotes/db.py
+++ b/py/webnotes/db.py
@@ -259,10 +259,10 @@ class Database:
r = self.sql("select value from tabSingles where field in ('%s') and doctype='%s'" % (fieldname, doctype))
return r and (len(r) > 1 and (i[0] for i in r) or r[0][0]) or None
- def set_value(self, dt, dn, field, val):
+ def set_value(self, dt, dn, field, val, modified = None):
from webnotes.utils import now
if dn and dt!=dn:
- self.sql("update `tab"+dt+"` set `"+field+"`=%s, modified=%s where name=%s", (val, now(), dn))
+ self.sql("update `tab"+dt+"` set `"+field+"`=%s, modified=%s where name=%s", (val, modified or now(), dn))
else:
if self.sql("select value from tabSingles where field=%s and doctype=%s", (field, dt)):
self.sql("update tabSingles set value=%s where field=%s and doctype=%s", (val, field, dt))
@@ -270,7 +270,7 @@ class Database:
self.sql("insert into tabSingles(doctype, field, value) values (%s, %s, %s)", (dt, field, val))
def set(self, doc, field, val):
- self.set_value(doc.doctype, doc.name, field, val)
+ self.set_value(doc.doctype, doc.name, field, val, doc.modified)
doc.fields[field] = val
# ======================================================================================
diff --git a/py/webnotes/handler.py b/py/webnotes/handler.py
index 707c43a637..04e3717cfe 100755
--- a/py/webnotes/handler.py
+++ b/py/webnotes/handler.py
@@ -127,66 +127,35 @@ def get_template():
@webnotes.whitelist()
def uploadfile():
+ import webnotes.utils
import webnotes.utils.file_manager
- if webnotes.form_dict.get('from_form'):
- webnotes.utils.file_manager.upload()
- else:
- # save the file
- fid, fname = webnotes.utils.file_manager.save_uploaded()
-
- # do something with the uploaded file
- if fid:
- if webnotes.form_dict.get('server_obj'):
- from webnotes.model.code import get_obj
- getattr(get_obj(webnotes.form_dict.get('server_obj')), webnotes.form_dict.get('method'))(fid, fname)
-
- elif webnotes.form_dict.get('modulename'):
- # calls a python module to handle the script
- __import__(webnotes.form_dict['modulename'])
+ import json
+
+ ret = []
+
+ try:
+ if webnotes.form_dict.get('from_form'):
+ webnotes.utils.file_manager.upload()
+ else:
+ if webnotes.form_dict.get('method'):
+ m = webnotes.form_dict['method']
+ modulename = '.'.join(m.split('.')[:-1])
+ methodname = m.split('.')[-1]
+
+ __import__(modulename)
import sys
- moduleobj = sys.modules[webnotes.form_dict['modulename']]
- getattr(moduleobj, webnotes.form_dict['method'])(fid, fname)
+ moduleobj = sys.modules[modulename]
+ ret = getattr(moduleobj, methodname)()
+ except Exception, e:
+ webnotes.msgprint(e)
+ webnotes.errprint(webnotes.utils.getTraceback())
-
- webnotes.response['result'] = ''
-
-# File upload (from scripts)
-# ------------------------------------------------------------------------------------
-
-@webnotes.whitelist()
-def upload_many():
- from webnotes.model.code import get_obj
-
- # pass it on to upload_many method in Control Panel
- cp = get_obj('Control Panel')
- cp.upload_many(webnotes.form)
-
- webnotes.response['result'] = """
-
-%s
-%s""" % (cp.upload_callback(webnotes.form), '\n----\n'.join(webnotes.message_log).replace("'", "\'"), '\n----\n'.join(webnotes.debug_log).replace("'", "\'").replace("\n","
"))
webnotes.response['type'] = 'iframe'
-
-
-@webnotes.whitelist()
-def get_file():
- import webnotes
- import webnotes.utils.file_manager
- form = webnotes.form
-
- res = webnotes.utils.file_manager.get_file(form.getvalue('fname'))
- if res:
- webnotes.response['type'] = 'download'
- webnotes.response['filename'] = res[0]
-
- if hasattr(res[1], 'tostring'):
- webnotes.response['filecontent'] = res[1].tostring()
- else:
- webnotes.response['filecontent'] = res[1]
- else:
- webnotes.msgprint('[get_file] Unknown file name')
+ if not webnotes.response.get('result'):
+ webnotes.response['result'] = """""" % (webnotes.form_dict.get('_id'),
+ json.dumps(ret))
@webnotes.whitelist(allow_guest=True)
def reset_password():
@@ -299,12 +268,25 @@ def print_csv():
print webnotes.response['result']
def print_iframe():
+ import json
print "Content-Type: text/html"
print
if webnotes.response.get('result'):
print webnotes.response['result']
if webnotes.debug_log:
- print '''''' % ('-------'.join(webnotes.debug_log).replace('"', '').replace('\n',''))
+ print """
+ """ % (json.dumps(webnotes.message_log), json.dumps(webnotes.debug_log))
def print_raw():
import mimetypes
diff --git a/py/webnotes/model/code.py b/py/webnotes/model/code.py
index fea49ee4dd..f6bc3f7795 100644
--- a/py/webnotes/model/code.py
+++ b/py/webnotes/model/code.py
@@ -39,7 +39,7 @@ import webnotes
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists
-from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
+from webnotes.model.doc import Document, addchild, getchildren, make_autoname
from webnotes.model.utils import getlist
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
from webnotes import session, form, is_testing, msgprint, errprint
@@ -70,7 +70,7 @@ def execute(code, doc=None, doclist=[]):
# --------------------------------------------------
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists
- from webnotes.model.doc import Document, addchild, removechild, getchildren
+ from webnotes.model.doc import Document, addchild, getchildren
from webnotes.model.utils import getlist
from webnotes import session, form, msgprint, errprint
diff --git a/py/webnotes/model/doc.py b/py/webnotes/model/doc.py
index 7cbe1ac4c3..7849c265a7 100755
--- a/py/webnotes/model/doc.py
+++ b/py/webnotes/model/doc.py
@@ -29,19 +29,6 @@ import webnotes.model.meta
from webnotes.utils import *
-# actually should be "BaseDocType" - deprecated. Only for v160
-class SuperDocType:
- def __init__(self):
- pass
-
- def __getattr__(self, name):
- if self.__dict__.has_key(name):
- return self.__dict__[name]
- elif self.super and hasattr(self.super, name):
- return getattr(self.super, name)
- else:
- raise AttributeError, 'BaseDocType Attribute Error'
-
class Document:
"""
The wn(meta-data)framework equivalent of a Database Record.
@@ -208,7 +195,6 @@ class Document:
# amendments
if self.amended_from:
self._get_amended_name()
-
# by method
elif so and hasattr(so, 'autoname'):
r = webnotes.model.code.run_server_obj(so, 'autoname')
@@ -401,6 +387,9 @@ class Document:
# add missing parentinfo (if reqd)
if self.parent and not (self.parenttype and self.parentfield):
self.update_parentinfo()
+
+ if self.parent and not self.idx:
+ self.set_idx()
# if required, make new
if new or (not new and self.fields.get('__islocal')) and (not res.get('issingle')):
@@ -431,6 +420,12 @@ class Document:
self.parenttype = tmp[0][0]
self.parentfield = tmp[0][1]
+ def set_idx(self):
+ """set idx"""
+ self.idx = (webnotes.conn.sql("""select max(idx) from `tab%s`
+ where parent=%s and parentfield=%s""" % (self.doctype, '%s', '%s'),
+ (self.parent, self.parentfield))[0][0] or 0) + 1
+
# check permissions
# ---------------------------------------------------------------------------
@@ -560,20 +555,6 @@ def addchild(parent, fieldname, childtype = '', local=0, doclist=None):
d.save(1)
"""
return parent.addchild(fieldname, childtype, local, doclist)
-
-# Remove Child
-# ------------
-
-def removechild(d, is_local = 0):
- """
- Sets the docstatus of the object d to 2 (deleted) and appends an 'old_parent:' to the parent name
- """
- if not is_local:
- set(d, 'docstatus', 2)
- set(d, 'parent', 'old_parent:' + d.parent)
- else:
- d.parent = 'old_parent:' + d.parent
- d.docstatus = 2
# Naming
# ------
@@ -645,11 +626,12 @@ def getchildren(name, childtype, field='', parenttype='', from_doctype=0, prefix
if field:
tmp = ' and parentfield="%s" ' % field
- if parenttype:
+ if parenttype:
tmp = ' and parenttype="%s" ' % parenttype
try:
- dataset = webnotes.conn.sql("select * from `%s%s` where parent='%s' %s order by idx" % (prefix, childtype, name, tmp))
+ dataset = webnotes.conn.sql("select * from `%s%s` where parent='%s' %s order by idx" \
+ % (prefix, childtype, name, tmp))
desc = webnotes.conn.get_description()
except Exception, e:
if prefix=='arc' and e.args[0]==1146:
diff --git a/py/webnotes/model/doclist.py b/py/webnotes/model/doclist.py
index 04fbdbb9d9..c1c4250877 100644
--- a/py/webnotes/model/doclist.py
+++ b/py/webnotes/model/doclist.py
@@ -40,6 +40,10 @@ class DocList:
self.to_docstatus = 0
if dt and dn:
self.load_from_db(dt, dn)
+ if type(dt) is list:
+ self.docs = dt
+ self.doc = dt[0]
+ self.children = dt[1:]
def load_from_db(self, dt, dn, prefix='tab'):
"""
diff --git a/py/webnotes/model/doctype.py b/py/webnotes/model/doctype.py
index d1044ac724..92effe37fd 100644
--- a/py/webnotes/model/doctype.py
+++ b/py/webnotes/model/doctype.py
@@ -368,7 +368,7 @@ class _DocType:
def insert_into_cache(self, doclist):
import json
json_doclist = json.dumps([d.fields for d in doclist])
- CacheItem(self.name).set(json_doclist, 3600)
+ CacheItem(self.name).set(json_doclist)
def get(dt, form=1):
"""
diff --git a/py/webnotes/model/sync.py b/py/webnotes/model/sync.py
index 1702b95fcc..c900096597 100644
--- a/py/webnotes/model/sync.py
+++ b/py/webnotes/model/sync.py
@@ -49,8 +49,8 @@ def walk_and_sync(start_path, force=0):
if doctype == 'doctype':
sync(module_name, name, force)
- elif doctype == 'page':
- reload_doc(module_name, 'page', name)
+ elif doctype in ['page']:#, 'search_criteria', 'Print Format', 'DocType Mapper']:
+ reload_doc(module_name, doctype, name)
print module_name + ' | ' + doctype + ' | ' + name
return modules
diff --git a/py/webnotes/utils/cache.py b/py/webnotes/utils/cache.py
index bf48cc4957..3404ec201b 100644
--- a/py/webnotes/utils/cache.py
+++ b/py/webnotes/utils/cache.py
@@ -48,19 +48,25 @@ class CacheItem:
def get(self):
"""get value"""
try:
- return webnotes.conn.sql("select `value` from __CacheItem where `key`=%s and expires_on > NOW()", self.key)[0][0]
+ return webnotes.conn.sql("""select `value` from __CacheItem where
+ `key`=%s and ifnull(expires_on, '2100-01-01') > NOW()""", self.key)[0][0]
except Exception:
return None
- def set(self, value, interval=6000):
+ def set(self, value, interval=None):
"""set a new value, with interval"""
self.clear()
- webnotes.conn.sql("""INSERT INTO
- __CacheItem (`key`, `value`, expires_on)
- VALUES
- (%s, %s, addtime(now(), sec_to_time(%s)))
- """, (self.key, str(value), interval))
-
+ if interval:
+ webnotes.conn.sql("""insert into
+ __CacheItem (`key`, `value`, expires_on)
+ values (%s, %s, addtime(now(), sec_to_time(%s)))
+ """, (self.key, str(value), interval))
+ else:
+ webnotes.conn.sql("""insert into
+ __CacheItem (`key`, `value`)
+ values (%s, %s)
+ """, (self.key, str(value)))
+
def clear(self):
"""clear the item"""
diff --git a/py/webnotes/utils/file_manager.py b/py/webnotes/utils/file_manager.py
index bba1874ee2..bba3624cca 100644
--- a/py/webnotes/utils/file_manager.py
+++ b/py/webnotes/utils/file_manager.py
@@ -70,26 +70,17 @@ def add_file_list(dt, dn, fname, fid):
"""
udpate file_list attribute of the record
"""
- try:
- # get the old file_list
- fl = webnotes.conn.get_value(dt, dn, 'file_list') or ''
- if fl:
- fl += '\n'
-
- # add new file id
- fl += fname + ',' + fid
-
- # save
- webnotes.conn.set_value(dt, dn, 'file_list', fl)
-
- return True
+ fl = webnotes.conn.get_value(dt, dn, 'file_list') or ''
+ if fl:
+ fl += '\n'
+
+ # add new file id
+ fl += fname + ',' + fid
- except Exception, e:
- webnotes.response['result'] = """
-""" % str(e)
+ # save
+ webnotes.conn.set_value(dt, dn, 'file_list', fl)
+ return True
def remove_all(dt, dn):
"""remove all files in a transaction"""
@@ -107,7 +98,7 @@ def remove_file(dt, dn, fid):
new_fl = []
fl = fl.split('\n')
for f in fl:
- if f.split(',')[1]!=fid:
+ if f and f.split(',')[1]!=fid:
new_fl.append(f)
# delete
@@ -133,37 +124,31 @@ def make_thumbnail(blob, size):
return fcontent
+def get_uploaded_content():
+ import webnotes
+
+ if 'filedata' in webnotes.form:
+ i = webnotes.form['filedata']
+ webnotes.uploaded_filename, webnotes.uploaded_content = i.filename, i.file.read()
+ return webnotes.uploaded_filename, webnotes.uploaded_content
+ else:
+ webnotes.msgprint('No File');
+ return None, None
-def save_uploaded(js_okay='window.parent.msgprint("File Upload Successful")', js_fail=''):
+def save_uploaded():
import webnotes.utils
webnotes.response['type'] = 'iframe'
- form, fid, fname = webnotes.form, None, None
+ form = webnotes.form
- try:
- # has attachment?
- if 'filedata' in form:
- i = form['filedata']
-
- fname, content = i.filename, i.file.read()
+ fname, content = get_uploaded_content()
+ if content:
+ fid = save_file(fname, content)
+ return fid, fname
- # get the file id
- fid = save_file(fname, content)
-
- # okay
- webnotes.response['result'] = """""" % js_okay
- else:
- webnotes.response['result'] = """""" % js_fail
-
- except Exception, e:
- webnotes.response['result'] = """""" % (str(e), \
- webnotes.utils.getTraceback().replace('\n','
').replace('"', '\\"'), js_fail)
-
- return fid, fname
+ else:
+ return None, fname
# -------------------------------------------------------
@@ -227,12 +212,8 @@ def delete_file(fid, verbose=0):
path = os.path.join(webnotes.get_files_path(), fid.replace('/','-'))
if os.path.exists(path):
os.remove(path)
-
-# Get File
-# -------------------------------------------------------
-
+
def get_file(fname):
- """deprecated"""
f = get_file_system_name(fname)
if f:
file_id = f[0][0].replace('/','-')
@@ -246,7 +227,4 @@ def get_file(fname):
with open(os.path.join(webnotes.get_files_path(), file_id), 'r') as f:
content = f.read()
- return [file_name, content]
-
-
-# -------------------------------------------------------
+ return [file_name, content]
\ No newline at end of file
diff --git a/py/webnotes/widgets/search.py b/py/webnotes/widgets/search.py
index f85254e571..a69d6eb33d 100644
--- a/py/webnotes/widgets/search.py
+++ b/py/webnotes/widgets/search.py
@@ -49,7 +49,7 @@ def getsearchfields():
webnotes.response['searchfields'] = [['name', 'ID', 'Data', '']] + res
def make_query(fields, dt, key, txt, start, length):
- return """SELECT %(fields)s
+ query = """SELECT %(fields)s
FROM `tab%(dt)s`
WHERE `tab%(dt)s`.`%(key)s` LIKE '%(txt)s' AND `tab%(dt)s`.docstatus != 2
ORDER BY `tab%(dt)s`.`%(key)s`
@@ -61,6 +61,7 @@ def make_query(fields, dt, key, txt, start, length):
'start': start,
'len': length
}
+ return query
def get_std_fields_list(dt, key):
# get additional search fields
@@ -102,6 +103,12 @@ def search_link():
txt = webnotes.form.getvalue('txt')
dt = webnotes.form.getvalue('dt')
query = webnotes.form.getvalue('query')
+
+ # txt - decode it to utf-8. why to do this?
+ # "%(something_unicode)s %(something ascii encoded with utf-8)s"
+ # tries to decode ascii string using ascii codec and not utf-8
+ # since web pages are encoded in utf-8, we can force decode to utf-8
+ txt = txt.decode('utf-8')
if query:
res = webnotes.conn.sql(scrub_custom_query(query, 'name', txt))
@@ -122,6 +129,12 @@ def search_widget():
key = webnotes.form.getvalue('searchfield') or 'name' # key field
user_query = webnotes.form.getvalue('query') or ''
+ # txt - decode it to utf-8. why to do this?
+ # "%(something_unicode)s %(something ascii encoded with utf-8)s"
+ # tries to decode ascii string using ascii codec and not utf-8
+ # since web pages are encoded in utf-8, we can force decode to utf-8
+ txt = txt.decode('utf-8')
+
if user_query:
query = scrub_custom_query(user_query, key, txt)
else:
diff --git a/wnf.py b/wnf.py
index 1290adf807..6fb3c8ca87 100755
--- a/wnf.py
+++ b/wnf.py
@@ -84,6 +84,8 @@ def setup_options():
# build
parser.add_option("-b", "--build", default=False, action="store_true",
help="minify + concat js files")
+ parser.add_option("--cms", default=False, action="store_true",
+ help="take a dump of website pages, js and css")
# git
parser.add_option("--status", default=False, action="store_true",
@@ -162,13 +164,22 @@ def run():
webnotes.connect(options.db_name, options.password)
else:
webnotes.connect(options.db_name)
- elif not options.install:
+ elif not any([options.install, options.pull]):
webnotes.connect(conf.db_name)
# build
if options.build:
import build.project
- build.project.build()
+ build.project.build()
+
+ elif options.cms:
+ from webnotes.model.code import get_obj
+ # rewrite pages
+ ws = get_obj('Website Settings')
+ ws.rewrite_pages()
+ ss = get_obj('Style Settings')
+ ss.validate()
+ ss.on_update()
# code replace
elif options.replace: