diff --git a/conf/index.html b/conf/index.html new file mode 100644 index 0000000000..9a6bd71f4f --- /dev/null +++ b/conf/index.html @@ -0,0 +1,15 @@ + + + + ERPNext + {{ ajax_meta_tag }} + + + + + {{ body_html }} + diff --git a/css/legacy/default.css b/css/legacy/default.css index 1541e0dda0..c5c66a0e1d 100644 --- a/css/legacy/default.css +++ b/css/legacy/default.css @@ -1,8 +1,7 @@ /* -* lib/css/legacy/body.css -*/ -html { + * lib/css/legacy/body.css + */html { margin: 0px; padding: 0px; } @@ -179,9 +178,8 @@ div.std-footer-item { } /* -* lib/css/legacy/menus.css -*/ - + * lib/css/legacy/menus.css + */ /******** Menus - menu.js ************/ ul.menu_toolbar { @@ -233,9 +231,8 @@ div.dd_item { } div.dd_item_mo { background-color: #FE8; } /* -* lib/css/legacy/messages.css -*/ - + * lib/css/legacy/messages.css + */ /* FLOATING MESSAGE */ .btn-img { cursor: pointer; } @@ -284,9 +281,8 @@ div.notice { font-size: 14px; } /* -* lib/css/legacy/forms.css -*/ -/* FORMS */ + * lib/css/legacy/forms.css + *//* FORMS */ div.frm_print_wrapper { @@ -508,9 +504,8 @@ div.sidebar-comment-info { color: #777; } /* -* lib/css/legacy/grid.css -*/ - + * lib/css/legacy/grid.css + */ /* Grid */ @@ -633,9 +628,8 @@ div.sidebar-comment-info { .gridDivSelected option { border: 0px; } /* -* lib/css/legacy/listing.css -*/ -/* listing 2.0 */ + * lib/css/legacy/listing.css + *//* listing 2.0 */ div.listing-more { margin: 7px 0px 17px 0px; @@ -693,9 +687,8 @@ div.srs_filter_area td { /* -* lib/css/legacy/report.css -*/ - + * lib/css/legacy/report.css + */ /* Reports */ div.report_grid_area { @@ -876,9 +869,8 @@ table.builder_tab td { padding: 2px; } /* -* lib/css/legacy/calendar.css -*/ -/**** CALENDAR ****/ + * lib/css/legacy/calendar.css + *//**** CALENDAR ****/ .caldiv { position:absolute; @@ -1051,9 +1043,8 @@ div.cal_event_hover { } /* -* lib/css/legacy/autosuggest.css -*/ -/* + * lib/css/legacy/autosuggest.css + *//* ================================================ autosuggest, inquisitor style ================================================ @@ -1146,9 +1137,8 @@ div.autosuggest ul em } /* -* lib/css/legacy/dialog.css -*/ -/***** Dialogs *******/ + * lib/css/legacy/dialog.css + *//***** Dialogs *******/ div.dialog_wrapper { position: absolute; @@ -1227,9 +1217,8 @@ div.dialog_row table td textarea { } /* -* lib/css/legacy/wntoolbar.css -*/ - + * lib/css/legacy/wntoolbar.css + */ /* Recent */ div.status_flag { @@ -1256,9 +1245,8 @@ div.status_flag { .sprite-search { background-position: 0 -330px; } .sprite-tools { background-position: 0 -396px; } /* -* lib/css/legacy/tabs.css -*/ - + * lib/css/legacy/tabs.css + */ /******* TABS ********/ div.box_label_wrapper { @@ -1318,9 +1306,8 @@ ul.box_tabs li.box_tab_selected a { } /* -* lib/css/legacy/bw-icons.css -*/ - + * lib/css/legacy/bw-icons.css + */ /** general icons **/ .wn-icon { background: url('lib/images/icons/icons.png'); width: 16px; height: 16px; cursor: pointer; } @@ -1572,9 +1559,8 @@ ul.box_tabs li.box_tab_selected a { /* -* lib/css/legacy/sidebar.css -*/ -div.psidebar-wrapper { + * lib/css/legacy/sidebar.css + */div.psidebar-wrapper { margin: 0px 8px; } @@ -1624,9 +1610,8 @@ div.follower-list { font-size: 11px; } /* -* lib/css/legacy/bootstrap-buttons.css -*/ -.btn.danger, + * lib/css/legacy/bootstrap-buttons.css + */.btn.danger, .alert-message.danger, .btn.danger:hover, .alert-message.danger:hover, diff --git a/js/core.min.js b/js/core.min.js index b60a3b02ca..9045714dd4 100644 --- a/js/core.min.js +++ b/js/core.min.js @@ -1,53 +1,46 @@ /* -* lib/js/wn/class.js -*/ - + * lib/js/wn/class.js + */ (function(){var initializing=false,fnTest=/xyz/.test(function(){xyz;})?/\b_super\b/:/.*/;this.Class=function(){};Class.extend=function(prop){var _super=this.prototype;initializing=true;var prototype=new this();initializing=false;for(var name in prop){prototype[name]=typeof prop[name]=="function"&&typeof _super[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,prop[name]):prop[name];} function Class(){if(!initializing&&this.init) this.init.apply(this,arguments);} Class.prototype=prototype;Class.prototype.constructor=Class;Class.extend=arguments.callee;return Class;};})(); /* -* lib/js/wn/provide.js -*/ - -wn={} + * lib/js/wn/provide.js + */ +if(!window.wn)wn={} wn.provide=function(namespace){var nsl=namespace.split('.');var l=nsl.length;var parent=window;for(var i=0;i'+val+'';}} /* -* lib/js/legacy/widgets/form/grid.js -*/ - + * lib/js/legacy/widgets/form/grid.js + */ _f.cur_grid_cell=null;_f.Grid=function(parent){} _f.Grid.prototype.init=function(parent,row_height){this.col_idx_by_name={} this.alt_row_bg='#F2F2FF';this.row_height=row_height;if(!row_height)this.row_height='26px';this.make_ui(parent);this.insert_column('','','Int','Sr','50px','',[1,0,0]);if(this.oninit)this.oninit();keypress_observers.push(this);var me=this;$(cur_frm.wrapper).bind('render_complete',function(){me.set_ht();});} @@ -328,9 +323,8 @@ _f.Grid.prototype.set_ht=function(){var max_ht=cint(0.37*screen.width);var ht=$( ht=100;if(ht>max_ht)ht=max_ht;ht+=4;$y(this.wrapper,{height:ht+'px'});} _f.Grid.prototype.refresh_row=function(ridx,docname){var row=this.tab.rows[ridx];row.docname=docname;row.is_newrow=false;for(var cidx=0;cidx1)?me.table_list:me.table_list[0];} /* -* lib/js/legacy/widgets/form/email.js -*/ - + * lib/js/legacy/widgets/form/email.js + */ _e.email_as_field='email_id';_e.email_as_dt='Contact';_e.email_as_in='email_id,contact_name';sendmail=function(emailto,emailfrom,cc,subject,message,fmt,with_attachments){var fn=function(html){$c('webnotes.utils.email_lib.send_form',{'sendto':emailto,'sendfrom':emailfrom?emailfrom:'','cc':cc?cc:'','subject':subject,'message':replace_newlines(message),'body':html,'full_domain':wn.urllib.get_base_url(),'with_attachments':with_attachments?1:0,'dt':cur_frm.doctype,'dn':cur_frm.docname},function(r,rtxt){});} _p.build(fmt,fn);} _e.make=function(){var d=new Dialog(440,440,"Send Email");var email_go=function(){var emailfrom=d.widgets['From'].value;var emailto=d.widgets['To'].value;if(!emailfrom) @@ -469,9 +461,8 @@ as.createList(as.aSug);} $c('webnotes.utils.email_lib.get_contact_list',{'select':_e.email_as_field,'from':_e.email_as_dt,'where':_e.email_as_in,'txt':(last_txt?strip(last_txt):'%')},call_back);return;} var sel;_e.dialog=d;} /* -* lib/js/legacy/widgets/form/clientscriptAPI.js -*/ - + * lib/js/legacy/widgets/form/clientscriptAPI.js + */ $c_get_values=function(args,doc,dt,dn,user_callback){var call_back=function(r,rt){if(!r.message)return;if(user_callback)user_callback(r.message);var fl=args.fields.split(',');for(var i in fl){locals[dt][dn][fl[i]]=r.message[fl[i]];if(args.table_field) refresh_field(fl[i],dn,args.table_field);else refresh_field(fl[i]);}} @@ -495,9 +486,8 @@ unhide_field=function(n){function _hide_field(n,hidden){var df=get_field(cur_frm if(cur_frm){if(n.substr)_hide_field(n,0);else{for(var i in n)_hide_field(n[i],0)}}} get_field_obj=function(fn){return cur_frm.fields_dict[fn];} /* -* lib/js/legacy/widgets/form/form_comments.js -*/ - + * lib/js/legacy/widgets/form/form_comments.js + */ wn.widgets.form.comments={n_comments:{},comment_list:{},sync:function(dt,dn,r){var f=wn.widgets.form.comments;f.n_comments[dn]=r.n_comments;f.comment_list[dn]=r.comment_list;},add:function(input,dt,dn,callback){$c('webnotes.widgets.form.comments.add_comment',wn.widgets.form.comments.get_args(input,dt,dn),function(r,rt){wn.widgets.form.comments.update_comment_list(input,dt,dn);input.value='';callback(input,dt,dn);});},remove:function(dt,dn,comment_id,callback){$c('webnotes.widgets.form.comments.remove_comment',{id:comment_id,dt:dt,dn:dn},callback);},get_args:function(input,dt,dn){return{comment:input.value,comment_by:user,comment_by_fullname:user_fullname,comment_doctype:dt,comment_docname:dn}},update_comment_list:function(input,dt,dn){var f=wn.widgets.form.comments;f.n_comments[dn]=cint(f.n_comments[dn])+1;f.comment_list[dn]=add_lists([f.get_args(input,dt,dn)],f.comment_list[dn]);}} CommentList=function(parent,dt,dn){this.wrapper=$a(parent,'div','',{margin:'16px'});this.input_area=$a(this.wrapper,'div','',{margin:'2px'});this.lst_area=$a(this.wrapper,'div','',{margin:'2px'});this.make_input();this.make_lst();this.dt;this.dn;} CommentList.prototype.run=function(){this.lst.run();} @@ -516,16 +506,14 @@ else{time=hr+':'+min+' AM'}} this.cmt_dtl.innerHTML='On '+d[ri][10].substring(0,3)+' '+d[ri][9]+', '+d[ri][11]+' at '+time;this.cmt.innerHTML=replace_newlines(d[ri][1]);} CommentItem.prototype.cmt_delete=function(cell,ri,ci,d){var me=this;if(d[ri][2]==user||d[ri][3]==user){del=$a(cell,'div','wn-icon ic-trash',{cursor:'pointer'});del.cmt_id=d[ri][0];del.onclick=function(){wn.widgets.form.comments.remove(cur_frm.doctype,cur_frm.docname,this.cmt_id,function(){me.comment.lst.run();})}}} /* -* lib/js/legacy/wn/widgets/form/sidebar.js -*/ - + * lib/js/legacy/wn/widgets/form/sidebar.js + */ wn.widgets.form.sidebar={Sidebar:function(form){var me=this;this.form=form;this.opts={sections:[{title:'Actions',items:[{type:'link',label:'New',icon:'ic-doc_new',display:function(){return in_list(profile.can_create,form.doctype)},onclick:function(){new_doc(me.form.doctype)}},{type:'link',label:'Refresh',icon:'ic-playback_reload',onclick:function(){me.form.reload_doc()}},{type:'link',label:'Print',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_print);},icon:'ic-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_email);},icon:'ic-mail',onclick:function(){me.form.email_doc()}},{type:'link',label:'Copy',display:function(){return in_list(profile.can_create,me.form.doctype)&&!me.form.meta.allow_copy},icon:'ic-clipboard_copy',onclick:function(){me.form.copy_doc()}},{type:'link',label:'Delete',display:function(){return me.form.meta.allow_trash&&cint(me.form.doc.docstatus)!=2&&(!me.form.doc.__islocal)&&me.form.perm[0][CANCEL]},icon:'ic-trash',onclick:function(){me.form.savetrash()}}]},{title:'Assign To',render:function(wrapper){me.form.assign_to=new wn.widgets.form.sidebar.AssignTo(wrapper,me,me.form.doctype,me.form.docname);},display:function(){if(!me.form.doc.__local)return true;else return false;}},{title:'Attachments',render:function(wrapper){me.form.attachments=new wn.widgets.form.sidebar.Attachments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return me.form.meta.allow_attach}},{title:'Comments',render:function(wrapper){new wn.widgets.form.sidebar.Comments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return!me.form.doc.__islocal}},{title:'Tags',render:function(wrapper){me.form.taglist=new TagList(wrapper,me.form.doc._user_tags?me.form.doc._user_tags.split(','):[],me.form.doctype,me.form.docname,0,function(){});},display:function(){return!me.form.doc.__islocal}}]} this.refresh=function(){var parent=this.form.page_layout.sidebar_area;if(!this.sidebar){$y(parent,{paddingTop:'37px'}) this.sidebar=new wn.widgets.PageSidebar(parent,this.opts);}else{this.sidebar.refresh();}}}} /* -* lib/js/legacy/wn/widgets/form/comments.js -*/ - + * lib/js/legacy/wn/widgets/form/comments.js + */ wn.widgets.form.sidebar.Comments=function(parent,sidebar,doctype,docname){var me=this;this.sidebar=sidebar;this.doctype=doctype;this.docname=docname;this.refresh=function(){$c('webnotes.widgets.form.comments.get_comments',{dt:me.doctype,dn:me.docname,limit:5},function(r,rt){wn.widgets.form.comments.sync(me.doctype,me.docname,r);me.make_body();});} this.make_body=function(){if(this.wrapper)this.wrapper.innerHTML='';else this.wrapper=$a(parent,'div','sidebar-comment-wrapper');this.input=$a_input(this.wrapper,'text');this.btn=$btn(this.wrapper,'Post',function(){me.add_comment()},{marginLeft:'8px'});this.render_comments()} this.render_comments=function(){var f=wn.widgets.form.comments;var cl=f.comment_list[me.docname] @@ -535,9 +523,8 @@ this.render_one_comment=function(det){$a(this.wrapper,'div','social sidebar-comm this.add_comment=function(){if(!this.input.value)return;this.btn.set_working();wn.widgets.form.comments.add(this.input,me.doctype,me.docname,function(){me.btn.done_working();me.make_body();});} this.refresh();} /* -* lib/js/legacy/wn/widgets/form/attachments.js -*/ - + * lib/js/legacy/wn/widgets/form/attachments.js + */ wn.widgets.form.sidebar.Attachments=function(parent,sidebar,doctype,docname){var me=this;this.frm=sidebar.form;this.make=function(){if(this.wrapper)this.wrapper.innerHTML='';else this.wrapper=$a(parent,'div','sidebar-comment-wrapper');this.attach_wrapper=$a(this.wrapper,'div');if(this.frm.doc.__islocal){this.attach_wrapper.innerHTML='Attachments can be uploaded after saving' return;} var n=this.frm.doc.file_list?this.frm.doc.file_list.split('\n').length:0;if(n%(owner)s \ diff --git a/js/legacy/report.compressed.js b/js/legacy/report.compressed.js index c2b32b65c6..9bc95f039a 100644 --- a/js/legacy/report.compressed.js +++ b/js/legacy/report.compressed.js @@ -1,8 +1,7 @@ /* -* lib/js/legacy/widgets/report_builder/report_builder.js -*/ - + * lib/js/legacy/widgets/report_builder/report_builder.js + */ _r.ReportContainer=function(){if(user=='Guest'){msgprint("Not Allowed");return;} wn.require('lib/js/legacy/widgets/form/fields.js');this.wrapper=page_body.add_page("Report Builder",function(){});this.wrapper.className='layout_wrapper';var head_div=$a(this.wrapper,'div');this.rb_area=$a(this.wrapper,'div');$dh(this.wrapper);var me=this;this.rb_dict={};this.page_head=new PageHeader(head_div);$y(this.page_head.wrapper,{marginBottom:'0px'});var run_fn=function(){if(me.cur_rb){me.cur_rb.dt.start_rec=1;me.cur_rb.dt.run();}} var runbtn=this.page_head.add_button('Run',run_fn,1,'ui-icon-circle-triangle-e',1);if(has_common(['Administrator','System Manager'],user_roles)){var savebtn=this.page_head.add_button('Save',function(){if(me.cur_rb)me.cur_rb.save_criteria();},0,'ui-icon-disk');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;} @@ -149,9 +148,8 @@ this.all_fields[i].selected=1;}} _r.ReportColumnPicker.prototype.add_field=function(f){if(!f.label)return;var by_default=(f.in_filter)?1:0;this.all_fields.push({selected:by_default,df:f,sel_idx:(by_default?this.sel_idx:0),selected_by_default:by_default});this.sel_idx+=by_default;} _r.ReportColumnPicker.prototype.set=function(dt,label,selected){for(var i=0;i=100)comma=',' else comma='' return bestguess+comma+' '+in_words(remainder);}else{return bestguess;}} /* -* lib/js/legacy/utils/browser_detect.js -*/ - + * lib/js/legacy/utils/browser_detect.js + */ var appVer=navigator.appVersion.toLowerCase();var is_minor=parseFloat(appVer);var is_major=parseInt(is_minor);var iePos=appVer.indexOf('msie');if(iePos!=-1){is_minor=parseFloat(appVer.substring(iePos+5,appVer.indexOf(';',iePos))) is_major=parseInt(is_minor);} var isIE=(iePos!=-1);var isIE6=(isIE&&is_major<=6);var isIE7=(isIE&&is_major>=7);if(/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){var isFF=1;var ffversion=new Number(RegExp.$1) if(ffversion>=3)var isFF3=1;else if(ffversion>=2)var isFF2=1;else if(ffversion>=1)var isFF1=1;} var isSafari=navigator.userAgent.indexOf('Safari')!=-1?1:0;var isChrome=navigator.userAgent.indexOf('Chrome')!=-1?1:0; /* -* lib/js/legacy/utils/datetime.js -*/ - + * lib/js/legacy/utils/datetime.js + */ function same_day(d1,d2){if(d1.getFullYear()==d2.getFullYear()&&d1.getMonth()==d2.getMonth()&&d1.getDate()==d2.getDate())return true;else return false;} var month_list=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];var month_last={1:31,2:28,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31} var month_list_full=['January','February','March','April','May','June','July','August','September','October','November','December'];var week_list=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];var week_list_full=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];function int_to_str(i,len){i=''+i;if(i.length","/":"?","\\":"|"}};function keyHandler(handleObj){if(typeof handleObj.data!=="string"){return;} var origHandler=handleObj.handler,keys=handleObj.data.toLowerCase().split(" ");handleObj.handler=function(event){if(this!==event.target&&(/textarea|select/i.test(event.target.nodeName)||event.target.type==="text")){return;} var special=event.type!=="keypress"&&jQuery.hotkeys.specialKeys[event.which],character=String.fromCharCode(event.which).toLowerCase(),key,modif="",possible={};if(event.altKey&&special!=="alt"){modif+="alt+";} @@ -300,9 +292,8 @@ if(special){possible[modif+special]=true;}else{possible[modif+character]=true;po for(var i=0,l=keys.length;i');});} html.push('');html.push('');html.push('
'+elementHtml+'
');html.push('');html.push('');return html.join('');};})(window); /* -* lib/js/wn/ui/dialog.js -*/ - + * lib/js/wn/ui/dialog.js + */ wn.widgets.FieldGroup=function(){this.first_button=false;this.make_fields=function(body,fl){wn.require('lib/js/legacy/widgets/form/fields.js');$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;i'+t+'');} function setup_err_console(){err_console=new Dialog(640,480,'Error Console') err_console.make_body([['HTML','Error List'],['Button','Clear'],['HTML','Error Report']]);var span=$a(err_console.widgets['Error Report'],'span','link_type');span.innerHTML='Send Error Report';span.onclick=function(){msg=prompt('How / where did you get the error [optional]') @@ -713,9 +689,8 @@ err_console.onshow=function(){err_console.rows['Error List'].innerHTML='
')+'';}} startup_list.push(setup_err_console); /* -* lib/js/legacy/webpage/loaders.js -*/ - + * lib/js/legacy/webpage/loaders.js + */ function loadreport(dt,rep_name,onload,menuitem,reset_report){wn.require('lib/js/legacy/report.compressed.js');dt=get_label_doctype(dt);var show_report_builder=function(){if(!_r.rb_con){_r.rb_con=new _r.ReportContainer();} _r.rb_con.set_dt(dt,function(rb){if(rep_name){var t=rb.current_loaded;rb.load_criteria(rep_name);if(onload) onload(rb);if((rb.dt)&&(!rb.dt.has_data()||rb.current_loaded!=t)) @@ -753,18 +728,16 @@ script.onreadystatechange=function(){if(this.readyState=='complete'||this.readyS var doc_browser_page;function loaddocbrowser(dt,label,fields){wn.require('lib/js/legacy/widgets/form/fields.js');wn.require('lib/js/legacy/webpage/docbrowser.js');dt=get_label_doctype(dt);if(!doc_browser_page) doc_browser_page=new ItemBrowserPage();doc_browser_page.show(dt,label,fields);nav_obj.open_notify('List',dt,'');} /* -* lib/js/legacy/webpage/uploader.js -*/ - + * lib/js/legacy/webpage/uploader.js + */ var uploaders={};var upload_frame_count=0;Uploader=function(parent,args,callback){var id='frame'+upload_frame_count;upload_frame_count++;this.callback=callback;var div=$a(parent,'div');div.innerHTML='';var div=$a(parent,'div');div.innerHTML='
';var ul_form=div.childNodes[0];var f_list=[];var inp_fdata=$a_input($a(ul_form,'span'),'file',{name:'filedata'},{marginLeft:'7px'});if(!('cmd'in args)){var inp=$a_input($a(ul_form,'span'),'hidden',{name:'cmd'});inp.value='uploadfile';} var inp=$a_input($a(ul_form,'span'),'hidden',{name:'uploader_id'});inp.value=id;var inp=$a_input($a(ul_form,'span'),'submit',null,{marginLeft:'7px'});inp.value='Upload';$y(inp,{width:'80px'});for(var key in args){var inp=$a_input($a(ul_form,'span'),'hidden',{name:key});inp.value=args[key];} uploaders[id]=this;} function upload_callback(id,fid){uploaders[id].callback(fid);} /* -* lib/js/legacy/webpage/page.js -*/ - + * lib/js/legacy/webpage/page.js + */ var pages=[];var stylesheets=[];function Page(page_name,content){var me=this;this.name=page_name;this.trigger=function(event){try{if(pscript[event+'_'+this.name]) pscript[event+'_'+this.name](this.wrapper);}catch(e){console.log(e);}} this.onshow=function(){set_title(me.doc.title?me.doc.title:me.name);if(!me.onload_complete){me.trigger('onload');me.onload_complete=true;} @@ -781,15 +754,13 @@ page_body.change_to(page_name);return p;} function refresh_page(page_name){var fn=function(r,rt){render_page(page_name)} $c('webnotes.widgets.page.getpage',{'name':page_name,stylesheets:JSON.stringify(stylesheets)},fn);} /* -* lib/js/legacy/wn/page_layout.js -*/ - + * lib/js/legacy/wn/page_layout.js + */ wn.PageLayout=function(args){$.extend(this,args) this.wrapper=$a(this.parent,'div');this.wtab=make_table(this.wrapper,1,2,'100%',[this.main_width,this.sidebar_width]);this.main=$a($td(this.wtab,0,0),'div','layout_wrapper');this.sidebar_area=$a($td(this.wtab,0,1),'div');this.head=$a(this.main,'div');this.toolbar_area=$a(this.main,'div');this.body=$a(this.main,'div');this.footer=$a(this.main,'div');if(this.heading){this.page_head=new PageHeader(this.head,this.heading);}} /* -* lib/js/legacy/wn/widgets/page_sidebar.js -*/ - + * lib/js/legacy/wn/widgets/page_sidebar.js + */ wn.widgets.PageSidebar=function(parent,opts){this.opts=opts this.sections={} this.wrapper=$a(parent,'div','psidebar-wrapper') @@ -814,17 +785,15 @@ this.ln=$a(this.wrapper,'span','link_type psidebar-section-link',opts.style,opts wn.widgets.PageSidebarButton=function(section,opts,wrapper){this.wrapper=wrapper;this.section=section;this.opts=opts;var me=this;this.btn=$btn(this.wrapper,opts.label,opts.onclick,opts.style,opts.color);} wn.widgets.PageSidebarHTML=function(section,opts,wrapper){wrapper.innerHTML=opts.content} /* -* lib/js/legacy/wn/widgets/footer.js -*/ - + * lib/js/legacy/wn/widgets/footer.js + */ wn.widgets.Footer=function(args){$.extend(this,args);this.make=function(){this.wrapper=$a(this.parent,'div','std-footer');this.table=make_table(this.wrapper,1,this.columns,[],{width:100/this.columns+'%'});this.render_items();} this.render_items=function(){for(var i=0;iMandatory fields required in '+ (doc.parenttype?(fields[doc.parenttype][doc.parentfield].label+' (Table)'):get_doctype_label(doc.doctype))+':\n'+errfld.join('\n'));return all_clear;} /* -* lib/js/legacy/webpage/body.js -*/ - + * lib/js/legacy/webpage/body.js + */ function Body(){this.left_sidebar=null;this.right_sidebar=null;this.status_area=null;var me=this;page_body=this;this.no_of_columns=function(){var n=2;if(cint(me&&me.cp&&me.cp.right_sidebar_width)) n=n+1;return n;} this.ready=function(){$dh('startup_div');$ds('body_div');} @@ -939,9 +906,8 @@ this.status_area.innerHTML=txt;} this.set_session_changed=function(){if(this.session_message_set)return;var div=$a($i('body_div').parentNode,'div','',{textAlign:'center',fontSize:'14px',margin:'150px auto'});$dh('body_div');div.innerHTML='This session has been changed. Please refresh to continue';this.session_message_set=1;} this.setup();} /* -* lib/js/legacy/app.js -*/ - + * lib/js/legacy/app.js + */ var popup_cont;var session={};var start_sid=null;if(!wn)var wn={};function startup(){start_sid=get_cookie('sid');popup_cont=$a(document.getElementsByTagName('body')[0],'div');var setup_globals=function(r){wn.boot=r;profile=r.profile;user=r.profile.name;user_fullname=profile.first_name+(r.profile.last_name?(' '+r.profile.last_name):'');user_defaults=profile.defaults;user_roles=profile.roles;user_email=profile.email;profile.start_items=r.start_items;home_page=r.home_page;_p.letter_heads=r.letter_heads;sys_defaults=r.sysdefaults;session.rt=profile.can_read;if(r.ipinfo)session.ipinfo=r.ipinfo;session.dt_labels=r.dt_labels;session.rev_dt_labels={} _tags.color_map=r.tag_color_map;if(r.dt_labels){for(key in r.dt_labels)session.rev_dt_labels[r.dt_labels[key]]=key;} wn.control_panel=r.control_panel;} @@ -953,7 +919,10 @@ var callback=function(r,rt){if(r.exc)console.log(r.exc);setup_globals(r);setup_h if(get_url_arg('embed')){newdoc(get_url_arg('embed'));return;} var t=to_open();if(t){historyChange(t);}else if(home_page){loadpage(home_page);} page_body.ready();} -if(_startup_data&&keys(_startup_data).length&&_startup_data.docs){LocalDB.sync(_startup_data.docs);callback(_startup_data,'');if(_startup_data.server_messages)msgprint(_startup_data.server_messages);}else{if($i('startup_div')) +if(wn.boot){LocalDB.sync(wn.boot.docs);callback(wn.boot,'');if(wn.boot.error_messages) +console.log(wn.boot.error_messages) +if(wn.boot.server_messages) +msgprint(wn.boot.server_messages);}else{if($i('startup_div')) $c('startup',{},callback,null,1);}} function to_open(){if(get_url_arg('page')) return get_url_arg('page');var h=location.hash;if(h){return h.substr(1);}} diff --git a/js/wn/provide.js b/js/wn/provide.js index 99f03c020d..424d8ba251 100644 --- a/js/wn/provide.js +++ b/js/wn/provide.js @@ -1,5 +1,5 @@ // provide a namespace -wn = {} +if(!window.wn)wn = {} wn.provide = function(namespace) { var nsl = namespace.split('.'); var l = nsl.length; diff --git a/js/wn/ui/toolbar.min.js b/js/wn/ui/toolbar.min.js index b8d360432b..928800b2ff 100644 --- a/js/wn/ui/toolbar.min.js +++ b/js/wn/ui/toolbar.min.js @@ -1,8 +1,7 @@ /* -* lib/js/bootstrap/bootstrap-dropdown.js -*/ -/* ============================================================ + * lib/js/bootstrap/bootstrap-dropdown.js + *//* ============================================================ * bootstrap-dropdown.js v1.4.0 * http://twitter.github.com/bootstrap/javascript.html#dropdown * ============================================================ @@ -59,31 +58,26 @@ }( window.jQuery || window.ender ); /* -* lib/js/wn/ui/toolbar/selector_dialog.js -*/ - + * lib/js/wn/ui/toolbar/selector_dialog.js + */ wn.ui.toolbar.SelectorDialog=Class.extend({init:function(opts){this.opts=opts;try{this.make_dialog();}catch(e){console.log(e);} this.bind_events();},make_dialog:function(){this.dialog=new wn.widgets.Dialog({title:this.opts.title,width:300,fields:[{fieldtype:'Select',fieldname:'doctype',options:'Select...',label:'Select Type'},{fieldtype:'Button',label:'Go',fieldname:'go'}]});},bind_events:function(){var me=this;$(this.dialog.fields_dict.go.input).click(function(){me.dialog.hide();me.opts.execute(me.dialog.fields_dict.doctype.get_value());});$(this.dialog.fields_dict.doctype.input).change(function(){me.dialog.fields_dict.go.input.click();}).keypress(function(ev){if(ev.which==13){me.dialog.fields_dict.go.input.click();}});},show:function(){this.dialog.show();this.dialog.fields_dict.doctype.input.focus();return false;},set_values:function(lst){for(var i=0;i\ Recent\ \ @@ -95,9 +89,8 @@ catch(e){return;} var m=rlist.length;if(m>15)m=15;for(var i=0;i\
\ diff --git a/js/wn/versions.js b/js/wn/versions.js index 28e9eb0968..1857bebeca 100644 --- a/js/wn/versions.js +++ b/js/wn/versions.js @@ -7,6 +7,8 @@ wn.versions = { if(window._version_number==-1 || parseInt(localStorage._version_number) != parseInt(window._version_number)) { localStorage.clear(); + console.log("Cache cleared - version: " + _version_number + + ' to ' + localStorage._version_number) } localStorage.setItem('_version_number', window._version_number); } diff --git a/py/build/bundle.py b/py/build/bundle.py index 53bd74733d..2958701193 100644 --- a/py/build/bundle.py +++ b/py/build/bundle.py @@ -34,7 +34,7 @@ class Bundle: data = "\nwn.assets.handler.css('%s');\n" %\ data.replace("'", "\\'").replace('\n', '\\\n') - outtxt += ('\n/*\n*\t%s\n*/\n' % f) + outtxt += ('\n/*\n *\t%s\n */' % f) # append if suffix=='concat' or out_type != 'js': diff --git a/py/build/project.py b/py/build/project.py index 1591cfd7ca..d96130f76d 100644 --- a/py/build/project.py +++ b/py/build/project.py @@ -1,80 +1,43 @@ verbose = False -import os +import os -class Project: - """ - Build a project - Make files:: - - index.html - assets/template.html - assets/js/core.min.js - assets/timestamps.json - """ - def __init__(self): - """ - load libraries - """ - from py.build.bundle import Bundle - self.bundle = Bundle() - - def getversion(self): - """get from version.num file and increment it""" - - if os.path.exists('version.num'): - with open('version.num', 'r') as vfile: - self.version = int(vfile.read()) + 1 - else: - self.version = 1 - - with open('version.num', 'w') as vfile: - vfile.write(str(self.version)) - - return self.version - - def boot(self): - """ - returns bootstrap js - """ - import json - - corejs = open('lib/js/core.min.js', 'r') - boot = ('window._version_number="%s";' % str(self.getversion())) + \ - '\n' + corejs.read() - - corejs.close() - - return boot - - def render_templates(self): - """ - Generate static files from templates - """ - # render templates - boot = self.boot() - for wt in os.walk('templates'): - for fname in wt[2]: - if fname.split('.')[-1]=='html' and not fname.startswith('template'): - fpath = os.path.relpath(os.path.join(wt[0], fname), 'templates') - - with open(os.path.join(wt[0], fname), 'r') as tempfile: - temp = tempfile.read() - - temp = temp % boot - - with open(fpath, 'w') as outfile: - outfile.write(temp) - - print "Rendered %s | %.2fkb" % (fpath, os.path.getsize(fpath) / 1024.0) - - - def build(self): - """ - build js files, index.html - """ - for wt in os.walk('lib'): - for fname in wt[2]: - if fname=='build.json': - self.bundle.make(os.path.join(wt[0], fname)) +def build(): + """concat / minify js files""" + from py.build.bundle import Bundle + bundle = Bundle() + for wt in os.walk('lib'): + for fname in wt[2]: + if fname=='build.json': + bundle.make(os.path.join(wt[0], fname)) - self.render_templates() \ No newline at end of file + increment_version() + +def get_version(): + """get from version.num file and increment it""" + if os.path.exists('version.num'): + with open('version.num', 'r') as vfile: + version = int(vfile.read()) + 1 + else: + version = 1 + + return version + +def increment_version(): + """incremenet version by 1""" + version = get_version() + with open('version.num', 'w') as vfile: + vfile.write(str(version)) + + return version + +def get_corejs(): + """return corejs with version number""" + import json + + corejs = open('lib/js/core.min.js', 'r') + boot = ('window._version_number="%s";' % str(get_version())) + \ + '\n' + corejs.read() + + corejs.close() + + return boot \ No newline at end of file diff --git a/py/core/page/login_page/login_page.js b/py/core/page/login_page/login_page.js index ea4761318b..dc2b75706e 100644 --- a/py/core/page/login_page/login_page.js +++ b/py/core/page/login_page/login_page.js @@ -6,7 +6,7 @@ pscript['onload_Login Page'] = function(){ pscript.login_btn = $btn('login_btn', 'Login', pscript.doLogin); $(pscript.login_btn).addClass('primary'); - $('#login_wrapper').keyup(function(ev){ + $('#password').keypress(function(ev){ if(ev.which==13 && $('#password').value) pscript.doLogin(); }) @@ -20,7 +20,7 @@ pscript['onshow_Login Page'] = function() { pscript.onLoginReply = function(r, rtext) { pscript.login_btn.done_working(); if(r.message=="Logged In"){ - window.location.href='index.html' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : ''); + window.location.href='index.cgi' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : ''); } else { $i('login_message').innerHTML = ''+(r.message)+''; //if(r.exc)alert(r.exc); diff --git a/py/webnotes/__init__.py b/py/webnotes/__init__.py index 00eb787bb2..a1fc3cfb25 100644 --- a/py/webnotes/__init__.py +++ b/py/webnotes/__init__.py @@ -1,18 +1,8 @@ -# -# import modules path -# -import os, sys +""" +globals attached to webnotes module ++ some utility functions that should probably be moved +""" -try: - import webnotes.defs - m = getattr(webnotes.defs,'modules_path',None) - m and sys.path.append(m) -except Exception,e: - raise e - -# -# map for identifying which field values come from files -# code_fields_dict = { 'Page':[('script', 'js'), ('content', 'html'), ('style', 'css'), ('static_content', 'html'), ('server_code', 'py')], 'DocType':[('server_code_core', 'py'), ('client_script_core', 'js')], @@ -23,81 +13,43 @@ code_fields_dict = { 'Control Panel':[('startup_code', 'js'), ('startup_css', 'css')] } -# -# globals -# -#: "v170" version = 'v170' form_dict = {} auth_obj = None - -#: The database connection :class:`webnotes.db.Database` setup by :mod:`auth` conn = None - -#: The cgi.FieldStorage() object (Dictionary representing the formdata from the URL) form = None - session = None -""" - Global session dictionary. - - * session['user'] - Current user - * session['data'] - Returns a dictionary of the session cache -""" - user = None is_testing = None -""" Flag to identify if system is in :term:`Testing Mode` """ - incoming_cookies = {} -add_cookies = {} -""" Dictionary of additional cookies appended by custom code """ - +add_cookies = {} # append these to outgoing request cookies = {} auto_masters = {} tenant_id = None +response = {'message':'', 'exc':''} +debug_log = [] +message_log = [] -from webnotes.utils import cstr -# -# Custom Class (no traceback) -# class ValidationError(Exception): pass -# -# HTTP standard response -# -response = {'message':'', 'exc':''} -""" - The JSON response object. Default is:: - - {'message':'', 'exc':''} -""" - -# -# the logs -# -debug_log = [] -""" List of exceptions to be shown in the :term:`Error Console` """ - -message_log = [] -""" List of messages to be shown to the user in a popup box at the end of the request """ - def getTraceback(): - import webnotes.utils - return webnotes.utils.getTraceback() + import utils + return utils.getTraceback() def errprint(msg): """ Append to the :data:`debug log` """ + from utils import cstr debug_log.append(cstr(msg or '')) def msgprint(msg, small=0, raise_exception=0, as_table=False): """ Append to the :data:`message_log` """ + from utils import cstr if as_table and type(msg) in (list, tuple): msg = '' + ''.join([''+''.join(['' % c for c in r])+'' for r in msg]) + '
%s
' @@ -118,9 +70,7 @@ def get_index_path(): return os.sep.join(os.path.dirname(os.path.abspath(__file__)).split(os.sep)[:-2]) def get_files_path(): - global conn - import defs, os - + import defs if not conn: raise Exception, 'You must login first' @@ -143,7 +93,6 @@ def create_folder(path): else: raise e - def connect(db_name=None): """ Connect to this db (or db), if called from command prompt @@ -162,46 +111,16 @@ def connect(db_name=None): global user user = webnotes.profile.Profile('Administrator') - -# Environment Variables -#----------------------------------------------------------- def get_env_vars(env_var): + import os return os.environ.get(env_var,'None') remote_ip = get_env_vars('REMOTE_ADDR') #Required for login from python shell - -# Logging -# ----------------------------------------------------------- - logger = None - - -def setup_logging(): - import logging - import logging.handlers - # Also please set umask for apache to 002. - global logger - - try: - logger = logging.getLogger('WNLogger') - logger.setLevel(eval(defs.log_level)) - - log_handler = logging.handlers.RotatingFileHandler(defs.log_file_name, maxBytes = defs.log_file_size, backupCount = defs.log_file_backup_count) - formatter = logging.Formatter('%(name)s - %(asctime)s - %(levelname)s\n%(message)s\n-------------------') - - log_handler.setFormatter(formatter) - logger.addHandler(log_handler) - - except IOError,e: - if e.args == 13: - open(defs.log_file_name).close() - - -if getattr(defs, 'log_file_name', None): - setup_logging() def get_db_password(db_name): - from webnotes import defs + import defs + if hasattr(defs, 'get_db_password'): return defs.get_db_password(db_name) diff --git a/py/webnotes/auth.py b/py/webnotes/auth.py index 01abd08491..d324f0bc98 100644 --- a/py/webnotes/auth.py +++ b/py/webnotes/auth.py @@ -39,7 +39,6 @@ class HTTPRequest: # start session webnotes.session_obj = Session() webnotes.session = webnotes.session_obj.data - webnotes.tenant_id = webnotes.session.get('tenant_id', 0) # write out cookies if sid is supplied (this is a pre-logged in redirect) if webnotes.form_dict.get('sid'): @@ -316,15 +315,8 @@ class Session: def load(self): import webnotes - r=None - try: - r = webnotes.conn.sql("""select user, sessiondata, status from - tabSessions where sid='%s'""" % self.sid) - except Exception, e: - if e.args[0]==1054: - self.add_status_column() - else: - raise e + r = webnotes.conn.sql("""select user, sessiondata, status from + tabSessions where sid='%s'""" % self.sid) if r: r=r[0] @@ -419,13 +411,6 @@ class Session: # clear out old sessions webnotes.conn.sql("delete from tabSessions where TIMEDIFF(NOW(), lastupdate) > '72:00:00'") - # ----------------------------- - def add_status_column(self): - webnotes.conn.commit() - webnotes.conn.sql("alter table tabSessions add column `status` varchar(20)") - webnotes.conn.begin() - - # Get IP Info from ipinfodb.com # ----------------------------- def get_ipinfo(self): diff --git a/py/webnotes/boot.py b/py/webnotes/boot.py index aeee5e3518..db982ab7da 100644 --- a/py/webnotes/boot.py +++ b/py/webnotes/boot.py @@ -8,9 +8,8 @@ def get_bootinfo(): import webnotes bootinfo = {} doclist = [] - - webnotes.conn.begin() + webnotes.conn.begin() # profile get_profile(bootinfo) @@ -59,10 +58,10 @@ def get_home_page(bootinfo, doclist): home_page = webnotes.user.get_home_page() if home_page: import webnotes.widgets.page + page_doclist = webnotes.widgets.page.get(home_page) doclist += webnotes.widgets.page.get(home_page) bootinfo['home_page'] = home_page or '' - - + bootinfo['home_page_html'] = page_doclist[0].content def get_dt_labels(): import webnotes diff --git a/py/webnotes/handler.py b/py/webnotes/handler.py index b0637f55a6..fa2bf0baaf 100755 --- a/py/webnotes/handler.py +++ b/py/webnotes/handler.py @@ -39,13 +39,6 @@ def runserverobj(arg=None): def logout(): webnotes.login_manager.logout() -# versions -# -------- - -def get_diff(): - v = webnotes.form_dict.get('version_number') - from build.version import VersionControl - webnotes.response['message'] = VersionControl().repo.diff(v) # DocType Mapper # ------------------------------------------------------------------------------------ @@ -166,27 +159,6 @@ def get_file(): webnotes.response['filecontent'] = res[1] else: webnotes.msgprint('[get_file] Unknown file name') - -# Get Graph -# ------------------------------------------------------------------------------------ -def get_graph(): - form = webnotes.form - - import StringIO - f = StringIO.StringIO() - - # call the object - obj = server.get_obj(form_dict.get('dt')) - plt = server.run_server_obj(obj, form_dict.get('method'), form_dict.get('arg')) - plt.savefig(f) - - # stream out - webnotes.response['type'] = 'download' - webnotes.response['filename'] = webnotes.user.get_random_password() + '.png' - webnotes.response['filecontent'] = f.getvalue() - -# Reset Password -# ------------------------------------------------------------------------------------ def reset_password(): form_dict = webnotes.form_dict @@ -199,27 +171,59 @@ def reset_password(): else: webnotes.msgprint("No such user (%s)", user) -# Resume session -# ------------------------------------------------------------------------------------ -def resume_session(): - webnotes.response['message'] = webnotes.session_obj.resume() +def handle(): + """handle request""" + cmd = webnotes.form_dict['cmd'] -# ------------- -# Create Backup -# ------------- + if cmd!='login': + # login executed in webnotes.auth + try: + execute_cmd(cmd) + except webnotes.ValidationError: + webnotes.conn.rollback() + except: + webnotes.errprint(webnotes.utils.getTraceback()) + webnotes.conn and webnotes.conn.rollback() + + if webnotes.conn: + webnotes.conn.close() + + print_response() -def backupdb(form_dict, session): - db_name = server.decrypt(form_dict.get('db_name')) +def execute_cmd(cmd): + """execute a request as python module""" + validate_cmd(cmd) + method = get_method(cmd) - server.backup_db(db_name) + if not webnotes.conn.in_transaction: + webnotes.conn.begin() - webnotes.response['type'] = 'download' - webnotes.response['filename'] = db_name+'.tar.gz' - webnotes.response['filecontent'] = open('../backups/' + db_name+'.tar.gz','rb').read() + if 'arg' in webnotes.form_dict: + # direct method call + ret = method(webnotes.form_dict.get('arg')) + else: + ret = method() -# --------------------------------------------------------------------- + # returns with a message + if ret: + webnotes.response['message'] = ret + # update session + webnotes.session_obj.update() + + if webnotes.conn.in_transaction: + webnotes.conn.commit() + +def get_method(cmd): + """get method object from cmd""" + if '.' in cmd: + module = __import__('.'.join(cmd.split('.')[:-1]), fromlist=['']) + method = getattr(module, cmd.split('.')[-1]) + else: + method = globals()[cmd] + return method + def validate_cmd(cmd): # check if there is no direct possibility of malicious script injection if cmd.startswith('webnotes.model.code'): @@ -230,145 +234,27 @@ def validate_cmd(cmd): if cmd.startswith('webnotes.conn'): raise Exception, 'Cannot call database connection method directly from the handler' - -# Execution Starts Here -# --------------------------------------------------------------------- - -import webnotes.auth -import webnotes.db - -# reset password -# --------------------------------------------------------------------- - -if form_dict.has_key('cmd') and (form_dict.get('cmd')=='reset_password'): - webnotes.conn = webnotes.db.Database(use_default = 1) - sql = webnotes.conn.sql - sql("START TRANSACTION") - try: - reset_password() - sql("COMMIT") - except Exception, e: - webnotes.errprint(str(e)) - sql("ROLLBACK") - -# pre-login access - for registration etc. -# --------------------------------------------------------------------- - -elif form_dict.has_key('cmd') and (form_dict.get('cmd')=='prelogin'): - webnotes.conn = webnotes.db.Database(use_default = 1) - sql = webnotes.conn.sql - webnotes.session = {'user':'Administrator'} - - import webnotes.model.code - - sql("START TRANSACTION") - try: - webnotes.response['message'] = webnotes.model.code.get_obj('Profile Control').prelogin(form_dict) or '' - sql("COMMIT") - except: - webnotes.errprint(webnotes.utils.getTraceback()) - sql("ROLLBACK") - -# main stuff -# --------------------------------------------------------------------- - -else: - - try: - webnotes.request = webnotes.auth.HTTPRequest() - - if form_dict.get('cmd') != 'login' and webnotes.conn: - sql = webnotes.conn.sql - # NOTE: - # guest should only be allowed: - # getdoc (if Guest access) - # runserverobj (if Guest access) +def print_response(): + import string + import os + + if webnotes.response.get('type')=='csv': + print_csv() + elif webnotes.response.get('type')=='iframe': + print_iframe() + elif webnotes.response.get('type')=='download': + print_raw() + else: + print_json() - # get command cmd - cmd = form_dict.has_key('cmd') and form_dict.get('cmd') or '' - read_only = form_dict.has_key('_read_only') and form_dict.get('_read_only') or None - - validate_cmd(cmd) - - module = '' - if '.' in cmd: - module = '.'.join(cmd.split('.')[:-1]) - cmd = cmd.split('.')[-1] - - exec 'from %s import %s' % (module, cmd) in locals() - - - # execute - if locals().has_key(cmd): - if (not webnotes.conn.in_transaction) and (not read_only): - webnotes.conn.begin() - - if webnotes.form_dict.get('arg'): - # direct method call - ret = locals()[cmd](webnotes.form_dict.get('arg')) - else: - ret = locals()[cmd]() - - # returns with a message - if ret: - webnotes.response['message'] = ret - - # update session - webnotes.session_obj.update() - - if webnotes.conn.in_transaction: - webnotes.conn.commit() - else: - if cmd!='login': - webnotes.msgprint('No Method: %s' % cmd) - - except webnotes.ValidationError: - webnotes.conn.rollback() - except: - webnotes.errprint(webnotes.utils.getTraceback()) - webnotes.conn and webnotes.conn.rollback() - - -#### cleanup -#----------- - -if webnotes.conn: - webnotes.conn.close() - -#### go - -import string -import os - -acceptsGzip, out_buf, str_out = 0, None, None -try: - if string.find(os.environ["HTTP_ACCEPT_ENCODING"], "gzip") != -1: - acceptsGzip = 1 # problem in win ? -except: - pass - -def compressBuf(buf): - import gzip, cStringIO - zbuf = cStringIO.StringIO() - zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) - zfile.write(buf) - zfile.close() - return zbuf.getvalue() - -# CSV -# ------------------------------------------------------------------- - -if webnotes.response.get('type')=='csv': +def print_csv(): print "Content-Type: text/csv" print "Content-Disposition: attachment; filename="+webnotes.response['doctype'].replace(' ', '_')+".csv" print print webnotes.response['result'] -# IFRAME -# ------------------------------------------------------------------- - -elif webnotes.response.get('type')=='iframe': +def print_iframe(): print "Content-Type: text/html" print if webnotes.response.get('result'): @@ -376,69 +262,63 @@ elif webnotes.response.get('type')=='iframe': if webnotes.debug_log: print '''''' % ('-------'.join(webnotes.debug_log).replace('"', '').replace('\n','')) -# file -# ------------------------------------------------------------------- - -elif webnotes.response.get('type')=='download': +def print_raw(): import mimetypes print "Content-Type: %s" % (mimetypes.guess_type(webnotes.response['filename'])[0] or 'application/unknown') print "Content-Disposition: filename="+webnotes.response['filename'].replace(' ', '_') print print webnotes.response['filecontent'] -# JSON -# ------------------------------------------------------------------- - -else: - if webnotes.debug_log: - save_log = 1 - if webnotes.debug_log[0].startswith('[Validation Error]'): - save_log = 0 - - t = '\n----------------\n'.join(webnotes.debug_log) - if errdoctype: - t = t + '\nDocType: ' + errdoctype - if errdoc: - t = t + '\nName: ' + errdoc - if errmethod: - t = t + '\nMethod: ' + errmethod - webnotes.response['exc'] = '
'+t.replace('\n','
')+'
' - - if save_log: # don't save validation errors - try: save_log(t, 'Server') - except: pass - - if webnotes.message_log: - webnotes.response['server_messages'] = '\n----------------\n'.join(webnotes.message_log) - +def print_json(): + make_logs() cleanup_docs() - - # Convert to JSON - # --------------- - try: - import json - except: # python 2.4 - import simplejson as json - + + import json str_out = json.dumps(webnotes.response) - if acceptsGzip and 1 and len(str_out)>512: + if accept_gzip() and len(str_out)>512: out_buf = compressBuf(str_out) print "Content-Encoding: gzip" print "Content-Length: %d" % (len(out_buf)) + str_out = out_buf print "Content-Type: text/html; charset: utf-8" - - # if there ar additional cookies defined during the request, add them here + print_cookies() + + # Headers end + print + print str_out + +def accept_gzip(): + """return true if client accepts gzip""" + try: + if string.find(os.environ["HTTP_ACCEPT_ENCODING"], "gzip") != -1: + return True + except: + return False + +def make_logs(): + """make strings for msgprint and errprint""" + if webnotes.debug_log: + t = '\n----------------\n'.join(webnotes.debug_log) + webnotes.response['exc'] = t + + if webnotes.message_log: + t = '\n----------------\n'.join(webnotes.message_log) + webnotes.response['server_messages'] = t + +def print_cookies(): + """if there ar additional cookies defined during the request, add them""" if webnotes.cookies or webnotes.add_cookies: for c in webnotes.add_cookies.keys(): webnotes.cookies[c] = webnotes.add_cookies[c] - - print webnotes.cookies - print # Headers end - -if out_buf: - sys.stdout.write(out_buf) -elif str_out: - print str_out + print webnotes.cookies + +def compressBuf(buf): + import gzip, cStringIO + zbuf = cStringIO.StringIO() + zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) + zfile.write(buf) + zfile.close() + return zbuf.getvalue() \ No newline at end of file diff --git a/py/webnotes/index.py b/py/webnotes/index.py new file mode 100644 index 0000000000..2e85b9a21c --- /dev/null +++ b/py/webnotes/index.py @@ -0,0 +1,109 @@ +""" +Generate index.cgi html + +Loads index.html from the template with: + +1. bootinfo +2. static html of home / if _escaped_fragment_ is given +3. top menus and bottom menus + +""" + +import webnotes + +body_html = """ +
+
+ Loading... +
+ +
+
+ +
+ +
+""" + +def get(): + """get index html""" + import webnotes + from jinja2 import Template + + with open('lib/conf/index.html', 'r') as f: + template = Template(f.read()) + + # google crawler + if '_escaped_fragment_' in webnotes.form: + page = webnotes.form_dict['_escaped_fragment_'] + if not page: + page = webnotes.user.get_home_page() + + return template.render(bootinfo = '', \ + corejs = '', body_html=html_snapshot(page), ajax_meta_tag = '') + + # home page + else: + import webnotes.session_cache + from build.project import get_corejs + import json + + bootinfo = webnotes.session_cache.get() + + # is this needed? + home_content = bootinfo['home_page_html'] + del bootinfo['home_page_html'] + + bootinfo = """var wn = {}; wn.boot = %s;""" % json.dumps(bootinfo) + + return template.render(bootinfo = bootinfo, \ + corejs = get_corejs(), body_html=body_html % '', \ + ajax_meta_tag = '') + +def html_snapshot(page): + """get html snapshot for search bot""" + from webnotes.widgets.page import get_page_html + from webnotes.model.doc import Document + + doc = Document('Top Bar Settings', 'Top Bar Settings') + doc.content = get_page_html(page) + doc.header_menu = doc.footer_menu = '' + doc.page_name = page + + for m in webnotes.conn.sql("""select parentfield, label, std_page, custom_page + from `tabTop Bar Item` where parent='Top Bar Settings' order by idx""", as_dict=1): + + if m['custom_page']: + m['std_page'] = m['custom_page'] + + if m['parentfield']=='top_bar_items': + doc.header_menu += '
  • %(label)s
  • ' % m + else: + doc.footer_menu += '
  • %(label)s
  • ' % m + + return """ +
    +

    %(brand_html)s

    +
      + %(header_menu)s +
    +
    + %(content)s + + """ % doc.fields + + \ No newline at end of file diff --git a/py/webnotes/install_lib/install.py b/py/webnotes/install_lib/install.py index 9f21dd128f..46694a9510 100755 --- a/py/webnotes/install_lib/install.py +++ b/py/webnotes/install_lib/install.py @@ -49,11 +49,25 @@ class Installer: webnotes.conn.sq.("""create table `__SessionCache` (user VARCHAR(120), country VARCHAR(120), cache LONGTEXT)""") + create_sessions_table() + # set the basic passwords webnotes.conn.begin() webnotes.conn.sql("update tabProfile set password = password('admin') where name='Administrator'") webnotes.conn.commit() + def create_sessions_table(self): + self.dbman.drop_table('tabSessions') + webnotes.conn.sql("""CREATE TABLE `tabSessions` ( + `user` varchar(40) DEFAULT NULL, + `sid` varchar(120) DEFAULT NULL, + `sessiondata` longtext, + `ipaddress` varchar(16) DEFAULT NULL, + `lastupdate` datetime DEFAULT NULL, + `status` varchar(20) DEFAULT NULL, + KEY `sid` (`sid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8""") + def import_core_module(self): """ Imports the "Core" module from .txt file and creates diff --git a/py/webnotes/profile.py b/py/webnotes/profile.py index 7427b5d6e1..b6dbe90d07 100644 --- a/py/webnotes/profile.py +++ b/py/webnotes/profile.py @@ -100,13 +100,14 @@ class Profile: """ Get the name of the user's home page from the `Control Panel` """ - roles = self.get_roles() - hpl = webnotes.conn.sql("select role, home_page from `tabDefault Home Page` where parent='Control Panel' order by idx asc") - for h in hpl: - if h[0] in roles: - return h[1] - - return webnotes.conn.get_value('Control Panel',None,'home_page') or 'Login Page' + hpl = webnotes.conn.sql("""select home_page from `tabDefault Home Page` + where parent='Control Panel' + and role in ('%s') order by idx asc limit 1""" % "', '".join(self.get_roles())) + + if hpl: + return hpl[0][0] + else: + return webnotes.conn.get_value('Control Panel',None,'home_page') or 'Login Page' def get_defaults(self): """ diff --git a/py/webnotes/session_cache.py b/py/webnotes/session_cache.py index 8381fae213..72d8cda21d 100644 --- a/py/webnotes/session_cache.py +++ b/py/webnotes/session_cache.py @@ -20,6 +20,8 @@ def clear_cache(user=''): webnotes.conn.sql("delete from __SessionCache") webnotes.conn.sql("update tabSessions set sessiondata=NULL") + # rebuild a cache for guest + if webnotes.session: webnotes.session['data'] = {} diff --git a/py/webnotes/widgets/page.py b/py/webnotes/widgets/page.py index de31fb9fd7..6523a994b1 100644 --- a/py/webnotes/widgets/page.py +++ b/py/webnotes/widgets/page.py @@ -116,4 +116,30 @@ def getpage(): # send webnotes.response['docs'] = doclist + +def get_page_path(page_name, module): + import os + import webnotes.defs + from webnotes.modules import scrub + return os.path.join(webnotes.defs.modules_path, 'erpnext', scrub(module), \ + 'page', scrub(page_name), scrub(page_name) + '.html') + +def get_page_html(page_name): + """get html of page""" + p = webnotes.conn.sql("""select module, content from tabPage where name=%s""", \ + page_name, as_dict=1) + + if not p: + return '' + else: + import os + p=p[0] + + path = get_page_path(page_name, p['module']) + if os.path.exists(path): + with open(path, 'r') as f: + return f.read() + else: + return p['content'] + diff --git a/wnf.py b/wnf.py index 28d22512c2..e7cd18f3dc 100755 --- a/wnf.py +++ b/wnf.py @@ -43,12 +43,12 @@ def run(): cmd = sys.argv[1] if cmd=='build': - from build.project import Project - Project().build() + import build.project + build.project.build() elif cmd=='clear': - from build.project import Project - Project().render_templates() + from build.project import increment_version + print "Version:" + str(increment_version()) # replace code elif cmd=='replace':