commit d9404210e4b835ded65db509126f306e8e6c3c84 Author: Pratik Vyas Date: Wed Jun 8 14:24:18 2011 +0530 Sourced WebNotes Framework from Google Code. diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000000..58bfec90b6 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,81 @@ +INSTALL.txt +=========== + +Web Notes Framework Installation guide + +Web Notes Framework (WNF) is a meta-data driven web app framework. After install, you build +and configure your application from the web browser. + +WNF requires the following applications + +1. Python +2. MySQL +3. MySQL-Python (connector) +4. simplejson (for Python 2.4 or lower) +5. email (for Python 2.4 or lower) +6. pytz (easy_install pytz) +7. Apache +8. PIL (optional - for image processing (thumbnails etc) + - yum install libjpeg-devel + - yum install python-imaging + ) + +------------------------------------------------------------------------ +1. Create a databse instance for your application + + Call the install script with the following options. For more options use -h + + python [folder]/cgi-bin/webnotes/install_lib/install.py MYSQL_ROOT_LOGIN MYSQL_ROOT_PASSWORD DBNAME + +------------------------------------------------------------------------ +2. Setup defs.py + + The framework picks up the database details from cgi-bin/webnotes/defs.py + + You need to edit this file and set your database name and other options + +------------------------------------------------------------------------ +3. Configuring Apache + +a. You must set Apache to execute index.cgi file, one way to do this is to add cgi handler + and add ExecCGI in the options directive. + +b. You can also add couple of lines below to block Apache from rendering .py files + + RewriteEngine on + RewriteRule \.py - [F] + +c. Add "index.cgi" to DirectoryIndex + + +------------------------------------------------------------------------ +4. Login to application + +Start Apache, go to your web-browser and point to the folder where you installed the framework + +The default logins are: + +login: Administrator +password: admin + +------------------------------------------------------------------------ + +Step by step instructions on CentOS/Fedora: + 0.Check out the source code. + 1. Modify the v170/cgi-bin/webnotes/defs file to your required settings and rename it to defs.py + 2. yum install mysql + 3. yum install httpd + 4. yum install MySQL-python + 5. yum install python-setuptools + 6. easy_install pytz + 7. easy_install email + 8. easy_install simplejson suds + 9. easy_install pygeoip (optional for geo ip) + 9. yum install libjpeg-devel (optional) + 10.yum install python-imaging (optional) + + 11. Edit /etc/httpd/conf/httpd.conf and add the options as mentioned above. + 12. from the trunk/v170/cgi-bin folder run python webnotes/install_lib/install.py install + + + diff --git a/blank.html b/blank.html new file mode 100755 index 0000000000..2488c5be1c --- /dev/null +++ b/blank.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + +

blank.html - Needed for Internet Explorer's hidden iframe

+

+ + + diff --git a/blank1.html b/blank1.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/backupall.py b/cgi-bin/backupall.py new file mode 100644 index 0000000000..eb4954b0c6 --- /dev/null +++ b/cgi-bin/backupall.py @@ -0,0 +1,24 @@ +import os + +# go to current directory +os.chdir(__file__[:-12]) + +import webnotes.utils.backups + +webnotes.utils.backups.backup_all() + +# send the daily backup to the pair server +import webnotes.defs +if hasattr(webnotes.defs,'ps_host'): + import ftplib, time + + ftp = ftplib.FTP(webnotes.defs.ps_host, webnotes.defs.ps_login, webnotes.defs.ps_pwd) + ftp.cwd('pair_backups') + fname = 'daily-' + time.strftime('%Y-%m-%d') + '.tar.gz' + f = open('/backups/daily/' + fname, 'rb') + ftp.storbinary('STOR ' + webnotes.defs.server_prefix + '-' + fname, f) + ftp.quit() + + # delete from local pair directory + if hasattr(webnotes.defs, 'pair_dir') and len(os.listdir(webnotes.defs.pair_dir)) > 3: + delete_oldest_file(webnotes.defs.pair_dir) \ No newline at end of file diff --git a/cgi-bin/core/Module Def/Core/Core.txt b/cgi-bin/core/Module Def/Core/Core.txt new file mode 100644 index 0000000000..0316ef09cc --- /dev/null +++ b/cgi-bin/core/Module Def/Core/Core.txt @@ -0,0 +1,84 @@ +[ + { + 'creation': '2011-02-12 10:07:59', + 'disabled': 'No', + 'docstatus': 0, + 'doctype': 'Module Def', + 'doctype_list': None, + 'file_list': None, + 'idx': None, + 'is_hidden': 'Yes', + 'last_updated_date': None, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'module_desc': None, + 'module_icon': None, + 'module_label': 'Core', + 'module_name': 'Core', + 'module_page': None, + 'module_seq': None, + 'name': 'Core', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'trash_reason': None, + 'widget_code': None + }, + { + 'click_function': None, + 'creation': '2011-02-12 10:07:59', + 'description': None, + 'display_name': None, + 'doc_name': 'Pages', + 'doc_type': 'Separator', + 'docstatus': 0, + 'doctype': 'Module Def Item', + 'fields': None, + 'hide': None, + 'icon': None, + 'idx': None, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'name': 'MDI00288', + 'owner': 'Administrator', + 'parent': 'Core', + 'parentfield': 'items', + 'parenttype': 'Module Def' + }, + { + 'click_function': None, + 'creation': '2011-02-12 10:07:59', + 'description': None, + 'display_name': 'Manage Users', + 'doc_name': 'Manage Users', + 'doc_type': 'Pages', + 'docstatus': 0, + 'doctype': 'Module Def Item', + 'fields': None, + 'hide': None, + 'icon': None, + 'idx': None, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'name': 'MDI00289', + 'owner': 'Administrator', + 'parent': 'Core', + 'parentfield': 'items', + 'parenttype': 'Module Def' + }, + { + 'creation': '2011-02-12 10:07:59', + 'docstatus': 0, + 'doctype': 'Module Def Role', + 'idx': 1, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'name': 'MDR00076', + 'owner': 'Administrator', + 'parent': 'Core', + 'parentfield': 'roles', + 'parenttype': 'Module Def', + 'role': 'Administrator' + } +] \ No newline at end of file diff --git a/cgi-bin/core/Role/Administrator/Administrator.txt b/cgi-bin/core/Role/Administrator/Administrator.txt new file mode 100644 index 0000000000..d052c03f94 --- /dev/null +++ b/cgi-bin/core/Role/Administrator/Administrator.txt @@ -0,0 +1,17 @@ +[ + { + 'creation': '2010-08-08 17:08:51', + 'docstatus': 0, + 'doctype': 'Role', + 'idx': 0, + 'modified': '2011-06-03 10:08:30', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Administrator', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'role_name': 'Administrator' + } +] \ No newline at end of file diff --git a/cgi-bin/core/Role/All/All.txt b/cgi-bin/core/Role/All/All.txt new file mode 100644 index 0000000000..ac6e7f06cf --- /dev/null +++ b/cgi-bin/core/Role/All/All.txt @@ -0,0 +1,17 @@ +[ + { + 'creation': '2010-08-08 17:08:51', + 'docstatus': 0, + 'doctype': 'Role', + 'idx': None, + 'modified': '2011-06-03 10:08:41', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'All', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'role_name': 'All' + } +] \ No newline at end of file diff --git a/cgi-bin/core/Role/Guest/Guest.txt b/cgi-bin/core/Role/Guest/Guest.txt new file mode 100644 index 0000000000..52c23570bd --- /dev/null +++ b/cgi-bin/core/Role/Guest/Guest.txt @@ -0,0 +1,47 @@ +[ + { + 'creation': '2010-08-08 17:08:51', + 'docstatus': 0, + 'doctype': 'Role', + 'idx': None, + 'modified': '2011-06-03 10:08:51', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Guest', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'role_name': 'Guest' + }, + { + 'creation': '2010-08-08 17:08:51', + 'defkey': 'hide_webnotes_toolbar', + 'defvalue': '1', + 'docstatus': 0, + 'doctype': 'DefaultValue', + 'idx': 1, + 'modified': '2011-06-03 10:08:51', + 'modified_by': 'Administrator', + 'name': 'DEF000004', + 'owner': 'Administrator', + 'parent': 'Guest', + 'parentfield': 'defaults', + 'parenttype': 'Role' + }, + { + 'creation': '2010-08-08 17:08:51', + 'defkey': 'hide_sidebars', + 'defvalue': '1', + 'docstatus': 0, + 'doctype': 'DefaultValue', + 'idx': 2, + 'modified': '2011-06-03 10:08:51', + 'modified_by': 'Administrator', + 'name': 'DEF000005', + 'owner': 'Administrator', + 'parent': 'Guest', + 'parentfield': 'defaults', + 'parenttype': 'Role' + } +] \ No newline at end of file diff --git a/cgi-bin/core/__init__.py b/cgi-bin/core/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/__init__.py b/cgi-bin/core/doctype/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/comment_widget_record/__init__.py b/cgi-bin/core/doctype/comment_widget_record/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt b/cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt new file mode 100644 index 0000000000..7b83186625 --- /dev/null +++ b/cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt @@ -0,0 +1,358 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'CWR/.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:08:55', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:10:05', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Comment Widget Record', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 10 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-08-08 17:08:55', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-08-08 17:08:55', + 'modified_by': 'Administrator', + 'name': '_PERM00118', + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Comment', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00686', + 'no_copy': None, + 'oldfieldname': 'comment', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_by', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Comment By', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00687', + 'no_copy': None, + 'oldfieldname': 'comment_by', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_by_fullname', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Comment By Fullname', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00688', + 'no_copy': None, + 'oldfieldname': 'comment_by_fullname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_date', + 'fieldtype': 'Date', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Comment Date', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00689', + 'no_copy': None, + 'oldfieldname': 'comment_date', + 'oldfieldtype': 'Date', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_time', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Comment Time', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00690', + 'no_copy': None, + 'oldfieldname': 'comment_time', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_doctype', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Comment Doctype', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00691', + 'no_copy': None, + 'oldfieldname': 'comment_doctype', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_docname', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Comment Docname', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00692', + 'no_copy': None, + 'oldfieldname': 'comment_docname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'post_topic', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Post Topic', + 'modified': '2010-08-08 17:08:55', + 'modified_by': 'Administrator', + 'name': '_FL00693', + 'no_copy': None, + 'oldfieldname': 'post_topic', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/control_panel/__init__.py b/cgi-bin/core/doctype/control_panel/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/control_panel/control_panel.py b/cgi-bin/core/doctype/control_panel/control_panel.py new file mode 100644 index 0000000000..da1786b2ea --- /dev/null +++ b/cgi-bin/core/doctype/control_panel/control_panel.py @@ -0,0 +1,36 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import cint, flt +from webnotes.model.doc import Document +from webnotes.model.code import get_obj +from webnotes import session, form, is_testing, msgprint, errprint + +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc, doclist): + self.doc = doc + self.doclist = doclist + + def on_update(self): + # clear cache on save + sql("delete from __SessionCache") + + def upload_many(self,form): + pass + + def upload_callback(self,form): + pass + + def execute_test(self, arg=''): + if webnotes.user.name=='Guest': + raise Exception, 'Guest cannot call execute test!' + out = '' + exec(arg and arg or self.doc.test_code) + webnotes.msgprint('that worked!') + return out diff --git a/cgi-bin/core/doctype/control_panel/control_panel.txt b/cgi-bin/core/doctype/control_panel/control_panel.txt new file mode 100644 index 0000000000..eff2a542d4 --- /dev/null +++ b/cgi-bin/core/doctype/control_panel/control_panel.txt @@ -0,0 +1,1933 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': 1, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 1, + 'istable': 0, + 'max_attachments': None, + 'menu_index': 5, + 'modified': '2010-11-10 13:05:51', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Control Panel', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tray', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 1, + 'smallicon': 'controller.png', + 'use_template': None, + 'version': 18 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': '', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_PERM00001', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'General', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00001', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'date_format', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Date Format', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00002', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'currency_format', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Currency Format', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00421', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': 'Millions\nLacs', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-29 14:06:16', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'password_expiry_days', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Password Expires in (days)', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00243', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-07-09 13:55:51', + 'default': None, + 'depends_on': None, + 'description': 'Format: hh:mm example for one hour expiry set as 01:00. \nMax expiry will be 72 hours. Default is 24 hours', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'session_expiry', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Session Expires in (time)', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00303', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': '', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-08 14:18:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'new_style_search', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'New Style Search', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00264', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'title', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Title', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00004', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'account_id', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Account Id', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00005', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'company_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Company Name', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00422', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'industry', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Industry', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00423', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'time_zone', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Time Zone', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00424', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'country', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Country', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00425', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-07-09 14:53:42', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'sync_with_gateway', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Sync with Gateway', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00304', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'system_manager', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'System Manager', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00006', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'Profile', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'system_manager_email', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'System Manager Email', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00007', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 14:36:22', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'total_sms_sent', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Total SMS Sent', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00305', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 1, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 14:36:22', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Home Pages', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00306', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 11:14:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'default_home_pages', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Default Home Pages', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00356', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Default Home Page', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'home_page', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Home Page', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00008', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'Page', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-20 10:46:27', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Startup', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00289', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-20 10:46:27', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'startup_code', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Startup Code (JS)', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00288', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'startup_css', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': 'Startup CSS', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00429', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': 'Display', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00009', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 24, + 'in_filter': None, + 'label': 'Display Options', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00010', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '100%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': '', + 'description': 'Default page width is auto', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'page_width', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 25, + 'in_filter': None, + 'label': 'Page WIdth', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00011', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide_webnotes_toolbar', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 26, + 'in_filter': None, + 'label': 'Hide WebNotes Toolbar', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00012', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-12 10:12:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'background_color', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 27, + 'in_filter': None, + 'label': 'Background Color', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00278', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 28, + 'in_filter': None, + 'label': 'Header / Footer', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00013', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'Default header height is 40px', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'header_height', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 29, + 'in_filter': None, + 'label': 'Header Height', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00014', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'client_name', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 30, + 'in_filter': None, + 'label': 'Header HTML', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00015', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'footer_height', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 31, + 'in_filter': None, + 'label': 'Footer Height', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00016', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'footer_html', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 32, + 'in_filter': None, + 'label': 'Footer HTML', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00017', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'letter_head_image', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 33, + 'in_filter': None, + 'label': 'Letter Head Image', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00426', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'letter_head', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 34, + 'in_filter': None, + 'label': 'Letter Head', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00018', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': 1, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'client_logo', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 35, + 'in_filter': None, + 'label': 'Client Logo', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00019', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'File', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 36, + 'in_filter': None, + 'label': 'Mail Server', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00020', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': 'Enter Email Id to receive Error Report sent by users.\nE.g.: support@iwebnotes.com', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'support_email_id', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 37, + 'in_filter': None, + 'label': 'Support Email Id', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00427', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': 'automail@notesandreports.com', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'auto_email_id', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 38, + 'in_filter': None, + 'label': 'Auto Email Id', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00003', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-06-12 10:19:16', + 'default': None, + 'depends_on': None, + 'description': 'e.g. mail.webnotestech.com', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'outgoing_mail_server', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 39, + 'in_filter': None, + 'label': 'Outgoing Mail Server', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00279', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': '', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-11-25 10:13:39', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_port', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 40, + 'in_filter': None, + 'label': 'Mail Port', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00388', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-11-25 10:13:39', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'use_ssl', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 41, + 'in_filter': None, + 'label': 'Use SSL', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00389', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-12 10:19:16', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_login', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 42, + 'in_filter': None, + 'label': 'Login Id', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00280', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-12 10:19:16', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_password', + 'fieldtype': 'Password', + 'hidden': None, + 'icon': None, + 'idx': 43, + 'in_filter': None, + 'label': 'Mail Password', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00281', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_footer', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 44, + 'in_filter': None, + 'label': 'Mail Footer', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00428', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'rushabh@webnotestech.com', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 45, + 'in_filter': None, + 'label': 'Defaults', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00022', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:11', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'system_defaults', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 46, + 'in_filter': None, + 'label': 'System Defaults', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00023', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'DefaultValue', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 47, + 'in_filter': None, + 'label': 'Sidebars', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00024', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'To hide the left sidebar, leave this blank or 0', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'left_sidebar_width', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 48, + 'in_filter': None, + 'label': 'Left Sidebar Width', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00025', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'To hide the right sidebar, leave this blank or 0', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'right_sidebar_width', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 49, + 'in_filter': None, + 'label': 'Right Sidebar Width', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00026', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 50, + 'in_filter': None, + 'label': 'Test Script', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00027', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': '', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 14:36:22', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Button', + 'hidden': None, + 'icon': None, + 'idx': 51, + 'in_filter': None, + 'label': 'Execute Local', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00308', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Button', + 'hidden': None, + 'icon': 'accept.png', + 'idx': 52, + 'in_filter': None, + 'label': 'Execute (Careful!)', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00029', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'execute_test', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '150px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'test_code', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 53, + 'in_filter': None, + 'label': 'Test Code', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00028', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/custom_field/__init__.py b/cgi-bin/core/doctype/custom_field/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/custom_field/custom_field.js b/cgi-bin/core/doctype/custom_field/custom_field.js new file mode 100644 index 0000000000..dfd226d4fc --- /dev/null +++ b/cgi-bin/core/doctype/custom_field/custom_field.js @@ -0,0 +1,54 @@ +//168 +// Refresh +// -------- +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if(!doc.__islocal) get_field(doc.doctype, 'dt' , doc.name).permlevel = 1; + cur_frm.cscript.dt(doc, cdt, cdn); +} + + +cur_frm.cscript.has_special_chars = function(t) { + var iChars = "!@#$%^&*()+=-[]\\\';,./{}|\":<>?"; + for (var i = 0; i < t.length; i++) { + if (iChars.indexOf(t.charAt(i)) != -1) { + return true; + } + } + return false; +} + + +// Label +// ------ +cur_frm.cscript.label = function(doc){ + if(doc.label && cur_frm.cscript.has_special_chars(doc.label)){ + cur_frm.fields_dict['Label Help'].disp_area.innerHTML = 'Special Characters are not allowed'; + doc.label = ''; + refresh_field('label'); + } + else + cur_frm.fields_dict['Label Help'].disp_area.innerHTML = ''; +} + + +// Get Field Label based on DocType +// --------------------------------- +cur_frm.cscript.dt = function(doc, cdt, cdn) { + var callback = function(r, rt){ + + set_field_options('insert_after', r.message); + } + $c_obj([doc], 'get_fields_label', '', callback); +} + + +cur_frm.fields_dict['dt'].get_query = function(doc, dt, dn) { + return 'SELECT tabDocType.name FROM tabDocType WHERE IFNULL(tabDocType.issingle,0)=0 AND tabDocType.name LIKE "%s" ORDER BY name ASC LIMIT 50' +} + + +cur_frm.cscript.fieldtype = function(doc, dt, dn) { + if(doc.fieldtype == 'Link') cur_frm.fields_dict['Options Help'].disp_area.innerHTML = 'Please enter name of the document you want this field to be linked to in Options.
Eg.: Customer'; + else if(doc.fieldtype == 'Select') cur_frm.fields_dict['Options Help'].disp_area.innerHTML = 'Please enter values in Options separated by enter.
Eg.: Field: Country
Options:
China
India
United States

OR
You can also link it to existing Documents.
Eg.: link:Customer'; + else cur_frm.fields_dict['Options Help'].disp_area.innerHTML = ''; +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/custom_field/custom_field.py b/cgi-bin/core/doctype/custom_field/custom_field.py new file mode 100644 index 0000000000..9426c5e52d --- /dev/null +++ b/cgi-bin/core/doctype/custom_field/custom_field.py @@ -0,0 +1,100 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import cint, cstr, flt, formatdate, now +from webnotes.model.doc import Document +from webnotes import msgprint, errprint + +sql = webnotes.conn.sql + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl + + # Get Fields + # ----------- + def get_fields_label(self): + label_name = [] + for i in sql("SELECT idx, label FROM tabDocField WHERE parent = '%s' and ifnull(hidden,0) = 0 and fieldname != '%s' order by idx" % (self.doc.dt, cstr(self.doc.fieldname))): i[1] and i[0] and label_name.append(i[1]+' - '+cstr(i[0])) + return "\n".join(label_name) + + +# *************************** Validate ******************************* + # Set Field name + # ---------------- + def set_fieldname(self): + if not self.doc.fieldname: + # remove special characters from fieldname + self.doc.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_', cstr(self.doc.label).lower().replace(' ','_')) + + + # Validate Field + # --------------- + def validate_field(self): + if self.doc.__islocal == 1 and sql("select name from tabDocField where parent = %s and (label = %s or fieldname = %s)" , (self.doc.dt, self.doc.label, self.doc.fieldname)): + msgprint("%s field already exists in Document : %s" % (self.doc.label, self.doc.dt)) + raise Exception + + if self.doc.fieldtype=='Link' and self.doc.options: + if not sql("select name from tabDocType where name=%s", self.doc.options): + msgprint("%s is not a valid Document" % self.doc.options) + raise Exception + + + # Update Field + # ------------- + def update_field(self, df, new): + import webnotes.model + sql("update tabDocField set idx = idx + 1, modified = %s where parent = %s and idx > %s", (now(),self.doc.dt, self.idx)) + for k in self.doc.fields: + if k not in webnotes.model.default_fields and k not in self.ignore_fields and not k.startswith('_'): + df.fields[k] = self.doc.fields[k] + df.parent = self.doc.dt + df.parenttype = 'DocType' + df.parentfield = 'fields' + df.idx = self.idx+1 + df.save(new) + + + # Add Field + # ---------- + def add_field(self): + field_exists = sql("select name from tabDocField where parent = %s and (label = %s or fieldname = %s)" , (self.doc.dt, self.doc.label, self.doc.fieldname)) + field_exists = field_exists and field_exists[0][0] or '' + self.ignore_fields = ['dt','trash_reason','insert_after','index','customfield1','length'] + if field_exists: + df = Document('DocField',field_exists) + self.update_field(df, new = 0) + else: + df = Document('DocField') + self.update_field(df, new = 1) + + + # Validate + # --------- + def validate(self): + self.set_fieldname() + self.validate_field() + self.idx = cint((self.doc.insert_after).split(' - ')[1]) + self.add_field() + + # update the schema + from webnotes.model.db_schema import updatedb + updatedb(self.doc.dt) + + # Trash + # ------ + def on_trash(self): + sql("update tabDocField set idx = idx - 1 where parent = %s and idx > %s" , (self.doc.dt, cint((self.doc.insert_after).split(' - ')[1]))) + sql("delete from tabDocField where parent = %s and fieldname = %s", (self.doc.dt, self.doc.fieldname)) + + + # Restore + # -------- + def on_restore(self): + self.validate_field() + self.idx = cint((self.doc.insert_after).split(' - ')[1]) + self.add_field() diff --git a/cgi-bin/core/doctype/custom_field/custom_field.txt b/cgi-bin/core/doctype/custom_field/custom_field.txt new file mode 100644 index 0000000000..36ce318e79 --- /dev/null +++ b/cgi-bin/core/doctype/custom_field/custom_field.txt @@ -0,0 +1,929 @@ +[ + { + '_last_update': '1305006253', + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': 1, + 'autoname': "eval:doc.dt+'-'+doc.label", + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-10-13 16:39:01', + 'description': 'Add a custom field to a DocType', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Custom Field', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': 'dt,label,fieldtype', + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'subject': '%(label)s (%(fieldtype)s) on %(dt)s', + 'tag_fields': 'dt,fieldtype', + 'use_template': None, + 'version': 159 + }, + { + 'amend': None, + 'cancel': 1, + 'create': 1, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00695', + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 2, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00696', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 3, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00697', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 2, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'amend': None, + 'cancel': 1, + 'create': 1, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 4, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00698', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 5, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00699', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Details', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03961', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'trash_reason', + 'fieldtype': 'Small Text', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Trash Reason', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03962', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'trash_reason', + 'oldfieldtype': 'Small Text', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 1, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': 1, + 'label': 'Document', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03963', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'dt', + 'oldfieldtype': 'Link', + 'options': 'DocType', + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'label', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': 1, + 'label': 'Label', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03964', + 'no_column': None, + 'no_copy': 1, + 'oldfieldname': 'label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-14 09:28:31', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Label Help', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03981', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'HTML', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldtype', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': 1, + 'label': 'Field Type', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03965', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fieldtype', + 'oldfieldtype': 'Select', + 'options': '\nButton\nCheck\nColumn Break\nCurrency\nData\nDate\nFloat\nHTML\nInt\nLink\nRead Only\nSection Break\nSelect\nSmall Text\nText\nText Editor\nTime', + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 0, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Options Help', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03966', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'HTML', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'options', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Options', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03967', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'options', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Field Description', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03968', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '300px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Properties', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03969', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': 'Select the label after which you want to insert new field.', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'insert_after', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Insert After', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03970', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'insert_after', + 'oldfieldtype': 'Select', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'default', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Default Value', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03971', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'default', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldname', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Fieldname', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03972', + 'no_column': None, + 'no_copy': 1, + 'oldfieldname': 'fieldname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 2, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'width', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Width', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03973', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'width', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'reqd', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Is Mandatory Field', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03974', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'reqd', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_filter', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'In Report Filter', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03975', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_filter', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'no_copy', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'No Copy', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03976', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'no_copy', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'print_hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Print Hide', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03977', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'print_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'report_hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Report Hide', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03978', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'report_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_on_submit', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Allow on Submit', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03979', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_on_submit', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permlevel', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Permission Level', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03980', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'permlevel', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/custom_script/__init__.py b/cgi-bin/core/doctype/custom_script/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/custom_script/custom_script.txt b/cgi-bin/core/doctype/custom_script/custom_script.txt new file mode 100644 index 0000000000..446881a302 --- /dev/null +++ b/cgi-bin/core/doctype/custom_script/custom_script.txt @@ -0,0 +1,189 @@ +[ + { + '_last_update': '1305701384', + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': "eval:doc.dt + '-' + doc.script_type", + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:08:56', + 'description': 'Add a custom script (client or server) to a DocType', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Custom Script', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'subject': ' ', + 'tag_fields': 'dt,script_type', + 'use_template': None, + 'version': 8 + }, + { + 'amend': None, + 'cancel': 1, + 'create': 1, + 'creation': '2010-08-08 17:08:56', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_PERM00149', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': 1, + 'label': 'DocType', + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_FL00824', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'dt', + 'oldfieldtype': 'Link', + 'options': 'DocType', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'script_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': 1, + 'label': 'Script Type', + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_FL00825', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'script_type', + 'oldfieldtype': 'Select', + 'options': 'Server\nClient', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'script', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Script', + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_FL00826', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'script', + 'oldfieldtype': 'Code', + 'options': 'Script', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/default_home_page/__init__.py b/cgi-bin/core/doctype/default_home_page/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/default_home_page/default_home_page.txt b/cgi-bin/core/doctype/default_home_page/default_home_page.txt new file mode 100644 index 0000000000..da898dba4e --- /dev/null +++ b/cgi-bin/core/doctype/default_home_page/default_home_page.txt @@ -0,0 +1,125 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-10-28 11:12:48', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Default Home Page', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 11:12:48', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-10-28 11:22:02', + 'modified_by': 'Administrator', + 'name': '_FL00354', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Default Home Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 11:12:48', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'home_page', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Home Page', + 'modified': '2009-10-28 11:22:02', + 'modified_by': 'Administrator', + 'name': '_FL00355', + 'no_copy': None, + 'oldfieldname': 'home_page', + 'oldfieldtype': 'Link', + 'options': 'Page', + 'owner': 'Administrator', + 'parent': 'Default Home Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/defaultvalue/__init__.py b/cgi-bin/core/doctype/defaultvalue/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/defaultvalue/defaultvalue.txt b/cgi-bin/core/doctype/defaultvalue/defaultvalue.txt new file mode 100644 index 0000000000..b3f5b3ca1f --- /dev/null +++ b/cgi-bin/core/doctype/defaultvalue/defaultvalue.txt @@ -0,0 +1,125 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'DEF.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DefaultValue', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:11', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'defkey', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Key', + 'modified': '2009-05-12 11:19:11', + 'modified_by': 'Administrator', + 'name': '_FL00030', + 'no_copy': None, + 'oldfieldname': 'defkey', + 'oldfieldtype': 'Data', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DefaultValue', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 0, + 'trigger': '', + 'width': '200px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:11', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'defvalue', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Value', + 'modified': '2009-05-12 11:19:11', + 'modified_by': 'Administrator', + 'name': '_FL00031', + 'no_copy': None, + 'oldfieldname': 'defvalue', + 'oldfieldtype': 'Text', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DefaultValue', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '200px' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/docfield/__init__.py b/cgi-bin/core/doctype/docfield/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/docfield/docfield.txt b/cgi-bin/core/doctype/docfield/docfield.txt new file mode 100644 index 0000000000..ab184c21af --- /dev/null +++ b/cgi-bin/core/doctype/docfield/docfield.txt @@ -0,0 +1,907 @@ +[ + { + '_last_update': '1304505340', + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'FL.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocField', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 4 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 0, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_PERM00003', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 0, + 'role': 'Administrator', + 'submit': 0, + 'write': 0 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'label', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Label', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00032', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldtype', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Type', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00033', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fieldtype', + 'oldfieldtype': 'Select', + 'options': 'Data\nSelect\nText\nSmall Text\nText Editor\nLink\nInt\nDate\nTime\nCurrency\nTable\nFloat\nCheck\nSection Break\nColumn Break\nButton\nRead Only\nCode\nHTML\nImage\nBlob\nPassword', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldname', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Name', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00034', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fieldname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'options', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Options', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00035', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'options', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permlevel', + 'fieldtype': 'Int', + 'hidden': 0, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Perm Level', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00036', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'permlevel', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'width', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Width', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00037', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'width', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'reqd', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Reqd', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00038', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'reqd', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'search_index', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Index', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00039', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'search_index', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_filter', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'In Filter', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00390', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_filter', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'nabin@webnotestech.com', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hidden', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Hidden', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00040', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'hidden', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-05 14:00:58', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'no_column', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'No Column', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '000000705', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'print_hide', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Print Hide', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00041', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'print_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'no_copy', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'No Copy', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00042', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'no_copy', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'report_hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Report Hide', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00043', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'report_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_on_submit', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Allow on Submit', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00044', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_on_submit', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'depends_on', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Depends On', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00045', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'depends_on', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00046', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '300px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'trigger', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Trigger', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00047', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'trigger', + 'oldfieldtype': 'Select', + 'options': '\nClient\nServer', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'default', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Default', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00048', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'default', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'colour', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Colour', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00049', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'colour', + 'oldfieldtype': 'Select', + 'options': 'White:FFF\nLight Blue:DEF\nLight Green:DFE\nPeach:FEF3C5\nPink:FEF2EA\nLilac:FDEAFE\nAqua:EAFEFA', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'icon', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Icon', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00050', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'icon', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'oldfieldname', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00051', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'oldfieldname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'oldfieldtype', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00052', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'oldfieldtype', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/docformat/__init__.py b/cgi-bin/core/doctype/docformat/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/docformat/docformat.txt b/cgi-bin/core/doctype/docformat/docformat.txt new file mode 100644 index 0000000000..5468599a6f --- /dev/null +++ b/cgi-bin/core/doctype/docformat/docformat.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'DF.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocFormat', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': None, + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'format', + 'fieldtype': 'Link', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Format', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00054', + 'no_copy': None, + 'oldfieldname': 'format', + 'oldfieldtype': 'Link', + 'options': 'Print Format', + 'owner': 'Administrator', + 'parent': 'DocFormat', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/docperm/__init__.py b/cgi-bin/core/doctype/docperm/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/docperm/docperm.txt b/cgi-bin/core/doctype/docperm/docperm.txt new file mode 100644 index 0000000000..3290aa228c --- /dev/null +++ b/cgi-bin/core/doctype/docperm/docperm.txt @@ -0,0 +1,405 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'PERM.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocPerm', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permlevel', + 'fieldtype': 'Int', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Level', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00055', + 'no_copy': None, + 'oldfieldname': 'permlevel', + 'oldfieldtype': 'Int', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '40px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00056', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '150px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'read', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Read', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00057', + 'no_copy': None, + 'oldfieldname': 'read', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'write', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Write', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00058', + 'no_copy': None, + 'oldfieldname': 'write', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'create', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Create', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00059', + 'no_copy': None, + 'oldfieldname': 'create', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'submit', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Submit', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00060', + 'no_copy': None, + 'oldfieldname': 'submit', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'cancel', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Cancel', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00061', + 'no_copy': None, + 'oldfieldname': 'cancel', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'execute', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Execute', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00062', + 'no_copy': None, + 'oldfieldname': 'execute', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'amend', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Amend', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00063', + 'no_copy': None, + 'oldfieldname': 'amend', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'match', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Match', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00064', + 'no_copy': None, + 'oldfieldname': 'match', + 'oldfieldtype': 'Data', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctrigger/__init__.py b/cgi-bin/core/doctype/doctrigger/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctrigger/doctrigger.txt b/cgi-bin/core/doctype/doctrigger/doctrigger.txt new file mode 100644 index 0000000000..666f2ca355 --- /dev/null +++ b/cgi-bin/core/doctype/doctrigger/doctrigger.txt @@ -0,0 +1,196 @@ +[ + { + '_last_update': None, + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': '_TRIGGER.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2011-05-09 11:04:24', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': 1, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-03-31 15:23:46', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocTrigger', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 1, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_type', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Doc Type', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000396', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Doc Name', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000397', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Event Name', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000398', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'method', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Method', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000399', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype/__init__.py b/cgi-bin/core/doctype/doctype/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctype/doctype.js b/cgi-bin/core/doctype/doctype/doctype.js new file mode 100644 index 0000000000..9218b58f0e --- /dev/null +++ b/cgi-bin/core/doctype/doctype/doctype.js @@ -0,0 +1,75 @@ +// ------------- +// Menu Display +// ------------- + +cur_frm.cscript.issingle = function(doc, cdt, cdn) { + if(doc.issingle) + unhide_field('show_in_menu'); + else { + doc.show_in_menu = 0; + hide_field('show_in_menu'); + hide_field('parent_node'); + hide_field('Parent HTML'); + hide_field('Menu HTML'); + hide_field('menu_index'); + hide_field('smallicon'); + } +} + +cur_frm.cscript.show_in_menu = function(doc, cdt, cdn) { + if(doc.show_in_menu) { + unhide_field('parent_node'); + unhide_field('Parent HTML'); + unhide_field('Menu HTML'); + unhide_field('menu_index'); + unhide_field('smallicon'); + } else { + hide_field('parent_node'); + hide_field('Parent HTML'); + hide_field('Menu HTML'); + hide_field('menu_index'); + hide_field('smallicon'); + } +} + +// Attachment + +cur_frm.cscript.allow_attach = function(doc, cdt, cdn) { + if(doc.allow_attach) { + unhide_field('max_attachments'); + } else { + hide_field('max_attachments'); + } +} + +cur_frm.cscript.onload = function(doc, cdt, cdn) { + this.issingle(doc, cdt, cdn); + this.allow_attach(doc, cdt, cdn); + this.show_in_menu(doc, cdt, cdn); +} + +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if(in_list(user_roles, 'System Manager') && !in_list(user_roles, 'Administrator')) { + // make the document read-only + cur_frm.perm = [[1,0,0]] + + // make help heading + cur_frm.tip_wrapper.innerHTML = ''; + $a(cur_frm.tip_wrapper, 'div', 'help_box','','Cannot Edit DocType directly: To edit DocType properties, create / update Custom Field, Custom Script and Property Setter') + } + + + // show button for import + cur_frm.add_custom_button('Import from File', cur_frm.cscript.do_import); +} + +cur_frm.cscript.validate = function(doc, cdt, cdn) { + doc.server_code_compiled = null; +} + +cur_frm.cscript.do_import = function(doc, cdt, cdn) { + callback = function(r,rt) { + cur_frm.refresh_doc(); + } + $c_obj([doc], 'import_doctype', '', callback) +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype/doctype.py b/cgi-bin/core/doctype/doctype/doctype.py new file mode 100644 index 0000000000..b7238cf1c1 --- /dev/null +++ b/cgi-bin/core/doctype/doctype/doctype.py @@ -0,0 +1,94 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import now, cint +sql = webnotes.conn.sql +msgprint = webnotes.msgprint + + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc=None, doclist=[]): + self.doc = doc + self.doclist = doclist + + def change_modified_of_parent(self): + parent_list = sql('SELECT parent from tabDocField where fieldtype="Table" and options="%s"' % self.doc.name) + for p in parent_list: + sql('UPDATE tabDocType SET modified="%s" WHERE `name`="%s"' % (now(), p[0])) + + def scrub_field_names(self): + restricted = ('name','parent','idx','owner','creation','modified','modified_by','parentfield','parenttype') + for d in self.doclist: + if d.parent and d.fieldtype: + if (not d.fieldname) and (d.fieldtype.lower() in ('data', 'select', 'int', 'float', 'currency', 'table', 'text', 'link', 'date', 'code', 'check', 'read only', 'small_text', 'time')): + d.fieldname = d.label.strip().lower().replace(' ','_') + if d.fieldname in restricted: + d.fieldname = d.fieldname + '1' + + def set_version(self): + self.doc.version = cint(self.doc.version) + 1 + + # + # check if this series is not used elsewhere + # + def validate_series(self, autoname=None, name=None): + if not autoname: autoname = self.doc.autoname + if not name: name = self.doc.name + + if autoname and (not autoname.startswith('field:')) and (not autoname.startswith('eval:')) and (not autoname=='Prompt'): + prefix = autoname.split('.')[0] + used_in = sql('select name from tabDocType where substring_index(autoname, ".", 1) = %s and name!=%s', (prefix, name)) + if used_in: + msgprint('Series already in use: The series "%s" is already used in "%s"' % (prefix, used_in[0][0]), raise_exception=1) + + # + # field validations + # + def validate_fields(self): + "validates fields for incorrect properties and double entries" + fieldnames = {} + for d in self.doclist: + if d.parent and d.fieldtype and d.parent == self.doc.name: + # check if not double + if d.fieldname: + if fieldnames.get(d.fieldname): + webnotes.msgprint('Fieldname %s appears twice (rows %s and %s). Please rectify' \ + % (d.fieldname, str(d.idx + 1), str(fieldnames[d.fieldname] + 1)), raise_exception=1) + fieldnames[d.fieldname] = d.idx + + # check illegal mandatory + if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd: + webnotes.msgprint('%(lable)s [%(fieldtype)s] cannot be mandatory', raise_exception=1) + + # validate if allow attach, then file_list must be present + if self.doc.allow_attach and not fieldnames.get('file_list'): + webnotes.msgprint('To allow attachments, a field with fieldname "file_list" of type text must be present', raise_exception = 1) + + def validate(self): + self.validate_series() + self.scrub_field_names() + self.validate_fields() + self.set_version() + + def on_update(self): + # make schma changes + from webnotes.model.db_schema import updatedb + updatedb(self.doc.name) + + self.change_modified_of_parent() + + import webnotes.defs + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + self.export_doc() + sql("delete from __DocTypeCache") + + def export_doc(self): + from webnotes.modules.export_module import export_to_files + export_to_files(record_list=[['DocType', self.doc.name]]) + + def import_doc(self): + from webnotes.modules.import_module import import_from_files + import_from_files(record_list=[[self.doc.module, 'doctype', self.doc.name]]) diff --git a/cgi-bin/core/doctype/doctype/doctype.txt b/cgi-bin/core/doctype/doctype/doctype.txt new file mode 100644 index 0000000000..2905663ea4 --- /dev/null +++ b/cgi-bin/core/doctype/doctype/doctype.txt @@ -0,0 +1,1796 @@ +[ + { + '_last_update': '1305026481', + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'Prompt', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocType', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': 'Yes', + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': 'autoname', + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'subject': None, + 'tag_fields': None, + 'use_template': None, + 'version': 9 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': None, + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_PERM00004', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 2, + 'match': None, + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_PERM00005', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Options', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000398', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Settings', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000399', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00067', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Link', + 'options': 'Module Def', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'version', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Version', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00068', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'version', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:21:46', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'name', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Name', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00309', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'autoname', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Auto Name', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00069', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'autoname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:21:46', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'owner', + 'fieldtype': 'Link', + 'hidden': 1, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Owner', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00310', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'owner', + 'oldfieldtype': 'Link', + 'options': 'Profile', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'name_case', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Name Case', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00070', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'name_case', + 'oldfieldtype': 'Select', + 'options': '\nTitle Case\nUPPER CASE', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'search_fields', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Search Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00071', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'search_fields', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2011-05-10 14:02:46', + 'default': None, + 'depends_on': None, + 'description': 'Subject will appear as a string in the docbrowser: eg.\n[%(status)s] %(description)s\nIf it is a JS Expression, use "eval:"', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'subject', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Subject', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000757', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2011-05-10 16:51:20', + 'default': None, + 'depends_on': None, + 'description': 'Fields separated by (,) that will be set as tags', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'tag_fields', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'tag_fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000758', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'istable', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Is Table', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00072', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'istable', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'read_only', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Not In Search', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00073', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'read_only', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_create', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Not In Create', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00074', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_create', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'issingle', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Is Single', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00075', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'issingle', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-04-01 12:38:02', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'read_only_onload', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Show Print First', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00410', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'read_only_onload', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 16:51:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'show_in_menu', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Show In Pages', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00418', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'show_in_menu', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-09-20 12:44:07', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'document_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Document Type', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL03897', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'document_type', + 'oldfieldtype': 'Select', + 'options': '\nMaster\nTransaction\nSystem\nOther', + 'owner': 'harshada@webnotestech.com', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': 0, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Display', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000400', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 09:58:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'is_transaction_doc', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Is Transaction Doc', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000384', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'is_transaction_doc', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'use_template', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Use Template', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00082', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'use_template', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'print_outline', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': 'Print Outline', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00083', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'print_outline', + 'oldfieldtype': 'Select', + 'options': '\nNo\nYes', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_print', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': 'Hide Print', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00084', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_print', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_email', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 24, + 'in_filter': None, + 'label': 'Hide Email', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00085', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_email', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 16:51:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_dialog', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 25, + 'in_filter': None, + 'label': 'In Dialog', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00420', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_dialog', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_copy', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 26, + 'in_filter': None, + 'label': 'Hide Copy', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00086', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_copy', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide_toolbar', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 27, + 'in_filter': None, + 'label': 'Hide Toolbar', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00087', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'hide_toolbar', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide_heading', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 28, + 'in_filter': None, + 'label': 'Hide Heading', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00088', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'hide_heading', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': 'allow_attach', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 29, + 'in_filter': None, + 'label': 'Allow Attach', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00089', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_attach', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'max_attachments', + 'fieldtype': 'Int', + 'hidden': 1, + 'icon': None, + 'idx': 30, + 'in_filter': None, + 'label': 'Max Attachments', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00090', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'max_attachments', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_rename', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 31, + 'in_filter': None, + 'label': 'Allow Rename', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00091', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_rename', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'section_style', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 32, + 'in_filter': None, + 'label': 'Section Style', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00092', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'section_style', + 'oldfieldtype': 'Select', + 'options': 'Simple\nPaged\nTabbed\nTray', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'colour', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 33, + 'in_filter': None, + 'label': 'Colour', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00093', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'colour', + 'oldfieldtype': 'Select', + 'options': 'White:FFF\nLight Blue:DEF\nLight Green:DFE\nPeach:FEF3C5\nPink:FEF2EA\nLilac:FDEAFE\nAqua:EAFEFA', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'smallicon', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 34, + 'in_filter': None, + 'label': 'Small Icon', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00094', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'smallicon', + 'oldfieldtype': 'Select', + 'options': '\naccept.png\nadd.png\napplication.png\nbell.png\nbox.png\ncalendar.png\ncalculator.png\ncancel.png\ncart.png\ncd.png\nchart_bar.png\nclock.png\ncoins.png\ncomputer.png\ncontroller.png\ndisk.png\nemail.png\nerror.png\nfolder.png\ngroup.png\nhouse.png\nimages.png\nlock_open.png\nlock.png\nlorry.png\nmagnifier.png\nmap.png\nmoney.png\nnew.png\npage.png\nprinter.png\nreport.png\nserver.png\nshield.png\ntable.png\nuser.png', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 35, + 'in_filter': None, + 'label': 'Permissions', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000401', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 36, + 'in_filter': None, + 'label': 'Roles and Permissions', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000402', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '70%' + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permissions', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 37, + 'in_filter': None, + 'label': 'Permissions', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00097', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'permissions', + 'oldfieldtype': 'Table', + 'options': 'DocPerm', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 16:51:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_trash', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 38, + 'in_filter': None, + 'label': 'Allow Trash', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00419', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_trash', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 39, + 'in_filter': None, + 'label': 'Print Formats', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000403', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '30%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'formats', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 40, + 'in_filter': None, + 'label': 'Formats', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00099', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'formats', + 'oldfieldtype': 'Table', + 'options': 'DocFormat', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': 0, + 'icon': None, + 'idx': 41, + 'in_filter': None, + 'label': 'Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000404', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': 0, + 'icon': None, + 'idx': 42, + 'in_filter': None, + 'label': 'Document Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000405', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fields', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 43, + 'in_filter': None, + 'label': 'Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00102', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fields', + 'oldfieldtype': 'Table', + 'options': 'DocField', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': 0, + 'icon': None, + 'idx': 44, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000406', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 45, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00104', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '300px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 46, + 'in_filter': None, + 'label': 'Template', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000410', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt_template', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 47, + 'in_filter': None, + 'label': 'DocType Template', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00116', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'dt_template', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype_label/__init__.py b/cgi-bin/core/doctype/doctype_label/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctype_label/doctype_label.txt b/cgi-bin/core/doctype/doctype_label/doctype_label.txt new file mode 100644 index 0000000000..a7ab55b424 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_label/doctype_label.txt @@ -0,0 +1,148 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:dt', + 'change_log': None, + 'client_script': None, + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-11-30 17:30:00', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocType Label', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-11-30 17:30:00', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-11-30 17:30:00', + 'modified_by': 'Administrator', + 'name': '_PERM00045', + 'owner': 'Administrator', + 'parent': 'DocType Label', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Select DocType', + 'modified': '2010-11-30 17:30:00', + 'modified_by': 'Administrator', + 'name': '_FL00494', + 'no_copy': None, + 'oldfieldname': 'dt', + 'oldfieldtype': 'Select', + 'options': 'link:DocType', + 'owner': 'Administrator', + 'parent': 'DocType Label', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt_label', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'DocType Label', + 'modified': '2010-11-30 17:30:00', + 'modified_by': 'Administrator', + 'name': '_FL00495', + 'no_copy': None, + 'oldfieldname': 'dt_label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType Label', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype_mapper/__init__.py b/cgi-bin/core/doctype/doctype_mapper/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js new file mode 100644 index 0000000000..a084a981a3 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js @@ -0,0 +1,9 @@ +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if(doc.from_doctype) { + get_field(doc.doctype, 'from_doctype', doc.name).permlevel = 1; + refresh_field('from_doctype'); + + get_field(doc.doctype, 'to_doctype', doc.name).permlevel = 1; + refresh_field('to_doctype'); + } +} diff --git a/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py new file mode 100644 index 0000000000..7fb0f61766 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py @@ -0,0 +1,247 @@ +# Please edit this list and import only required elements +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.doclist import getlist, copy_doclist +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 + +set = webnotes.conn.set +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value +in_transaction = webnotes.conn.in_transaction +convert_to_lists = webnotes.conn.convert_to_lists + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + self.prefix = is_testing and 'test' or 'tab' + self.ref_doc = '' + # Autoname + #--------- + def autoname(self): + self.doc.name = make_autoname(self.doc.from_doctype + '-' + self.doc.to_doctype) + + # Map Custom Fields + # ------------------ + def map_custom_fields(self, from_doctype, to_doctype, from_doc, to_doc): + fld_list = [] + for d in sql("select fieldname from `tabCustom Field` where dt = %s and docstatus != 2",from_doctype): + if sql("select fieldname from `tabCustom Field` where dt = %s and fieldname = %s and docstatus != 2",(to_doctype, d[0])): + fld_list.append([d[0], d[0]]) + self.set_value(fld_list, from_doc, to_doc) + + # Maps the fields in 'To DocType' + #-------------------------------- + def dt_map(self, from_doctype, to_doctype, from_docname, to_doc, doclist, from_to_list = '[]'): + + # definition of arguments + ''' + String : contains the name of DocType initiating the function + String : contains the name of DocType created by the function + String : contains ID(name) of 'from_doctype' + String : contains doc of 'to_doctype' + String : contains doclist of 'to_doctype' + String : contains list of tables which will be mapped + ''' + # Validate reference doc docstatus + self.ref_doc = from_docname + self.check_ref_docstatus() + + if not doclist: + doclist.append(to_doc) + + tbl_list = sql("select from_table, to_table, from_field, to_field, match_id, validation_logic from `tabTable Mapper Detail` where parent ='%s' order by match_id" % (from_doctype + "-" + to_doctype)) + + for t in tbl_list: + from_table_name = t[0] + to_table_name = t[1] + from_table_fname = t[2] + to_table_fname = t[3] + match_id = t[4] + validation_logic = t[5] + + + from_to = [from_table_name, to_table_name] + + if from_to in eval(from_to_list): + fld_list = sql("select from_field, to_field from `tabField Mapper Detail` where parent = '%s' and match_id = %s and map = 'Yes'" % (from_doctype + "-" + to_doctype, match_id)) + if fld_list: + if not from_docname: + msgprint(from_doctype + " not selected for mapping") + raise Exception + + # Parent to parent mapping + if from_table_name == self.doc.from_doctype and to_table_name == self.doc.to_doctype: + + # Check validation + nm = sql("select name from `tab%s` where name = '%s' and %s" % (from_doctype, from_docname, validation_logic)) + nm = nm and nm[0][0] or '' + + # If validation failed raise exception + if not nm: + msgprint("Validation failed in doctype mapper. Please contact Administrator.") + raise Exception + + from_doc = Document(from_doctype, nm) + # Maps field in parent + self.set_value(fld_list, from_doc, to_doc) + # Map custom fields + self.map_custom_fields(from_doctype, to_doctype, from_doc, to_doc) + + # Parent to child OR child to child mapping + else: + dnlist = () + if from_table_name == self.doc.from_doctype: + dnlist = ((from_docname,),) + else: + dnlist = sql("select name from `tab%s` where parent='%s' and parenttype = '%s' and %s order by idx" % (from_table_name, from_docname, self.doc.from_doctype, validation_logic)) + + for dn in dnlist: + # Add a row in target table in 'To DocType' and returns obj + ch = addchild(to_doc, t[3], t[1], 1, doclist) + # Creates object for 'From DocType', it can be parent or child + d = Document(t[0], dn[0]) + # Map values + self.set_value(fld_list, d, ch) + # Map custom fields + self.map_custom_fields(from_table_name, t[1], d, ch) + + # Required when called from server side for refreshing table + return doclist + + # Assigns value to "To Doctype" + #------------------------------ + def set_value(self, fld_list, obj, to_doc): + for f in fld_list: + if f[0].startswith('eval:'): + to_doc.fields[f[1]] = eval(f[0][5:]) + else: + to_doc.fields[f[1]] = obj.fields.get(f[0]) + + # Validate + #--------- + def validate(self): + for d in getlist(self.doclist, 'field_mapper_details'): + # Automatically assigns default value if not entered + if not d.match_id: + d.match_id = 0 + if not d.map: + d.map = 'Yes' + for d in getlist(self.doclist, 'table_mapper_details'): + if not d.reference_doctype_key: + d.reference_doctype_key = '' + if not d.reference_key: + d.reference_key = '' + + # Check wrong field name + self.check_fields_in_dt() + + # Check if any wrong fieldname entered + #-------------------------------------- + def check_fields_in_dt(self): + for d in getlist(self.doclist, 'field_mapper_details'): + table_name = sql("select from_table, to_table from `tabTable Mapper Detail` where parent ='%s' and match_id = '%s'" % (self.doc.name, d.match_id)) + + if table_name: + exists1 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][0], d.from_field)) + exists2 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][1], d.to_field)) + + # Default fields like name, parent, owner does not exists in DocField + if not exists1 and d.from_field not in default_fields: + msgprint('"' + cstr(d.from_field) + '" does not exists in DocType "' + cstr(table_name[0][0]) + '"') + if not exists2 and d.to_field not in default_fields: + msgprint('"' + cstr(d.to_field) + '" does not exists in DocType "' + cstr(table_name[0][1]) + '"') + + # Check consistency of value with reference document + #--------------------------------------------------- + def validate_reference_value(self, obj, to_docname): + for t in getlist(self.doclist, 'table_mapper_details'): + # Reference key is the fieldname which will relate to the from_table + if t.reference_doctype_key: + for d in getlist(obj.doclist, t.to_field): + if d.fields[t.reference_doctype_key] == self.doc.from_doctype: + self.check_consistency(obj.doc, d, to_docname) + self.check_ref_docstatus() + + # Make list of fields whose value will be consistent with prevdoc + #----------------------------------------------------------------- + def get_checklist(self): + checklist = [] + for f in getlist(self.doclist, 'field_mapper_details'): + + # Check which field's value will be compared + if f.checking_operator: + checklist.append([f.from_field, f.to_field, f.checking_operator, f.match_id]) + return checklist + + def check_fld_type(self, tbl, fld, cur_val): + ft = sql("select fieldtype from tabDocField where fieldname = '%s' and parent = '%s'" % (fld,tbl)) + ft = ft and ft[0][0] or '' + if ft == 'Currency' or ft == 'Float': + cur_val = '%.2f' % cur_val + return cur_val, ft + + # Check consistency + #------------------- + def check_consistency(self, par_obj, child_obj, to_docname): + checklist = self.get_checklist() + self.ref_doc = '' + for t in getlist(self.doclist, 'table_mapper_details'): + if t.reference_key and child_obj.fields[t.reference_key]: + for cl in checklist: + if cl[3] == t.match_id: + if t.to_field: + cur_val = child_obj.fields[cl[1]] + else: + cur_val = par_obj.fields[cl[1]] + + ft = self.check_fld_type(t.to_table, cl[1], cur_val) + cur_val = ft[0] + + if cl[2] == '=' and (ft[1] == 'Currency' or ft[1] == 'Float'): + consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' - %s <= 0.5" % (cl[0], t.from_table, child_obj.fields[t.reference_key], flt(cur_val), cl[0])) + else: + #consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s %s" % (cl[0], t.from_table, child_obj.fields[t.reference_key], cur_val, cl[2], cl[0])) + consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s ifnull(%s, '')" % (cl[0], t.from_table, child_obj.fields[t.reference_key], ft[1] in ('Currency', 'Float', 'Int') and flt(cur_val) or cstr(cur_val), cl[2], cl[0])) + + if not self.ref_doc: + det = sql("select name, parent from `tab%s` where name = '%s'" % (t.from_table, child_obj.fields[t.reference_key])) + self.ref_doc = det[0][1] and det[0][1] or det[0][0] + + if not consistent: + self.give_message(t.from_table, t.to_table, cl[0], cl[1], child_obj.fields[t.reference_key], cl[2]) + + # Gives message and raise exception + #----------------------------------- + def give_message(self, from_table, to_table, from_field, to_field, ref_value, operator): + # Select label of the field + to_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (to_table, to_field)) + from_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (from_table, from_field)) + + op_in_words = {'=':'equal to ', '>=':'greater than equal to ', '>':'greater than ', '<=':'less than equal to ', '<':'less than '} + msgprint(to_fld_label[0][0] + " should be " + op_in_words[operator] + from_fld_label[0][0] + " of " + self.doc.from_doctype + ": " + self.ref_doc) + raise Exception, "Validation Error." + + def check_ref_docstatus(self): + if self.ref_doc: + det = sql("select name, docstatus from `tab%s` where name = '%s'" % (self.doc.from_doctype, self.ref_doc)) + if not det: + msgprint(self.doc.from_doctype + ": " + self.ref_doc + " does not exists in the system") + raise Exception, "Validation Error." + elif self.doc.ref_doc_submitted and det[0][1] != 1: + msgprint(self.doc.from_doctype + ": " + self.ref_doc + " is not Submitted Document.") + raise Exception, "Validation Error." + + def on_update(self): + import webnotes.defs + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + from webnotes.modules.export_module import export_to_files + export_to_files(record_list=[[self.doc.doctype, self.doc.name]]) + diff --git a/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt new file mode 100644 index 0000000000..e9f4cb67b5 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt @@ -0,0 +1,311 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:08:59', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': None, + 'max_attachments': None, + 'menu_index': 12, + 'modified': '2010-12-16 18:13:25', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocType Mapper', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 10 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-08-08 17:08:59', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-08-08 17:08:59', + 'modified_by': 'Administrator', + 'name': '_PERM00192', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-08-08 17:08:59', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 2, + 'match': None, + 'modified': '2010-08-08 17:08:59', + 'modified_by': 'Administrator', + 'name': '_PERM00193', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01049', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Select', + 'options': 'link:Module Def', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'from_doctype', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'From DocType', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01050', + 'no_copy': 1, + 'oldfieldname': 'from_doctype', + 'oldfieldtype': 'Select', + 'options': 'link:DocType', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'to_doctype', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'To DocType', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01051', + 'no_copy': 1, + 'oldfieldname': 'to_doctype', + 'oldfieldtype': 'Select', + 'options': 'link:DocType', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'ref_doc_submitted', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Ref Doc should be submitted?', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01052', + 'no_copy': None, + 'oldfieldname': 'ref_doc_submitted', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'nabin@webnotestech.com', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'field_mapper_details', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Field Mapper Details', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01053', + 'no_copy': None, + 'oldfieldname': 'field_mapper_details', + 'oldfieldtype': 'Table', + 'options': 'Field Mapper Detail', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'table_mapper_details', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Table Mapper Details', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01054', + 'no_copy': None, + 'oldfieldname': 'table_mapper_details', + 'oldfieldtype': 'Table', + 'options': 'Table Mapper Detail', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/event/__init__.py b/cgi-bin/core/doctype/event/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/event/event.txt b/cgi-bin/core/doctype/event/event.txt new file mode 100644 index 0000000000..298210b1c9 --- /dev/null +++ b/cgi-bin/core/doctype/event/event.txt @@ -0,0 +1,603 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'EV.#####', + 'change_log': None, + 'client_script': "cur_frm.cscript.onload = function(doc, cdt, cdn) {\n var df = get_field('Event', 'Intro HTML', doc.name);\n if(doc.ref_type) {\n ref = repl(cur_frm.cstring.ref_html, {'dt': doc.ref_type, 'dn':doc.ref_name});\n } else var ref = '';\n \n df.options = repl(cur_frm.cstring.intro_html, {'ref': ref});\n refresh_fields('Intro HTML');\n}", + 'client_script_core': None, + 'client_string': '---intro_html---\n\n
\n %(ref)s\n Go To Calendar\n
\n\n---ref_html---\n\nReference : %(dn)s

', + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': 1, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Event', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 1, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tabbed', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': 'owner', + 'modified': '2009-05-12 11:19:22', + 'modified_by': 'Administrator', + 'name': '_PERM00006', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'All', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Details', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00117', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Intro HTML', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00118', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'HTML', + 'options': '', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_date', + 'fieldtype': 'Date', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Event Date', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00119', + 'no_copy': None, + 'oldfieldname': 'event_date', + 'oldfieldtype': 'Date', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_hour', + 'fieldtype': 'Time', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Event Time', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00120', + 'no_copy': None, + 'oldfieldname': 'event_hour', + 'oldfieldtype': 'Time', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 22:44:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_name', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Event', + 'modified': '2010-11-30 22:44:59', + 'modified_by': 'Administrator', + 'name': '_FL03481', + 'no_copy': None, + 'oldfieldname': 'event_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Description', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00121', + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'notes', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Notes', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00122', + 'no_copy': None, + 'oldfieldname': 'notes', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Event Type', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00123', + 'no_copy': None, + 'oldfieldname': 'event_type', + 'oldfieldtype': 'Select', + 'options': 'Private\nPublic\nCancel', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Participants', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00124', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Individuals', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00125', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_individuals', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Event Individuals', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00126', + 'no_copy': None, + 'oldfieldname': 'event_individuals', + 'oldfieldtype': 'Table', + 'options': 'Event User', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Groups', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00127', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_roles', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Event Roles', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00128', + 'no_copy': None, + 'oldfieldname': 'event_roles', + 'oldfieldtype': 'Table', + 'options': 'Event Role', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'ref_type', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Ref Type', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00129', + 'no_copy': None, + 'oldfieldname': 'ref_type', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'ref_name', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Ref Name', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00130', + 'no_copy': None, + 'oldfieldname': 'ref_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/event_role/__init__.py b/cgi-bin/core/doctype/event_role/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/event_role/event_role.txt b/cgi-bin/core/doctype/event_role/event_role.txt new file mode 100644 index 0000000000..10c0de2c68 --- /dev/null +++ b/cgi-bin/core/doctype/event_role/event_role.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': '__EVR.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Event Role', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00131', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Event Role', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/event_user/__init__.py b/cgi-bin/core/doctype/event_user/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/event_user/event_user.txt b/cgi-bin/core/doctype/event_user/event_user.txt new file mode 100644 index 0000000000..54bba6a6de --- /dev/null +++ b/cgi-bin/core/doctype/event_user/event_user.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'EVP.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Event User', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'person', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Person', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00132', + 'no_copy': None, + 'oldfieldname': 'person', + 'oldfieldtype': 'Select', + 'options': 'link:Profile', + 'owner': 'Administrator', + 'parent': 'Event User', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/field_mapper_detail/__init__.py b/cgi-bin/core/doctype/field_mapper_detail/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt b/cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt new file mode 100644 index 0000000000..1ec71d3d37 --- /dev/null +++ b/cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt @@ -0,0 +1,230 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'FMD/.#####', + 'change_log': None, + 'client_script': '', + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-11-30 17:30:01', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Field Mapper Detail', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tray', + 'server_code': '', + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': '', + 'use_template': None, + 'version': 10 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'from_field', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'From Field', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00503', + 'no_copy': None, + 'oldfieldname': 'from_field', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '180px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'to_field', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'To Field', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00504', + 'no_copy': None, + 'oldfieldname': 'to_field', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '180px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'match_id', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Match Id', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00505', + 'no_copy': None, + 'oldfieldname': 'match_id', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'map', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Map', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00506', + 'no_copy': None, + 'oldfieldname': 'map', + 'oldfieldtype': 'Select', + 'options': 'Yes\nNo', + 'owner': 'nabin@webnotestech.com', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'checking_operator', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Checking Operator (To Fld, Operator, From Fld)', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00507', + 'no_copy': None, + 'oldfieldname': 'checking_operator', + 'oldfieldtype': 'Select', + 'options': '\n=\n>\n>=\n<\n<=', + 'owner': 'nabin@webnotestech.com', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '180px' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/file_data/__init__.py b/cgi-bin/core/doctype/file_data/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/file_data/file_data.txt b/cgi-bin/core/doctype/file_data/file_data.txt new file mode 100644 index 0000000000..1a7bcd945a --- /dev/null +++ b/cgi-bin/core/doctype/file_data/file_data.txt @@ -0,0 +1,125 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'FileData/.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-12-01 13:35:53', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'File Data', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': 'file_name', + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'File Name', + 'modified': '2010-12-01 13:35:53', + 'modified_by': 'Administrator', + 'name': '_FL00133', + 'no_copy': None, + 'oldfieldname': 'file_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'File Data', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-01 13:35:53', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Module', + 'modified': '2010-12-01 13:35:53', + 'modified_by': 'Administrator', + 'name': '_FL03754', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Link', + 'options': 'Module Def', + 'owner': 'Administrator', + 'parent': 'File Data', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/letter_head/__init__.py b/cgi-bin/core/doctype/letter_head/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/letter_head/letter_head.js b/cgi-bin/core/doctype/letter_head/letter_head.js new file mode 100644 index 0000000000..24ddcca23e --- /dev/null +++ b/cgi-bin/core/doctype/letter_head/letter_head.js @@ -0,0 +1,26 @@ +cur_frm.cscript.validate = function(doc, dt, dn) { + return 1; +} + +cur_frm.cscript['Set From Image'] = function(doc, dt, dn) { + if(!doc.file_list) { + msgprint('Please attach an image file first'); + return; + } + if(doc.content) { + if(!confirm('Are you sure you want to overwrite the existing HTML?')) + return; + } + + var file_name = doc.file_list.split(',')[0] + + if(!in_list(['gif','jpg','jpeg','png'], file_name.split('.')[1].toLowerCase())) { + msgprint("Please upload a web friendly (GIF, JPG or PNG) image file for the letter head"); + return; + } + + img_link = '
' + + doc.content = img_link; + refresh_field('content'); +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/letter_head/letter_head.py b/cgi-bin/core/doctype/letter_head/letter_head.py new file mode 100755 index 0000000000..4e64b69d11 --- /dev/null +++ b/cgi-bin/core/doctype/letter_head/letter_head.py @@ -0,0 +1,31 @@ +# Please edit this list and import only required elements +import webnotes +from webnotes import msgprint + +sql = webnotes.conn.sql + +class DocType: + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + + # + # on update + # + def on_update(self): + # clear the cache so that the new letter head is uploaded + sql("delete from __SessionCache") + + self.set_as_default() + + # + # this is default, un-set everyone else + # + def set_as_default(self): + from webnotes.utils import set_default + if self.doc.is_default: + sql("update `tabLetter Head` set is_default=0 where name != %s", self.doc.name) + set_default('letter_head', self.doc.name) + + # update control panel - so it loads new letter directly + webnotes.conn.set_value('Control Panel', None, 'letter_head', self.doc.content) \ No newline at end of file diff --git a/cgi-bin/core/doctype/letter_head/letter_head.txt b/cgi-bin/core/doctype/letter_head/letter_head.txt new file mode 100644 index 0000000000..a7c3d8b3f5 --- /dev/null +++ b/cgi-bin/core/doctype/letter_head/letter_head.txt @@ -0,0 +1,324 @@ +[ + { + '_last_update': None, + 'allow_attach': 1, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:letter_head_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-12-14 10:32:59', + 'description': 'Create a Letter Head for Print Formats. The letter head must be in HTML.\nYou can also set the letter head from an attachment.\nIf you click on "Set from Image" then, the HTML Content will be overwritten.', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': 3, + 'menu_index': None, + 'modified': '2011-04-14 10:25:09', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Letter Head', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 11 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-12-14 10:32:59', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-12-14 10:32:59', + 'modified_by': 'Administrator', + 'name': '_PERM00735', + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'letter_head_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': 0, + 'label': 'Letter Head Name', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04150', + 'no_copy': None, + 'oldfieldname': 'letter_head_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'disabled', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Disabled', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04151', + 'no_copy': None, + 'oldfieldname': 'disabled', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-21 18:32:42', + 'default': None, + 'depends_on': None, + 'description': 'Check this to make this the default letter head in all prints', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'is_default', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Is Default', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04428', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 10:50:46', + 'default': None, + 'depends_on': None, + 'description': 'To update your HTML from attachment, click here', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'set_from_image', + 'fieldtype': 'Button', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Set From Image', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '000000156', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': 'Your letter head content in HTML.', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'content', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Content', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04152', + 'no_copy': None, + 'oldfieldname': 'content', + 'oldfieldtype': 'Text Editor', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 10:50:46', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'url', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'URL', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '000000157', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_list', + 'fieldtype': 'Text', + 'hidden': 1, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'File LIst', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04153', + 'no_copy': None, + 'oldfieldname': 'file_list', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def/__init__.py b/cgi-bin/core/doctype/module_def/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/module_def/module_def.py b/cgi-bin/core/doctype/module_def/module_def.py new file mode 100644 index 0000000000..6a13a6dbca --- /dev/null +++ b/cgi-bin/core/doctype/module_def/module_def.py @@ -0,0 +1,50 @@ +# Please edit this list and import only required elements +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.doclist import getlist, copy_doclist +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 + +set = webnotes.conn.set +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value +in_transaction = webnotes.conn.in_transaction +convert_to_lists = webnotes.conn.convert_to_lists + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self,d,dl): + self.doc, self.doclist = d,dl + + def on_update(self): + if not getlist(self.doclist,'items') and not self.doc.widget_code: + obj = Document(self.doc.doctype, self.doc.name) + + doc_type = [['DocType','name','name','Forms',"(istable is null or istable=0) and (issingle is null or issingle=0)"],['Page','name','page_name','Pages','(show_in_menu=1 or show_in_menu=0)'],['Search Criteria','doc_type','criteria_name','Reports',"(disabled is null or disabled=0)"]] + for dt in doc_type: + dn = [[d[0] or '', d[1] or ''] for d in sql("select %s,%s from `tab%s` where module = '%s' and %s" % (dt[1],dt[2],dt[0],self.doc.name,dt[4]))] + + if dn: + r = addchild(obj,'items','Module Def Item',1) + r.doc_type = 'Separator' + r.doc_name = dt[3] + r.save(1) + + for d in dn: + r = addchild(obj,'items','Module Def Item',1) + r.doc_type = dt[3] + r.doc_name = d[0] + r.display_name = d[1] + r.save(1) + + def on_update(self): + import webnotes.defs + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + from webnotes.modules.export_module import export_to_files + export_to_files(record_list=[[self.doc.doctype, self.doc.name]]) + \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def/module_def.txt b/cgi-bin/core/doctype/module_def/module_def.txt new file mode 100644 index 0000000000..427e32426e --- /dev/null +++ b/cgi-bin/core/doctype/module_def/module_def.txt @@ -0,0 +1,708 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:module_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-27 11:16:33', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Module Def', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': 'doctype_list', + 'section_style': 'Tray', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-08-08 17:16:13', + 'modified_by': 'Administrator', + 'name': '_PERM00007', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'trash_reason', + 'fieldtype': 'Small Text', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Trash Reason', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL01996', + 'no_copy': None, + 'oldfieldname': 'trash_reason', + 'oldfieldtype': 'Small Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 1, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Module Details', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000462', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'disabled', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Disabled', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL01998', + 'no_copy': None, + 'oldfieldname': 'disabled', + 'oldfieldtype': 'Select', + 'options': 'No\nYes', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Module Name', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL00135', + 'no_copy': None, + 'oldfieldname': 'module_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_label', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Module Label', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL01999', + 'no_copy': None, + 'oldfieldname': 'module_label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doctype_list', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'DocType List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL00136', + 'no_copy': None, + 'oldfieldname': 'doctype_list', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_page', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Module Page', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02000', + 'no_copy': None, + 'oldfieldname': 'module_page', + 'oldfieldtype': 'Link', + 'options': 'Page', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_desc', + 'fieldtype': 'Text Editor', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Module Description', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02001', + 'no_copy': None, + 'oldfieldname': 'module_desc', + 'oldfieldtype': 'Text Editor', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_icon', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Module Icon', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02002', + 'no_copy': None, + 'oldfieldname': 'module_icon', + 'oldfieldtype': 'Select', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_seq', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': 1, + 'label': 'Module Sequence', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02003', + 'no_copy': None, + 'oldfieldname': 'module_seq', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Item List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000463', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'items', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Items', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02005', + 'no_copy': None, + 'oldfieldname': 'items', + 'oldfieldtype': 'Table', + 'options': 'Module Def Item', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Role List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000464', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'roles', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Roles', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02007', + 'no_copy': None, + 'oldfieldname': 'roles', + 'oldfieldtype': 'Table', + 'options': 'Module Def Role', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_list', + 'fieldtype': 'Text', + 'hidden': 1, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'File List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02008', + 'no_copy': None, + 'oldfieldname': 'file_list', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': 1, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Widget Script', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000465', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'widget_code', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Widget Code', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02010', + 'no_copy': None, + 'oldfieldname': 'widget_code', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-01 19:01:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'is_hidden', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Is Hidden', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL03943', + 'no_copy': None, + 'oldfieldname': 'is_hidden', + 'oldfieldtype': 'Select', + 'options': 'No\nYes', + 'owner': 'yogesh@webnotestech.com', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def_item/__init__.py b/cgi-bin/core/doctype/module_def_item/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/module_def_item/module_def_item.txt b/cgi-bin/core/doctype/module_def_item/module_def_item.txt new file mode 100644 index 0000000000..2c3244e627 --- /dev/null +++ b/cgi-bin/core/doctype/module_def_item/module_def_item.txt @@ -0,0 +1,335 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'MDI.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:09:10', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:42:16', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Module Def Item', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 21 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Doc Type', + 'modified': '2011-04-05 10:01:39', + 'modified_by': 'Administrator', + 'name': '_FL02011', + 'no_copy': None, + 'oldfieldname': 'doc_type', + 'oldfieldtype': 'Select', + 'options': 'Forms\nPages\nReports\nSeparator\nMore Reports\nSetup Forms\nSetup Pages\nSingle DocType', + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Doc Name', + 'modified': '2011-04-05 10:01:39', + 'modified_by': 'Administrator', + 'name': '_FL02012', + 'no_copy': None, + 'oldfieldname': 'doc_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'display_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Display Name', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02013', + 'no_copy': None, + 'oldfieldname': 'display_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'icon', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Icon', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02014', + 'no_copy': None, + 'oldfieldname': 'icon', + 'oldfieldtype': 'Select', + 'options': '\naccept.gif\nadd.gif\napplication.gif\narrow_down.gif\narrow_left.gif\narrow_right.gif\narrow_up.gif\ncalculator.gif\ncalendar.gif\ncancel.gif\nchart_bar.gif\nclose.gif\ncomments.gif\ndisk.gif\ndown-arrow.gif\nemail.gif\nerror.gif\nfolder.gif\ngroup.gif\nhelp.gif\nicon-recommend.gif\nlightbulb.gif\nmagnifier.gif\nminus.gif\nnote.gif\npage.gif\npage_add.gif\npage_copy.gif\npage_excel.gif\npage_refresh.gif\npaperclip.gif\nplus.gif\nprinter.gif\nresultset_first.gif\nresultset_last.gif\nresultset_next.gif\nresultset_previous.gif\nsort_asc.gif\nsort_desc.gif\nstar.gif\ntable.gif\ntable_row_delete.gif\ntable_row_insert.gif\nuser.gif\nwrench.gif', + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02015', + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fields', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Fields', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02016', + 'no_copy': None, + 'oldfieldname': 'fields', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-04 17:46:19', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'click_function', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Click Function', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL03944', + 'no_copy': None, + 'oldfieldname': 'click_function', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'harshada@webnotestech.com', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-24 17:46:27', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Hide', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL04430', + 'no_copy': None, + 'oldfieldname': 'hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def_role/__init__.py b/cgi-bin/core/doctype/module_def_role/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/module_def_role/module_def_role.txt b/cgi-bin/core/doctype/module_def_role/module_def_role.txt new file mode 100644 index 0000000000..f0e2461ca4 --- /dev/null +++ b/cgi-bin/core/doctype/module_def_role/module_def_role.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'MDR.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:09:10', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:42:16', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Module Def Role', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02017', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Module Def Role', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/page/__init__.py b/cgi-bin/core/doctype/page/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/page/page.py b/cgi-bin/core/doctype/page/page.py new file mode 100644 index 0000000000..5e2b873b99 --- /dev/null +++ b/cgi-bin/core/doctype/page/page.py @@ -0,0 +1,49 @@ +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d,dl + + def autoname(self): + if (self.doc.name and self.doc.name.startswith('New Page')) or not self.doc.name: + self.doc.name = self.doc.page_name.lower().replace(' ', '-') + + def onload(self): + import os + from webnotes.modules import get_module_path, scrub + + # load content + try: + file = open(os.path.join(get_module_path(self.doc.module), 'page', scrub(self.doc.name) + '.html'), 'r') + self.doc.content = file.read() or '' + file.close() + except IOError, e: # no file / permission + if e.args[0]!=2: + raise e + + # replace $image + # ------------------ + def validate(self): + import re + p = re.compile('\$image\( (?P [^)]*) \)', re.VERBOSE) + if self.doc.content: + self.doc.content = p.sub(self.replace_by_img, self.doc.content) + + def replace_by_img(self, match): + import webnotes + name = match.group('name') + return '' % (webnotes.conn.get('Control Panel', None, 'account_id'), name) + + # export + def on_update(self): + from webnotes.modules.export_module import export_to_files + from webnotes.modules import get_module_path, scrub + import os + from webnotes import defs + + if getattr(defs,'developer_mode', 0): + export_to_files(record_list=[['Page', self.doc.name]]) + + if self.doc.write_content and self.doc.content: + file = open(os.path.join(get_module_path(self.doc.module), 'page', scrub(self.doc.name), scrub(self.doc.name) + '.html'), 'w') + file.write(self.doc.content) + file.close() + diff --git a/cgi-bin/core/doctype/page/page.txt b/cgi-bin/core/doctype/page/page.txt new file mode 100644 index 0000000000..9d906d1bc2 --- /dev/null +++ b/cgi-bin/core/doctype/page/page.txt @@ -0,0 +1,1023 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:page_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:43:43', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Page', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tabbed', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 7 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': '', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_PERM00008', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Page HTML', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000429', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 10:51:29', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'page_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Page Name', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00353', + 'no_copy': None, + 'oldfieldname': 'page_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-30 16:18:42', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00291', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Select', + 'options': 'link:Module Def', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'template', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Template', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000415', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Page Template', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'stylesheet', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Stylesheet', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000416', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Stylesheet', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:22:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'standard', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Standard', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00319', + 'no_copy': None, + 'oldfieldname': 'standard', + 'oldfieldtype': 'Select', + 'options': '\nYes\nNo', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': None, + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000430', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'author', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Author', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000418', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'category', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Category', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000419', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': '\nStandard\nBlog', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'publish', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Publish', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000420', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'page_title', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Page Title', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000421', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:22:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'style', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Style', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00321', + 'no_copy': None, + 'oldfieldname': 'style', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'keywords', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Keywords', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000422', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'site_description', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Site Description', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000423', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:22:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'static_content', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Static Content', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00323', + 'no_copy': None, + 'oldfieldname': 'static_content', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Page Content', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000431', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'write_content', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Write Content', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000425', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'show_in_menu', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Show In Start', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00145', + 'no_copy': None, + 'oldfieldname': 'show_in_menu', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'content', + 'fieldtype': 'Text Editor', + 'hidden': 0, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Content', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00138', + 'no_copy': None, + 'oldfieldname': 'content', + 'oldfieldtype': 'Text Editor', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'parent_node', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Parent Node', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00395', + 'no_copy': None, + 'oldfieldname': 'parent_node', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'icon', + 'fieldtype': 'Select', + 'hidden': 1, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Icon', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00397', + 'no_copy': None, + 'oldfieldname': 'icon', + 'oldfieldtype': 'Select', + 'options': '\naccept.png\nadd.png\napplication.png\nbell.png\nbox.png\ncalendar.png\ncalculator.png\ncancel.png\ncart.png\ncd.png\nchart_bar.png\nclock.png\ncoins.png\ncomputer.png\ncontroller.png\ndisk.png\nemail.png\nerror.png\nfolder.png\ngroup.png\nhouse.png\nimages.png\nlock_open.png\nlock.png\nlorry.png\nmagnifier.png\nmap.png\nmoney.png\nnew.png\npage.png\nprinter.png\nreport.png\nserver.png\nshield.png\ntable.png\nuser.png', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': 'Image List', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000432', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': 'Page Script', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000433', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'script', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 24, + 'in_filter': None, + 'label': 'Script', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00140', + 'no_copy': None, + 'oldfieldname': 'script', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_list', + 'fieldtype': 'Text', + 'hidden': 1, + 'icon': None, + 'idx': 25, + 'in_filter': None, + 'label': 'File List', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000428', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'menu_index', + 'fieldtype': 'Int', + 'hidden': 1, + 'icon': None, + 'idx': 26, + 'in_filter': None, + 'label': 'Menu Index', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00398', + 'no_copy': None, + 'oldfieldname': 'menu_index', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'roles', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 27, + 'in_filter': None, + 'label': 'Roles', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00143', + 'no_copy': None, + 'oldfieldname': 'roles', + 'oldfieldtype': 'Table', + 'options': 'Page Role', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/page_role/__init__.py b/cgi-bin/core/doctype/page_role/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/page_role/page_role.txt b/cgi-bin/core/doctype/page_role/page_role.txt new file mode 100644 index 0000000000..41322d430f --- /dev/null +++ b/cgi-bin/core/doctype/page_role/page_role.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'PR.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Page Role', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': None, + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00151', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Page Role', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/page_template/__init__.py b/cgi-bin/core/doctype/page_template/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/page_template/page_template.py b/cgi-bin/core/doctype/page_template/page_template.py new file mode 100644 index 0000000000..550367e5df --- /dev/null +++ b/cgi-bin/core/doctype/page_template/page_template.py @@ -0,0 +1,20 @@ +import webnotes + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d,dl + + # export + def on_update(self): + import webnotes.defs + from webnotes.modules.export_module import export_to_files + from webnotes.modules import get_module_path, scrub + import os + + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + + export_to_files(record_list=[['Page Template', self.doc.name]]) + + file = open(os.path.join(get_module_path(self.doc.module), 'Page Template', self.doc.name, self.doc.name + '.html'), 'w') + file.write(self.doc.content) + file.close() \ No newline at end of file diff --git a/cgi-bin/core/doctype/page_template/page_template.txt b/cgi-bin/core/doctype/page_template/page_template.txt new file mode 100644 index 0000000000..a1b0bfc577 --- /dev/null +++ b/cgi-bin/core/doctype/page_template/page_template.txt @@ -0,0 +1,160 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:template_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2011-04-05 10:01:43', + 'description': 'Page Template is used in the CMS. In Page, if you select a template, the page appears within the template.\n\nNote: The template must have a "%(content)s" for string replacement and all % must be %%!\n\nIn developer_mode, the template is saved to the file system. ', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:10:06', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Page Template', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': 6 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'template_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Template Name', + 'modified': '2011-04-05 10:01:43', + 'modified_by': 'Administrator', + 'name': '000000434', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page Template', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-04-05 10:01:43', + 'modified_by': 'Administrator', + 'name': '000000435', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Module Def', + 'owner': 'Administrator', + 'parent': 'Page Template', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'template', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Template', + 'modified': '2011-04-05 10:01:43', + 'modified_by': 'Administrator', + 'name': '000000436', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page Template', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/print_format/__init__.py b/cgi-bin/core/doctype/print_format/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/print_format/print_format.txt b/cgi-bin/core/doctype/print_format/print_format.txt new file mode 100644 index 0000000000..8794c48e60 --- /dev/null +++ b/cgi-bin/core/doctype/print_format/print_format.txt @@ -0,0 +1,183 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'Prompt', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Print Format', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 3 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': '', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_PERM00009', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-30 16:22:31', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Module', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_FL00293', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Select', + 'options': 'link:Module Def', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': '' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'html', + 'fieldtype': 'Text Editor', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'HTML', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_FL00152', + 'no_copy': None, + 'oldfieldname': 'html', + 'oldfieldtype': 'Text Editor', + 'options': '', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:21:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'standard', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Standard', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_FL00318', + 'no_copy': None, + 'oldfieldname': 'standard', + 'oldfieldtype': 'Select', + 'options': '\nYes\nNo', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/profile/__init__.py b/cgi-bin/core/doctype/profile/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/profile/profile.js b/cgi-bin/core/doctype/profile/profile.js new file mode 100644 index 0000000000..b392a3a160 --- /dev/null +++ b/cgi-bin/core/doctype/profile/profile.js @@ -0,0 +1,26 @@ +cur_frm.cscript['Change Password']= function(doc, cdt, cdn) { + var error = false; + if ((!doc.new_password)||(!doc.retype_new_password)){ + alert("Both fields are required!"); + error = true; + } + if (doc.new_password.length<4) { + alert("Password must be atleast 4 characters long"); + error = true; + } + if(doc.new_password!=doc.retype_new_password) { + alert("Passwords must match"); + error = true; + } + if(!error) { + cur_frm.runscript('update_password', '', function(r,t) { + doc.new_password = ''; + doc.retype_new_password = ''; + }); + } +} + +cur_frm.cscript.validate = function(doc, cdt, cdn) { + doc.new_password = ''; + doc.retype_new_password = ''; +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/profile/profile.py b/cgi-bin/core/doctype/profile/profile.py new file mode 100644 index 0000000000..60388f039f --- /dev/null +++ b/cgi-bin/core/doctype/profile/profile.py @@ -0,0 +1,48 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes import msgprint + +sql = webnotes.conn.sql + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc, doclist): + self.doc = doc + self.doclist = doclist + + # Autoname is Email id + # -------------------- + + def autoname(self): + import re + from webnotes.utils import validate_email_add + + self.doc.email = self.doc.email.strip() + if self.doc.name not in ('Guest','Administrator'): + if not validate_email_add(self.doc.email): + msgprint("%s is not a valid email id" % self.doc.email) + raise Exception + self.doc.name = self.doc.email + + def on_update(self): + # owner is always name + if not self.doc.password: + webnotes.conn.set(self.doc, 'password' ,'password') + webnotes.conn.set(self.doc, 'owner' ,self.doc.name) + + + def update_password(self): + from webnotes.utils.email_lib import sendmail + s + sql("UPDATE `tabProfile` SET password=PASSWORD(%s) where name=%s", (self.doc.new_password, self.doc.name)) + email_text = '''%s, + +Your password has been changed. + +- Administrator +''' % self.doc.name + sendmail([self.doc.email], subject='Change of Password Notification', parts = [('text/plain', email_text)]) + msgprint("Your password has been changed") diff --git a/cgi-bin/core/doctype/profile/profile.txt b/cgi-bin/core/doctype/profile/profile.txt new file mode 100644 index 0000000000..7fe575fead --- /dev/null +++ b/cgi-bin/core/doctype/profile/profile.txt @@ -0,0 +1,2003 @@ +[ + { + '_last_update': None, + 'allow_attach': 1, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': 'cur_frm.cscript[\'Change Password\']= function(doc, cdt, cdn) {\n var error = false;\n if ((!doc.new_password)||(!doc.retype_new_password)){\n alert("Both fields are required!");\n error = true;\n }\n if (doc.new_password.length<4) {\n alert("Password must be atleast 4 characters long");\n error = true;\n }\n if(doc.new_password!=doc.retype_new_password) {\n alert("Passwords must match");\n error = true;\n }\n if(!/[A-Z]/.test(doc.new_password) || !/[0-9]/.test(doc.new_password) || !/[\\W_]/.test(doc.new_password)) {\n msgprint(\'New password must contain atleast 1 capital letter, 1 numeric and 1 special character.\');\n error = true;\n doc.new_password = \'\';\n refresh_field(\'new_password\');\n }\n if(!error) {\n cur_frm.runscript(\'update_password\', \'\', function(r,t) {\n\tdoc.new_password = \'\';\n\tdoc.retype_new_password = \'\';\n refresh_many([\'new_password\',\'retype_new_password\']);\n });\n }\n}\n\ncur_frm.cscript.validate = function(doc, cdt, cdn) {\n doc.new_password = \'\';\n doc.retype_new_password = \'\';\n}', + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': 'Defines the various users of the system.\n\nUse default values table to enable automatic form filling.', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': 1, + 'menu_index': None, + 'modified': '2011-04-21 14:09:06', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Profile', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': 'Yes', + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': 'first_name, last_name', + 'section_style': 'Tray', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': '
',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 30
+	},
+	{
+		'amend': None,
+		'cancel': 0,
+		'create': 1,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': 0,
+		'idx': 1,
+		'match': None,
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00010',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': 0,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': 1,
+		'creation': '2010-08-08 16:47:35',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00039',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'System Manager',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 3,
+		'match': None,
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00011',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 4,
+		'match': 'owner',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00013',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'All',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': 0,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Details',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000444',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': 0,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Picture',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000445',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Column Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Image',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Profile Picture',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00155',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Image',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Contact',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000446',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Column Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': '1',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'enabled',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Enabled',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00157',
+		'no_copy': None,
+		'oldfieldname': 'enabled',
+		'oldfieldtype': 'Check',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'registered',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': 'Registered',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000437',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': '1',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'send_email_invite',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': None,
+		'label': 'Send Email Invite',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00158',
+		'no_copy': None,
+		'oldfieldname': 'send_email_invite',
+		'oldfieldtype': 'Check',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': 'System Manager',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'escalates_to',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 8,
+		'in_filter': None,
+		'label': 'Escalates to',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00159',
+		'no_copy': None,
+		'oldfieldname': 'escalates_to',
+		'oldfieldtype': 'Link',
+		'options': 'Profile',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'unsubscribed',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 9,
+		'in_filter': None,
+		'label': 'Unsubscribed',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000438',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'invited',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 10,
+		'in_filter': None,
+		'label': 'Invited',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000439',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'reg_id',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 11,
+		'in_filter': None,
+		'label': 'Reg ID',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000440',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'campaign',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 12,
+		'in_filter': None,
+		'label': 'Campaign',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000441',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'billing_currency',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 13,
+		'in_filter': None,
+		'label': 'Billing Currency',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000442',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': 'INR\nUSD',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'recent_documents',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 14,
+		'in_filter': None,
+		'label': 'Recent Documents',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00160',
+		'no_copy': None,
+		'oldfieldname': 'recent_documents',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'first_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 15,
+		'in_filter': None,
+		'label': 'First Name',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00161',
+		'no_copy': None,
+		'oldfieldname': 'first_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'gender',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 16,
+		'in_filter': None,
+		'label': 'Gender',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02339',
+		'no_copy': None,
+		'oldfieldname': 'gender',
+		'oldfieldtype': 'Select',
+		'options': '\nMale\nFemale',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'middle_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 17,
+		'in_filter': None,
+		'label': 'Middle Name (Optional)',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00162',
+		'no_copy': None,
+		'oldfieldname': 'middle_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'last_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 18,
+		'in_filter': None,
+		'label': 'Last Name',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00163',
+		'no_copy': None,
+		'oldfieldname': 'last_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'occupation',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 19,
+		'in_filter': None,
+		'label': 'Designation',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02340',
+		'no_copy': None,
+		'oldfieldname': 'occupation',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'bio',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 20,
+		'in_filter': None,
+		'label': 'Bio',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02341',
+		'no_copy': None,
+		'oldfieldname': 'bio',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'email',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 21,
+		'in_filter': None,
+		'label': 'Email',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00164',
+		'no_copy': None,
+		'oldfieldname': 'email',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-12-14 10:33:01',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'interests',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 22,
+		'in_filter': None,
+		'label': 'Interests',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL04167',
+		'no_copy': None,
+		'oldfieldname': 'interests',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-01 14:13:42',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'birth_date',
+		'fieldtype': 'Date',
+		'hidden': None,
+		'icon': None,
+		'idx': 23,
+		'in_filter': None,
+		'label': 'Birth Date',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00294',
+		'no_copy': None,
+		'oldfieldname': 'birth_date',
+		'oldfieldtype': 'Date',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'home_phone',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 24,
+		'in_filter': None,
+		'label': 'Home Phone',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00165',
+		'no_copy': None,
+		'oldfieldname': 'home_phone',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-12-14 10:33:01',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'activities',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 25,
+		'in_filter': None,
+		'label': 'Activities',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL04168',
+		'no_copy': None,
+		'oldfieldname': 'activities',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'messanger_status',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 26,
+		'in_filter': None,
+		'label': 'Messanger Status',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02342',
+		'no_copy': None,
+		'oldfieldname': 'messanger_status',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'office_phone',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 27,
+		'in_filter': None,
+		'label': 'Office Phone',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00166',
+		'no_copy': None,
+		'oldfieldname': 'office_phone',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'extension',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 28,
+		'in_filter': None,
+		'label': 'Extension',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00167',
+		'no_copy': None,
+		'oldfieldname': 'extension',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'cell_no',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 29,
+		'in_filter': None,
+		'label': 'Cell No',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00168',
+		'no_copy': None,
+		'oldfieldname': 'cell_no',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-09-23 16:21:48',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'user_type',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 30,
+		'in_filter': None,
+		'label': 'User Type',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00313',
+		'no_copy': None,
+		'oldfieldname': 'user_type',
+		'oldfieldtype': 'Select',
+		'options': '\nSystem User\nPartner',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'default_app',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 31,
+		'in_filter': None,
+		'label': 'Default App',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000443',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': 'Application',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'last_login',
+		'fieldtype': 'Read Only',
+		'hidden': 0,
+		'icon': None,
+		'idx': 32,
+		'in_filter': None,
+		'label': 'Last Login',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00169',
+		'no_copy': None,
+		'oldfieldname': 'last_login',
+		'oldfieldtype': 'Read Only',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'last_ip',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 33,
+		'in_filter': None,
+		'label': 'Last IP',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00170',
+		'no_copy': None,
+		'oldfieldname': 'last_ip',
+		'oldfieldtype': 'Read Only',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 34,
+		'in_filter': None,
+		'label': 'Address',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000447',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'line_1',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 35,
+		'in_filter': None,
+		'label': 'Line 1',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00172',
+		'no_copy': None,
+		'oldfieldname': 'line_1',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'line_2',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 36,
+		'in_filter': None,
+		'label': 'Line 2',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00173',
+		'no_copy': None,
+		'oldfieldname': 'line_2',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'city',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 37,
+		'in_filter': None,
+		'label': 'City / Town',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00174',
+		'no_copy': None,
+		'oldfieldname': 'city',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'district',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 38,
+		'in_filter': None,
+		'label': 'District',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00175',
+		'no_copy': None,
+		'oldfieldname': 'district',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'state',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 39,
+		'in_filter': None,
+		'label': 'State',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00176',
+		'no_copy': None,
+		'oldfieldname': 'state',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'country',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 40,
+		'in_filter': None,
+		'label': 'Country',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00177',
+		'no_copy': None,
+		'oldfieldname': 'country',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'pin',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 41,
+		'in_filter': None,
+		'label': 'Pin',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00178',
+		'no_copy': None,
+		'oldfieldname': 'pin',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': 0,
+		'icon': None,
+		'idx': 42,
+		'in_filter': None,
+		'label': 'Roles',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000448',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:12',
+		'default': 'Simple',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'userroles',
+		'fieldtype': 'Table',
+		'hidden': 0,
+		'icon': None,
+		'idx': 43,
+		'in_filter': None,
+		'label': 'User Roles',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00181',
+		'no_copy': None,
+		'oldfieldname': 'userroles',
+		'oldfieldtype': 'Table',
+		'options': 'UserRole',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 44,
+		'in_filter': None,
+		'label': 'System Defaults',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000449',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:12',
+		'default': 'Simple',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'defaults',
+		'fieldtype': 'Table',
+		'hidden': 0,
+		'icon': None,
+		'idx': 45,
+		'in_filter': None,
+		'label': 'Defaults',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00183',
+		'no_copy': None,
+		'oldfieldname': 'defaults',
+		'oldfieldtype': 'Table',
+		'options': 'DefaultValue',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 46,
+		'in_filter': None,
+		'label': 'Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000450',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'Pink:FEF2EA',
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'password',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'icon': None,
+		'idx': 47,
+		'in_filter': None,
+		'label': 'Current Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00186',
+		'no_copy': None,
+		'oldfieldname': 'password',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'new_password',
+		'fieldtype': 'Password',
+		'hidden': None,
+		'icon': None,
+		'idx': 48,
+		'in_filter': None,
+		'label': 'New Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00187',
+		'no_copy': None,
+		'oldfieldname': 'new_password',
+		'oldfieldtype': 'Password',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'retype_new_password',
+		'fieldtype': 'Password',
+		'hidden': None,
+		'icon': None,
+		'idx': 49,
+		'in_filter': None,
+		'label': 'Retype New Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00188',
+		'no_copy': None,
+		'oldfieldname': 'retype_new_password',
+		'oldfieldtype': 'Password',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-28 17:24:55',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'password_last_updated',
+		'fieldtype': 'Date',
+		'hidden': 1,
+		'icon': None,
+		'idx': 50,
+		'in_filter': None,
+		'label': 'Password Last Updated',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00242',
+		'no_copy': None,
+		'oldfieldname': 'password_last_updated',
+		'oldfieldtype': 'Date',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': 1,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Button',
+		'hidden': None,
+		'icon': None,
+		'idx': 51,
+		'in_filter': None,
+		'label': 'Change Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00189',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Button',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': 'Client',
+		'width': '120px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 52,
+		'in_filter': None,
+		'label': 'Change Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000451',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Column Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'file_list',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 53,
+		'in_filter': None,
+		'label': 'File List',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00192',
+		'no_copy': None,
+		'oldfieldname': 'file_list',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/property_setter/__init__.py b/cgi-bin/core/doctype/property_setter/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/property_setter/property_setter.comp.js b/cgi-bin/core/doctype/property_setter/property_setter.comp.js
new file mode 100644
index 0000000000..51bd2d5c9c
--- /dev/null
+++ b/cgi-bin/core/doctype/property_setter/property_setter.comp.js
@@ -0,0 +1,8 @@
+
+$.extend(cur_frm.cscript,{onload:function(doc,dt,dn){cur_frm.cscript.do_setup(doc);},doctype_or_field:function(doc,dt,dn){doc.doc_type=doc.select_item=doc.doc_name=doc.select_doctype='';refresh_many(['doc_type','select_item','doc_name','select_doctype'])},do_setup:function(doc){$c_obj([doc],'get_setup_data','',function(r,rt){var r=r.message;cur_frm.cscript.set_doctypes(r.doctypes);cur_frm.dt_properties={};cur_frm.df_properties={};for(var i=0;i%(property)s property of %(doc_type)s %(doc_name)s',
+		'tag_fields': 'property',
+		'use_template': None,
+		'version': 33
+	},
+	{
+		'amend': None,
+		'cancel': 1,
+		'create': 1,
+		'creation': '2011-05-05 11:58:33',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 1,
+		'match': None,
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000700',
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': 1,
+		'create': 1,
+		'creation': '2011-05-05 11:58:33',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000701',
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'System Manager',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-05 13:25:40',
+		'default': None,
+		'depends_on': 'eval:doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doctype_or_field',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'DocType or Field',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000704',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': '\nDocField\nDocType',
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 14:11:44',
+		'default': None,
+		'depends_on': 'eval:doc.doctype_or_field && doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'select_doctype',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Select DocType',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000706',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 13:09:45',
+		'default': None,
+		'depends_on': "eval:doc.doctype_or_field=='DocField' && doc.__islocal",
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'select_item',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Select Field',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000703',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': 0,
+		'colour': None,
+		'creation': '2011-05-06 17:22:25',
+		'default': None,
+		'depends_on': 'eval:doc.doctype_or_field && doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'select_property',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Select Property',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000708',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': 'doc_name',
+		'description': 'New value to be set',
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'value',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Set Value',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000699',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-05 16:26:47',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': None,
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000707',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doc_type',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': 0,
+		'label': 'DocType',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000695',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': "eval:doc.doctype_or_field=='DocField'",
+		'description': 'ID (name) of the entity whose property is to be set',
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doc_name',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 8,
+		'in_filter': 0,
+		'label': 'Field ID',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000696',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': 'eval:doc.doc_name && doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'property',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 9,
+		'in_filter': 0,
+		'label': 'Property',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000697',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 12:38:01',
+		'default': None,
+		'depends_on': 'doc_name',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'property_type',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 10,
+		'in_filter': None,
+		'label': 'Property Type',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000702',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': 'doc_name',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'default_value',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 11,
+		'in_filter': None,
+		'label': 'Default Value',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000698',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/role/__init__.py b/cgi-bin/core/doctype/role/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/role/role.txt b/cgi-bin/core/doctype/role/role.txt
new file mode 100644
index 0000000000..79a5d8ad59
--- /dev/null
+++ b/cgi-bin/core/doctype/role/role.txt
@@ -0,0 +1,183 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': 0,
+		'allow_email': 0,
+		'allow_print': 0,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'field:role_name',
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:11',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': 0,
+		'hide_toolbar': 0,
+		'idx': 0,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': 0,
+		'istable': 0,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2010-09-20 14:06:57',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Role',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': 0,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 1
+	},
+	{
+		'amend': None,
+		'cancel': 0,
+		'create': 1,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': 0,
+		'idx': 1,
+		'match': '',
+		'modified': '2009-06-30 16:20:34',
+		'modified_by': 'Administrator',
+		'name': '_PERM00014',
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': 0,
+		'write': 1
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-06-30 16:20:34',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'module',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Module',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00292',
+		'no_copy': None,
+		'oldfieldname': 'module',
+		'oldfieldtype': 'Select',
+		'options': 'link:Module Def',
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'role_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Role Name',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00193',
+		'no_copy': None,
+		'oldfieldname': 'role_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'defaults',
+		'fieldtype': 'Table',
+		'hidden': 0,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Defaults',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00194',
+		'no_copy': None,
+		'oldfieldname': 'defaults',
+		'oldfieldtype': 'Table',
+		'options': 'DefaultValue',
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/search_criteria/__init__.py b/cgi-bin/core/doctype/search_criteria/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/search_criteria/search_criteria.py b/cgi-bin/core/doctype/search_criteria/search_criteria.py
new file mode 100644
index 0000000000..2acbc16c3b
--- /dev/null
+++ b/cgi-bin/core/doctype/search_criteria/search_criteria.py
@@ -0,0 +1,71 @@
+# Please edit this list and import only required elements
+import webnotes
+from webnotes.utils import cint
+
+sql = webnotes.conn.sql
+
+	
+# -----------------------------------------------------------------------------------------
+
+class DocType:
+	def __init__(self,d,dl):
+		self.doc, self.doclist = d,dl
+
+	def autoname(self):
+		self.doc.name = self.doc.criteria_name.lower().replace('(','').replace(')', '')\
+			.replace('.','').replace(',','').replace('"', '').replace("'",'').replace(' ', '_')\
+			.replace('/', '-')
+		
+		# for duplicates
+		if sql("select name from `tabSearch Criteria` where name = %s", self.doc.name):
+			m = sql("select name from `tabSearch Criteria` where name like '%s%%' order by name desc limit 1" % self.doc.name)[0][0]
+			self.doc.name = self.doc.name + str(cint(m[-1]) + 1)
+
+	def set_module(self):
+		if not self.doc.module:
+			doctype_module = sql("select module from tabDocType where name = '%s'" % (self.doc.doc_type))
+			webnotes.conn.set(self.doc,'module',doctype_module and doctype_module[0][0] or 'NULL')
+
+	def on_update(self):
+		self.set_module()
+		self.export_doc()
+	
+	def export_doc(self):
+		# export
+		if self.doc.standard == 'Yes' and getattr(webnotes.defs, 'developer_mode', 0) == 1:
+			from webnotes.modules.export_module import export_to_files
+			export_to_files(record_list=[['Search Criteria', self.doc.name]])
+
+	# patch to rename search criteria from old style numerical to
+	# new style based on criteria name
+	def rename(self):
+		old_name = self.doc.name
+		
+		if not self.doc.module:
+			self.set_module()
+		
+		self.autoname()
+		sql("update `tabSearch Criteria` set name=%s where name=%s", (self.doc.name, old_name))
+		
+	def rename_export(self, old_name):
+				
+		# export the folders
+		self.export_doc()
+		import os, shutil
+		from webnotes.modules import get_module_path, scrub
+		
+		path = os.path.join(get_module_path(self.doc.module), 'search_criteria', scrub(old_name))
+		
+		# copy py/js files
+		self.copy_file(path, scrub(old_name), '.py')
+		self.copy_file(path, scrub(old_name), '.js')
+		self.copy_file(path, scrub(old_name), '.sql')
+				
+	def copy_file(self, path, old_name, extn):
+		import os
+		from webnotes.modules import get_module_path, scrub
+
+		if os.path.exists(os.path.join(path, old_name + extn)):
+			os.system('cp %s %s' % (os.path.join(path, old_name + extn), \
+			os.path.join(get_module_path(self.doc.module), 'search_criteria', scrub(self.doc.name), scrub(self.doc.name) + extn)))
+	
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/search_criteria/search_criteria.txt b/cgi-bin/core/doctype/search_criteria/search_criteria.txt
new file mode 100644
index 0000000000..70bae16a99
--- /dev/null
+++ b/cgi-bin/core/doctype/search_criteria/search_criteria.txt
@@ -0,0 +1,1092 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': None,
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:11',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-02-11 15:44:30',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Search Criteria',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': 'criteria_name',
+		'section_style': 'Tabbed',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 4
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': 1,
+		'creation': '2010-12-23 11:48:49',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': None,
+		'match': None,
+		'modified': '2010-12-23 11:48:49',
+		'modified_by': 'Administrator',
+		'name': '_PERM00771',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'All',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2010-12-23 11:48:49',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': None,
+		'match': None,
+		'modified': '2010-12-23 11:48:49',
+		'modified_by': 'Administrator',
+		'name': '_PERM00772',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'All',
+		'submit': None,
+		'write': None
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 1,
+		'match': None,
+		'modified': '2009-07-08 23:44:31',
+		'modified_by': 'Administrator',
+		'name': '_PERM00015',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2009-07-08 23:44:31',
+		'modified_by': 'Administrator',
+		'name': '_PERM00016',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Details',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000454',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'disabled',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Disabled',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00196',
+		'no_copy': None,
+		'oldfieldname': 'disabled',
+		'oldfieldtype': 'Check',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'module',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Module',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00197',
+		'no_copy': None,
+		'oldfieldname': 'module',
+		'oldfieldtype': 'Link',
+		'options': 'Module Def',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-09-23 16:21:53',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'standard',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Standard',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00316',
+		'no_copy': None,
+		'oldfieldname': 'standard',
+		'oldfieldtype': 'Select',
+		'options': '\nYes\nNo',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'criteria_name',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Criteria Name',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00198',
+		'no_copy': None,
+		'oldfieldname': 'criteria_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'description',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': 'Description',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00199',
+		'no_copy': None,
+		'oldfieldname': 'description',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': None,
+		'label': 'Query Details',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000455',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doc_type',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'icon': None,
+		'idx': 8,
+		'in_filter': None,
+		'label': 'Doc Type',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00201',
+		'no_copy': None,
+		'oldfieldname': 'doc_type',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'filters',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 9,
+		'in_filter': None,
+		'label': 'Filters',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00202',
+		'no_copy': None,
+		'oldfieldname': 'filters',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'columns',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 10,
+		'in_filter': None,
+		'label': 'Columns',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00203',
+		'no_copy': None,
+		'oldfieldname': 'columns',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'parent_doc_type',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'icon': None,
+		'idx': 11,
+		'in_filter': None,
+		'label': 'Parent Doc Type',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00204',
+		'no_copy': None,
+		'oldfieldname': 'parent_doc_type',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'add_cond',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 12,
+		'in_filter': None,
+		'label': 'Additional Conditions',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00205',
+		'no_copy': None,
+		'oldfieldname': 'add_cond',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'add_col',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 13,
+		'in_filter': None,
+		'label': 'Additional Columns',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00206',
+		'no_copy': None,
+		'oldfieldname': 'add_col',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'add_tab',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 14,
+		'in_filter': None,
+		'label': 'Additional Tables',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00207',
+		'no_copy': None,
+		'oldfieldname': 'add_tab',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'dis_filters',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 15,
+		'in_filter': None,
+		'label': 'Disabled Filters',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00208',
+		'no_copy': None,
+		'oldfieldname': 'dis_filters',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'group_by',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 16,
+		'in_filter': None,
+		'label': 'Group By',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00209',
+		'no_copy': None,
+		'oldfieldname': 'group_by',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'graph_series',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 17,
+		'in_filter': None,
+		'label': 'Graph Series',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00210',
+		'no_copy': None,
+		'oldfieldname': 'graph_series',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'graph_values',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 18,
+		'in_filter': None,
+		'label': 'Graph Values',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00211',
+		'no_copy': None,
+		'oldfieldname': 'graph_values',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-08 23:27:40',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'sort_by',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 19,
+		'in_filter': None,
+		'label': 'Sort By',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00300',
+		'no_copy': None,
+		'oldfieldname': 'sort_by',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-08 23:27:40',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'sort_order',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 20,
+		'in_filter': None,
+		'label': 'Sort Order',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00299',
+		'no_copy': None,
+		'oldfieldname': 'sort_order',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-09-23 16:21:53',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'page_len',
+		'fieldtype': 'Int',
+		'hidden': None,
+		'icon': None,
+		'idx': 21,
+		'in_filter': None,
+		'label': 'Page Len',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00317',
+		'no_copy': None,
+		'oldfieldname': 'page_len',
+		'oldfieldtype': 'Int',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 22,
+		'in_filter': None,
+		'label': 'Client Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000456',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'report_script',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 23,
+		'in_filter': None,
+		'label': 'Report Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00213',
+		'no_copy': None,
+		'oldfieldname': 'report_script',
+		'oldfieldtype': 'Code',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 24,
+		'in_filter': None,
+		'label': 'Server Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000457',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'server_script',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 25,
+		'in_filter': None,
+		'label': 'Report Server Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00215',
+		'no_copy': None,
+		'oldfieldname': 'server_script',
+		'oldfieldtype': 'Code',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 26,
+		'in_filter': None,
+		'label': 'Overload Query',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000458',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-08 23:44:31',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'custom_query',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 27,
+		'in_filter': None,
+		'label': 'Custom Query',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00302',
+		'no_copy': None,
+		'oldfieldname': 'custom_query',
+		'oldfieldtype': 'Code',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/stylesheet/__init__.py b/cgi-bin/core/doctype/stylesheet/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/stylesheet/stylesheet.py b/cgi-bin/core/doctype/stylesheet/stylesheet.py
new file mode 100644
index 0000000000..9a4c7f9f66
--- /dev/null
+++ b/cgi-bin/core/doctype/stylesheet/stylesheet.py
@@ -0,0 +1,18 @@
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d,dl
+
+	# export
+	def on_update(self):
+		import webnotes.defs
+		
+		if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode:
+			from webnotes.modules.export_module import export_to_files	
+			from webnotes.modules import get_module_path, scurb
+			import os
+			
+			export_to_files(record_list=[['Stylesheet', self.doc.name]])
+
+			file = open(os.path.join(get_module_path(self.doc.module), 'Stylesheet', scrub(self.doc.name), scrub(self.doc.name) + '.html'), 'w')
+			file.write(self.doc.content)
+			file.close()	
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/stylesheet/stylesheet.txt b/cgi-bin/core/doctype/stylesheet/stylesheet.txt
new file mode 100644
index 0000000000..a067224731
--- /dev/null
+++ b/cgi-bin/core/doctype/stylesheet/stylesheet.txt
@@ -0,0 +1,160 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'field:stylesheet_name',
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2011-04-05 10:01:46',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-02-21 17:10:05',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Stylesheet',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': None,
+		'show_in_menu': None,
+		'smallicon': None,
+		'use_template': None,
+		'version': 4
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'stylesheet_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Stylesheet Name',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000459',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Stylesheet',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'module',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Module',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000460',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': 'Module Def',
+		'owner': 'Administrator',
+		'parent': 'Stylesheet',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'stylesheet',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Stylesheet',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000461',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Stylesheet',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/system_console/__init__.py b/cgi-bin/core/doctype/system_console/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/system_console/system_console.comp.js b/cgi-bin/core/doctype/system_console/system_console.comp.js
new file mode 100644
index 0000000000..97e8afd0b0
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.comp.js
@@ -0,0 +1,8 @@
+
+cur_frm.cscript['Server (Python)']=function(doc,dt,dn){$c_obj([doc],'execute_server','',function(r,rt){doc=locals[doc.doctype][doc.name];if(r.exc){doc.response=r.exc;}else{doc.response='Worked!'}
+refresh_field('response');})}
+cur_frm.cscript['Client (JS)']=function(doc,dt,dn){try{doc.response=eval(doc.script);}catch(e){doc.response=e.toString()
++'\nMessage:'+e.message
++'\nLine Number:'+e.lineNumber
++'\nStack:'+e.stack;}
+refresh_field('response');}
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/system_console/system_console.js b/cgi-bin/core/doctype/system_console/system_console.js
new file mode 100644
index 0000000000..a16c39f6ac
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.js
@@ -0,0 +1,23 @@
+cur_frm.cscript['Server (Python)'] = function(doc, dt, dn) {
+	$c_obj([doc], 'execute_server', '', function(r, rt) {
+		doc = locals[doc.doctype][doc.name];
+		if(r.exc) {
+			doc.response = r.exc;
+		} else {
+			doc.response = 'Worked!'
+		}
+		refresh_field('response');
+	})
+}
+
+cur_frm.cscript['Client (JS)'] = function(doc, dt, dn) {
+	try {
+		doc.response = eval(doc.script);		
+	} catch(e) {
+		doc.response = e.toString() 
+			+ '\nMessage:' + e.message
+			+ '\nLine Number:' + e.lineNumber
+			+ '\nStack:' + e.stack;
+	}
+	refresh_field('response');
+}
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/system_console/system_console.py b/cgi-bin/core/doctype/system_console/system_console.py
new file mode 100644
index 0000000000..511cf518ab
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.py
@@ -0,0 +1,17 @@
+import webnotes
+
+from webnotes.utils import cint, flt
+from webnotes.model.doc import Document
+from webnotes.model.code import get_obj
+from webnotes import session, msgprint, errprint
+
+sql = webnotes.conn.sql
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
+
+	def execute_server(self, arg=''):
+		if webnotes.user.name=='Guest':
+			raise Exception, 'Guest cannot call execute test!'
+		exec(self.doc.script)
diff --git a/cgi-bin/core/doctype/system_console/system_console.txt b/cgi-bin/core/doctype/system_console/system_console.txt
new file mode 100644
index 0000000000..cf5ff1434d
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.txt
@@ -0,0 +1,242 @@
+[
+	{
+		'_last_update': '1303450387',
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': None,
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-09 10:50:36',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': 'System',
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': 1,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-04-22 13:12:21',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'System Console',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': None,
+		'show_in_menu': 1,
+		'smallicon': None,
+		'use_template': None,
+		'version': 6
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': 1,
+		'creation': '2011-05-09 10:50:36',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 1,
+		'match': None,
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000145',
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2011-05-09 10:50:36',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000146',
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'script',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Script',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000147',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Button',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Server (Python)',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000148',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': 'Client',
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Button',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Client (JS)',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000149',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': 'Client',
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'response',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Error',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000150',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/table_mapper_detail/__init__.py b/cgi-bin/core/doctype/table_mapper_detail/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt b/cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt
new file mode 100644
index 0000000000..494fef1abf
--- /dev/null
+++ b/cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt
@@ -0,0 +1,335 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'TMD/.#######',
+		'change_log': None,
+		'client_script': '',
+		'client_script_core': '',
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2010-11-30 17:30:05',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': 1,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2010-09-20 14:06:57',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Table Mapper Detail',
+		'name_case': '',
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': '',
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Tray',
+		'server_code': '',
+		'server_code_compiled': None,
+		'server_code_core': '',
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': '',
+		'use_template': None,
+		'version': 5
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'from_table',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'From Table',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00587',
+		'no_copy': None,
+		'oldfieldname': 'from_table',
+		'oldfieldtype': 'Select',
+		'options': 'link:DocType',
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'to_table',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'To Table',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00588',
+		'no_copy': None,
+		'oldfieldname': 'to_table',
+		'oldfieldtype': 'Select',
+		'options': 'link:DocType',
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'from_field',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'From Field',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00589',
+		'no_copy': None,
+		'oldfieldname': 'from_field',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'to_field',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'To Field',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00590',
+		'no_copy': None,
+		'oldfieldname': 'to_field',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'match_id',
+		'fieldtype': 'Int',
+		'hidden': None,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Match Id',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00591',
+		'no_copy': None,
+		'oldfieldname': 'match_id',
+		'oldfieldtype': 'Int',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': None,
+		'trigger': None,
+		'width': '60px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'validation_logic',
+		'fieldtype': 'Small Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': 'Validation Logic',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00592',
+		'no_copy': None,
+		'oldfieldname': 'validation_logic',
+		'oldfieldtype': 'Small Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': '150px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:06',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'reference_doctype_key',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': None,
+		'label': 'Reference DocType Key',
+		'modified': '2010-11-30 17:30:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00593',
+		'no_copy': None,
+		'oldfieldname': 'reference_doctype_key',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'nabin@webnotestech.com',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': ''
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:06',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'reference_key',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 8,
+		'in_filter': None,
+		'label': 'Reference Docname Key',
+		'modified': '2010-11-30 17:30:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00594',
+		'no_copy': None,
+		'oldfieldname': 'reference_key',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'nabin@webnotestech.com',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/tag/__init__.py b/cgi-bin/core/doctype/tag/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/tag/tag.txt b/cgi-bin/core/doctype/tag/tag.txt
new file mode 100644
index 0000000000..9538f864a3
--- /dev/null
+++ b/cgi-bin/core/doctype/tag/tag.txt
@@ -0,0 +1,90 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': None,
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2010-08-08 17:09:26',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': 1,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-04-06 10:36:05',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Tag',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': 1,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 7
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-06 10:35:22',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'tag_color',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Tag Color',
+		'modified': '2011-04-06 10:36:05',
+		'modified_by': 'Administrator',
+		'name': '000000467',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Tag',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/userrole/__init__.py b/cgi-bin/core/doctype/userrole/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/userrole/userrole.txt b/cgi-bin/core/doctype/userrole/userrole.txt
new file mode 100644
index 0000000000..9e99c293e7
--- /dev/null
+++ b/cgi-bin/core/doctype/userrole/userrole.txt
@@ -0,0 +1,90 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': 0,
+		'allow_email': 0,
+		'allow_print': 0,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'UR.#####',
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:11',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': 0,
+		'hide_toolbar': 0,
+		'idx': 0,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': 0,
+		'istable': 1,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2010-09-20 14:06:57',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'UserRole',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': 0,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': '',
+		'creation': '2009-05-12 11:19:12',
+		'default': '',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'role',
+		'fieldtype': 'Link',
+		'hidden': 0,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Role',
+		'modified': '2009-05-12 11:19:12',
+		'modified_by': 'Administrator',
+		'name': '_FL00236',
+		'no_copy': None,
+		'oldfieldname': 'role',
+		'oldfieldtype': 'Link',
+		'options': 'Role',
+		'owner': 'Administrator',
+		'parent': 'UserRole',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': '',
+		'width': '200px'
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/module.info b/cgi-bin/core/module.info
new file mode 100644
index 0000000000..f51efd8b20
--- /dev/null
+++ b/cgi-bin/core/module.info
@@ -0,0 +1 @@
+{'update_date': '2011-03-18 18:12:06'}
\ No newline at end of file
diff --git a/cgi-bin/core/page/__init__.py b/cgi-bin/core/page/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/page/login_page/__init__.py b/cgi-bin/core/page/login_page/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/page/login_page/login_page.html b/cgi-bin/core/page/login_page/login_page.html
new file mode 100644
index 0000000000..3242669c6b
--- /dev/null
+++ b/cgi-bin/core/page/login_page/login_page.html
@@ -0,0 +1,29 @@
+
+

Login

+ + + + + + + + + + + + + + + + + + + + + + + +
Login Id
Password
Remember Me
  
 
+

Forgot Password

+

Debug

+
\ No newline at end of file diff --git a/cgi-bin/core/page/login_page/login_page.js b/cgi-bin/core/page/login_page/login_page.js new file mode 100644 index 0000000000..6f73ae14db --- /dev/null +++ b/cgi-bin/core/page/login_page/login_page.js @@ -0,0 +1,56 @@ +pscript['onload_Login Page'] = function(){ + var lw = $i('login_wrapper') + $bs(lw, '1px 1px 3px #888'); + $bg(document.getElementsByTagName('body')[0], '#DDD'); + + pscript.login_btn = $btn('login_btn', 'Login', pscript.doLogin) + + keypress_observers.push(new function() { + this.notify_keypress = function(kc) { if(kc==13 && $i("password").value) pscript.doLogin(); } + } + ); +} + + +// Login Callback +pscript.onLoginReply = function(r, rtext) { + pscript.login_btn.done_working(); + if(r.message=="Logged In"){ + window.location.href='index.cgi' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : ''); + } else { + $i('login_message').innerHTML = ''+eval(r.message)+''; + //if(r.exc)alert(r.exc); + } +} + + +// Login +pscript.doLogin = function(){ + + var args = {}; + args['usr']=$i("login_id").value; + args['pwd']=$i("password").value; + if($i('remember_me').checked) + args['remember_me'] = 1; + + pscript.login_btn.set_working(); + + $c("login", args, pscript.onLoginReply); +} + + +pscript.show_forgot_password = function(){ + // create dialog + var d = new Dialog(400, 400, 'Reset Password') + d.make_body([['HTML','Title','Enter your email id to reset the password'], ['Data','Email Id'], ['Button','Reset']]); + + var callback = function(r,rt) { + if(!r.exc) pscript.forgot_dialog.hide(); + } + + d.widgets['Reset'].onclick = function() { + $c('reset_password', {user: pscript.forgot_dialog.widgets['Email Id'].value}, callback) + } + d.show(); + pscript.forgot_dialog = d; +} \ No newline at end of file diff --git a/cgi-bin/core/page/login_page/login_page.txt b/cgi-bin/core/page/login_page/login_page.txt new file mode 100644 index 0000000000..0764e237f3 --- /dev/null +++ b/cgi-bin/core/page/login_page/login_page.txt @@ -0,0 +1,33 @@ +[ + { + 'content': None, + 'creation': '2010-01-20 11:10:18', + 'docstatus': 0, + 'doctype': 'Page', + 'icon': None, + 'idx': None, + 'keywords': None, + 'menu_index': None, + 'modified': '2011-02-17 13:01:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Login Page', + 'owner': 'Administrator', + 'page_name': 'Login Page', + 'page_title': None, + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'publish': None, + 'script': None, + 'show_in_menu': None, + 'site_description': None, + 'standard': 'Yes', + 'static_content': None, + 'style': None, + 'stylesheet': None, + 'template': None, + 'write_content': 1 + } +] \ No newline at end of file diff --git a/cgi-bin/core/page/login_page/login_page_static.html b/cgi-bin/core/page/login_page/login_page_static.html new file mode 100644 index 0000000000..00a339f2d2 --- /dev/null +++ b/cgi-bin/core/page/login_page/login_page_static.html @@ -0,0 +1,3 @@ +

Login Page

+ +

Powered by Web Notes Framework

\ No newline at end of file diff --git a/cgi-bin/getfile.cgi b/cgi-bin/getfile.cgi new file mode 100755 index 0000000000..cd652c0b6d --- /dev/null +++ b/cgi-bin/getfile.cgi @@ -0,0 +1,82 @@ +#!/usr/bin/python + +try: + + import sys, os + + sys.path.append(os.getcwd()+'/cgi-bin') + + def getTraceback(): + import sys, traceback, string + type, value, tb = sys.exc_info() + body = "Traceback (innermost last):\n" + list = traceback.format_tb(tb, None) \ + + traceback.format_exception_only(type, value) + body = body + "%-20s %s" % (string.join(list[:-1], ""), list[-1]) + return body + + import cgi + import webnotes + import webnotes.auth + import webnotes.utils + import webnotes.utils.file_manager + import webnotes.db + import webnotes.defs + + sys.path.append(webnotes.defs.modules_path) + + form = cgi.FieldStorage() + webnotes.form_dict = {} + + for each in form.keys(): + webnotes.form_dict[each] = form.getvalue(each) + + n = form.getvalue('name') + + # authenticate + webnotes.auth.HTTPRequest() + + # get file + res = webnotes.utils.file_manager.get_file(n) + + fname = res[0] + if hasattr(res[1], 'tostring'): + fcontent = res[1].tostring() + else: + fcontent = res[1] + + if form.getvalue('thumbnail'): + tn = webnotes.utils.cint(form.getvalue('thumbnail')) + try: + from PIL import Image + import cStringIO + + fobj = cStringIO.StringIO(fcontent) + image = Image.open(fobj) + image.thumbnail((tn,tn*2), Image.ANTIALIAS) + outfile = cStringIO.StringIO() + + if image.mode != "RGB": + image = image.convert("RGB") + + image.save(outfile, 'JPEG') + outfile.seek(0) + fcontent = outfile.read() + except: + pass + + import mimetypes + print "Content-Type: %s" % (mimetypes.guess_type(fname)[0] or 'application/unknown') + print "Content-Disposition: filename="+fname.replace(' ', '_') + print "Cache-Control: max-age=3600" + print + print fcontent + +except Exception, e: + print "Content-Type: text/html" + try: + out = {'message':'', 'exc':getTraceback().replace('\n','
')} + except: + out = {'exc': e} + print + print str(out) diff --git a/cgi-bin/getjsfile.cgi b/cgi-bin/getjsfile.cgi new file mode 100755 index 0000000000..18a876cead --- /dev/null +++ b/cgi-bin/getjsfile.cgi @@ -0,0 +1,73 @@ +#!/usr/bin/python + +import cgi +import datetime +import os + +try: + + form = cgi.FieldStorage() + out = '' + out_buf, str_out = '', '' + + # Traceback + # --------- + def getTraceback(): + import sys, traceback, string + type, value, tb = sys.exc_info() + body = "Traceback (innermost last):\n" + list = traceback.format_tb(tb, None) \ + + traceback.format_exception_only(type, value) + body = body + "%-20s %s" % (string.join(list[:-1], ""), list[-1]) + return body + + def load_js_file(): + global out + filename = form.getvalue('filename') + import os + try: + f = open(os.path.join('../js/', filename)) + try: + out = f.read() + finally: + f.close() + except IOError,e: + out = "Not Found: %s" % filename + + def compress_string(buf): + import gzip, cStringIO + zbuf = cStringIO.StringIO() + zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) + zfile.write(buf) + zfile.close() + return zbuf.getvalue() + + compress = 0 + try: + if string.find(os.environ["HTTP_ACCEPT_ENCODING"], "gzip") != -1: + compress = 1 + except: + pass + + load_js_file() + + if compress and len(out)>512: + out_buf = compress_string(str_out) + print "Content-Encoding: gzip" + print "Content-Length: %d" % (len(out_buf)) + + print "Content-Type: text/javascript" + + # Headers end + print + + if out_buf: + sys.stdout.write(out_buf) + elif out: + print out + +except Exception, e: + print "Content-Type: text/javascript" + print + print getTraceback().replace('\n','
') + \ No newline at end of file diff --git a/cgi-bin/pypi-setup.py b/cgi-bin/pypi-setup.py new file mode 100755 index 0000000000..07c6bb952d --- /dev/null +++ b/cgi-bin/pypi-setup.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Script for creating the pypi packages +# Works only for python 2.6+ + + +import os + +try: + from setuptools import setup, find_packages +except ImportError: + import ez_setup + ez_setup.use_setuptools() + from setuptools import setup, find_packages + +# Startup +appname = "webnotes-core" +appversion = "v170" + +setup( + name = appname, + version = appversion, + author = "Rushabh Mehta", + namespace_packages = ["webnotes"], + packages = ["webnotes"] + [ os.path.join("webnotes", a) for a in find_packages("webnotes") ], + author_email = "rmehta@gmail.com", + description = "A meta-data based library for creating web apps in python and javascript", + license = "MIT", + keywords = "Meta-data web app framework python", + url = "http://code.google.com/p/webnotes/", + classifiers = ["License :: OSI Approved :: MIT License","Topic :: Software Development :: Libraries :: Python Modules"], + long_description = "Webnotes is a meta-data based framework for web applications in python", +) + diff --git a/cgi-bin/webnotes/__init__.py b/cgi-bin/webnotes/__init__.py new file mode 100644 index 0000000000..8607425ffb --- /dev/null +++ b/cgi-bin/webnotes/__init__.py @@ -0,0 +1,228 @@ +# +# import modules path +# +import os, sys + +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')], + 'Search Criteria':[('report_script', 'js'), ('server_script', 'py'), ('custom_query', 'sql')], + 'Patch':[('patch_code', 'py')], + 'Stylesheet':['stylesheet', 'css'], + 'Page Template':['template', 'html'], + '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 """ + +cookies = {} +auto_masters = {} +tenant_id = None + +# +# 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() + +def errprint(msg): + """ + Append to the :data:`debug log` + """ + debug_log.append(str(msg or '')) + +def msgprint(msg, small=0, raise_exception=0): + """ + Append to the :data:`message_log` + """ + message_log.append((small and '__small:' or '')+str(msg or '')) + if raise_exception: + raise ValidationError + +def is_apache_user(): + import os + if os.environ.get('USER') == 'apache': + return True + else: + return (not os.environ.get('USER')) + # os.environ does not have user, so allows a security vulnerability,fixed now. + +def get_index_path(): + import os + return os.sep.join(os.path.dirname(os.path.abspath(__file__)).split(os.sep)[:-2]) + +def get_files_path(): + global conn + import defs, os + + if not conn: + raise Exception, 'You must login first' + + if defs.files_path: + return os.path.join(defs.files_path, conn.cur_db_name) + else: + return os.path.join(get_index_path(), 'user_files', conn.cur_db_name) + +def create_folder(path): + import os + + try: + os.makedirs(path) + except Exception, e: + if e.args[0]==17: + pass + else: + raise e + + +############################################################################### +# BEGIN: TENTATIVE CODE FEELS LIKE A CLASS/TEMPLATE IS A BETTER IDEA FOR THESE VARIABLES. +# Bad idea combining/using one function to set conn,user,session variables. +# Need to split up. +############################################################################### + +def set_as_account_master(): + import webnotes.db + global conn + conn = webnotes.db.Database(use_default = 1) + +def set_as_administrator(): + + global user + + if is_apache_user(): + raise Exception, 'Not for web users!' + + import webnotes.profile + user = webnotes.profile.Profile('Administrator') + +def set_as_admin_session(): + global session + session = {'user':'Administrator'} + +############################################################################### +#END +############################################################################### + + +def set_as_admin(db_name=None, ac_name=None): + + import os + if is_apache_user(): + raise Exception, 'Not for web users!' + + global conn + global session + global user + + import webnotes.db + if ac_name: + conn = webnotes.db.Database(ac_name = ac_name) + else: + set_as_account_master() + if db_name: + conn.use(db_name) + + session = {'user':'Administrator'} + import webnotes.profile + user = webnotes.profile.Profile('Administrator') + + +# Environment Variables +#----------------------------------------------------------- +def get_env_vars(env_var): + 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() + diff --git a/cgi-bin/webnotes/auth.py b/cgi-bin/webnotes/auth.py new file mode 100644 index 0000000000..c83118ce80 --- /dev/null +++ b/cgi-bin/webnotes/auth.py @@ -0,0 +1,424 @@ +import webnotes +import webnotes.db +import webnotes.utils +import webnotes.profile +import webnotes.defs + +# ================================================================================= +# HTTPRequest +# ================================================================================= + +class HTTPRequest: + def __init__(self): + + # Get Environment variables + self.domain = webnotes.get_env_vars('HTTP_HOST') + if self.domain and self.domain.startswith('www.'): + self.domain = self.domain[4:] + + webnotes.remote_ip = webnotes.get_env_vars('REMOTE_ADDR') + + # load cookies + webnotes.cookie_manager = CookieManager() + + # set db + self.set_db() + + # check status + if webnotes.conn.get_global("__session_status")=='stop': + webnotes.msgprint(webnotes.conn.get_global("__session_status_message")) + raise Exception + + # ----------------------------- + # start transaction + webnotes.conn.begin() + + # login + webnotes.login_manager = LoginManager() + + # 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'): + webnotes.cookie_manager.set_cookies() + + # run login triggers + if webnotes.form_dict.get('cmd')=='login': + webnotes.login_manager.run_trigger('on_login_post_session') + + # load profile + self.setup_profile() + + webnotes.conn.commit() + # end transaction + # ----------------------------- + + # setup profile + # ------------- + + def setup_profile(self): + webnotes.user = webnotes.profile.Profile() + # load the profile data + if webnotes.session['data'].get('profile'): + webnotes.user.load_from_session(webnotes.session['data']['profile']) + else: + webnotes.user.load_profile() + + + # get account name + # ------------------ + + def get_ac_name(self): + # login + if webnotes.form_dict.get('acx'): + return webnotes.form_dict.get('acx') + + # in form + elif webnotes.form_dict.get('ac_name'): + return webnotes.form_dict.get('ac_name') + + # in cookie + elif webnotes.incoming_cookies.get('ac_name'): + return webnotes.incoming_cookies.get('ac_name') + + + # set database login + # ------------------ + + def set_db(self, ac_name = None): + + + # select based on subdomain + if getattr(webnotes.defs,'domain_name_map', {}).get(self.domain): + db_name = webnotes.defs.domain_name_map[self.domain] + + # select based on ac_name + else: + ac_name = self.get_ac_name() + if ac_name: + db_name = getattr(webnotes.defs,'db_name_map',{}).\ + get(ac_name, ac_name) + else: + db_name = getattr(webnotes.defs,'default_db_name','') + + webnotes.conn = webnotes.db.Database(user = db_name,password = getattr(webnotes.defs,'db_password','')) + webnotes.ac_name = ac_name + +# ================================================================================= +# Login Manager +# ================================================================================= + +class LoginManager: + def __init__(self): + self.cp = None + if webnotes.form_dict.get('cmd')=='login': + # clear cache + from webnotes.session_cache import clear_cache + clear_cache(webnotes.form_dict.get('usr')) + + self.authenticate() + self.post_login() + webnotes.response['message'] = 'Logged In' + + # run triggers, write cookies + # --------------------------- + + def post_login(self): + self.validate_ip_address() + self.run_trigger() + + # check password + # -------------- + + def authenticate(self, user=None, pwd=None): + if not (user and pwd): + user, pwd = webnotes.form_dict.get('usr'), webnotes.form_dict.get('pwd') + + if not (user and pwd): + webnotes.msgprint('Incomplete Login Details', raise_exception=1) + + # custom authentication (for single-sign on) + self.load_control_panel() + if hasattr(self.cp, 'authenticate'): + self.user = self.cp.authenticate() + + # check the password + if user=='Administrator': + p = webnotes.conn.sql("select name from tabProfile where name=%s and (`password`=%s OR `password`=PASSWORD(%s))", (user, pwd, pwd)) + else: + p = webnotes.conn.sql("select name from tabProfile where name=%s and (`password`=%s OR `password`=PASSWORD(%s)) and IFNULL(enabled,0)=1", (user, pwd, pwd)) + + if not p: + webnotes.msgprint('Authentication Failed', raise_exception=1) + + self.user = p[0][0] + + # triggers + # -------- + + def load_control_panel(self): + import webnotes.model.code + try: + if not self.cp: + self.cp = webnotes.model.code.get_obj('Control Panel') + except Exception, e: + webnotes.response['Control Panel Exception'] = webnotes.utils.getTraceback() + + # -------- + def run_trigger(self, method='on_login'): + try: + import event_handlers + if hasattr(event_handlers, method): + getattr(event_handlers, method)(self) + return + except ImportError, e: + pass + + # deprecated + self.load_control_panel() + if self.cp and hasattr(self.cp, method): + getattr(self.cp, method)(self) + + # ip validation + # ------------- + + def validate_ip_address(self): + try: + ip = webnotes.conn.sql("select ip_address from tabProfile where name = '%s'" % self.user)[0][0] or '' + except: return + + ip = ip.replace(",", "\n").split('\n') + ip = [i.strip() for i in ip] + + if ret and ip: + if not (webnotes.remote_ip.startswith(ip[0]) or (webnotes.remote_ip in ip)): + raise Exception, 'Not allowed from this IP Address' + + # login as guest + # -------------- + + def login_as_guest(self): + res = webnotes.conn.sql("select name from tabProfile where name='Guest' and ifnull(enabled,0)=1") + if not res: + raise Exception, "No Guest Access" + self.user = 'Guest' + self.post_login() + + # Logout + # ------ + + def call_on_logout_event(self): + import webnotes.model.code + cp = webnotes.model.code.get_obj('Control Panel', 'Control Panel') + if hasattr(cp, 'on_logout'): + cp.on_logout(self) + + def logout(self, arg=''): + self.run_trigger('on_logout') + webnotes.conn.sql('update tabSessions set status="Logged Out" where sid="%s"' % webnotes.session['sid']) + +# ================================================================================= +# Cookie Manager +# ================================================================================= + +class CookieManager: + def __init__(self): + import Cookie + webnotes.cookies = Cookie.SimpleCookie() + self.get_incoming_cookies() + + # get incoming cookies + # -------------------- + def get_incoming_cookies(self): + import os + cookies = {} + if 'HTTP_COOKIE' in os.environ: + c = os.environ['HTTP_COOKIE'] + webnotes.cookies.load(c) + for c in webnotes.cookies.values(): + cookies[c.key] = c.value + + webnotes.incoming_cookies = cookies + + # Set cookies + # ----------- + + def set_cookies(self): + if webnotes.conn.cur_db_name: + webnotes.cookies['account_id'] = webnotes.conn.cur_db_name + + # ac_name + webnotes.cookies['ac_name'] = webnotes.ac_name or '' + + if webnotes.session.get('sid'): + webnotes.cookies['sid'] = webnotes.session['sid'] + + # sid expires in 3 days + import datetime + expires = datetime.datetime.now() + datetime.timedelta(days=3) + + webnotes.cookies['sid']['expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S') + + # Set Remember Me + # --------------- + + def set_remember_me(self): + if webnotes.utils.cint(webnotes.form_dict.get('remember_me')): + remember_days = webnotes.conn.get_value('Control Panel',None,'remember_for_days') or 7 + webnotes.cookies['remember_me'] = 1 + + import datetime + expires = datetime.datetime.now() + datetime.timedelta(days=remember_days) + + for k in webnotes.cookies.keys(): + webnotes.cookies[k]['expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S') + +# ================================================================================= +# Session +# ================================================================================= + +class Session: + def __init__(self, user=None): + self.user = user + self.sid = webnotes.form_dict.get('sid') or webnotes.incoming_cookies.get('sid') + self.data = {'user':user,'data':{}} + + if webnotes.form_dict.get('cmd')=='login': + self.start() + return + + self.load() + + # start a 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 + + if r: + r=r[0] + + # ExipredSession + if r[2]=='Expired' and (webnotes.form_dict.get('cmd')!='resume_session'): + if r[0]=='Guest' or (not webnotes.form_dict.get('cmd')) or webnotes.form_dict.get('cmd')=='logout': + webnotes.login_manager.login_as_guest() + self.start() + else: + webnotes.response['session_status'] = 'Session Expired' + raise Exception, 'Session Expired' + elif r[2]=='Logged Out': + webnotes.login_manager.login_as_guest() + self.start() + # allow refresh or logout + if webnotes.form_dict.get('cmd') and webnotes.form_dict.get('cmd')!='logout': + webnotes.response['session_status'] = 'Logged Out' + raise Exception, 'Logged Out' + else: + self.data = {'data':eval(r[1]), 'user':r[0], 'sid': self.sid} + else: + webnotes.login_manager.login_as_guest() + self.start() + + + # start a session + # --------------- + def start(self): + import os + import webnotes + import webnotes.utils + + # generate sid + self.data['user'] = webnotes.login_manager.user + self.data['sid'] = webnotes.utils.generate_hash() + self.data['data']['session_ip'] = os.environ.get('REMOTE_ADDR'); + self.data['data']['tenant_id'] = webnotes.form_dict.get('tenant_id', 0) + + # get ipinfo + if webnotes.conn.get_global('get_ip_info'): + self.get_ipinfo() + + # insert session + try: + self.insert_session_record() + except Exception, e: + if e.args[0]==1054: + self.add_status_column() + self.insert_session_record() + else: + raise e + + # update profile + webnotes.conn.sql("UPDATE tabProfile SET last_login = '%s', last_ip = '%s' where name='%s'" % (webnotes.utils.now(), webnotes.remote_ip, self.data['user'])) + + # set cookies to write + webnotes.session = self.data + webnotes.cookie_manager.set_cookies() + + + # resume session + # -------------- + def resume(self): + pwd = webnotes.form_dict.get('pwd') + webnotes.login_manager.authenticate(self.data['user'], pwd) + webnotes.conn.sql("update tabSessions set status='Active' where sid=%s", self.data['sid']) + return 'Logged In' + + # update session + # -------------- + def update(self): + # update session + webnotes.conn.sql("update tabSessions set sessiondata=%s, user=%s, lastupdate=NOW() where sid=%s" , (str(self.data['data']), self.data['user'], self.data['sid'])) + + self.check_expired() + + # check expired + # ------------- + def check_expired(self): + # in control panel? + exp_sec = webnotes.conn.get_value('Control Panel', None, 'session_expiry') or '6:00:00' + + # set sessions as expired + try: + webnotes.conn.sql("update from tabSessions where TIMEDIFF(NOW(), lastupdate) > %s SET `status`='Expired'", exp_sec) + except Exception, e: + if e.args[0]==1054: + self.add_status_column() + + # 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): + import os + + try: + import pygeoip + except: + return + + gi = pygeoip.GeoIP('data/GeoIP.dat') + self.data['data']['ipinfo'] = {'countryName': gi.country_name_by_addr(os.environ.get('REMOTE_ADDR'))} + + # ----------------------------- + def insert_session_record(self): + webnotes.conn.sql("insert into tabSessions (sessiondata, user, lastupdate, sid, status) values (%s , %s, NOW(), %s, 'Active')", (str(self.data['data']), self.data['user'], self.data['sid'])) + diff --git a/cgi-bin/webnotes/db.py b/cgi-bin/webnotes/db.py new file mode 100644 index 0000000000..912d70437c --- /dev/null +++ b/cgi-bin/webnotes/db.py @@ -0,0 +1,310 @@ +# Database Module +# -------------------- + +import MySQLdb +from webnotes import defs +import webnotes + +class Database: + """ + Open a database connection with the given parmeters, if use_default is True, use the + login details from `defs.py`. This is called by the request handler and is accessible using + the `conn` global variable. the `sql` method is also global to run queries + """ + def __init__(self, host='', user='', password='', ac_name = '', use_default = 0): + self.host = host or 'localhost' + self.user = user or getattr(defs, 'default_db_name', '') + self.password = password or getattr(defs, 'db_password', '') + + if ac_name: + self.user = self.get_db_login(ac_name) or defs.default_db_name + + if use_default: + self.user = defs.default_db_name + + self.is_testing = 0 + self.in_transaction = 0 + self.transaction_writes = 0 + self.testing_tables = [] + + self.connect() + if self.user != 'root': + self.use(self.user) + + if webnotes.logger: + webnotes.logger.debug('Database object initialized for:%s',self.user) + + def get_db_login(self, ac_name): + return getattr(defs,'db_name_map').get(ac_name, getattr(defs,'default_db_name')) + + def connect(self): + """ + Connect to a database + """ + self._conn = MySQLdb.connect(user=self.user, host=self.host, passwd=self.password) + try: + self._conn.set_character_set('utf8') + except: + pass + + self._cursor = self._conn.cursor() + + return self._cursor + + def use(self, db_name): + """ + `USE` db_name + """ + self._conn.select_db(db_name) + self.cur_db_name = db_name + + def check_transaction_status(self, query): + """ + Update *in_transaction* and check if "START TRANSACTION" is not called twice + """ + if self.in_transaction and query and query.strip().split()[0].lower() in ['start', 'alter', 'drop', 'create']: + raise Exception, 'This statement can cause implicit commit' + + if query and query.strip().lower()=='start transaction': + self.in_transaction = 1 + self.transaction_writes = 0 + + if query and query.strip().split()[0].lower() in ['commit', 'rollback']: + self.in_transaction = 0 + + if self.in_transaction and query[:6].lower() in ['update', 'insert']: + self.transaction_writes += 1 + if self.transaction_writes > 5000: + webnotes.msgprint('A very long query was encountered. If you are trying to import data, please do so using smaller files') + raise Exception, 'Bad Query!!! Too many writes' + + def fetch_as_dict(self, formatted=0): + """ + Internal - get results as dictionary + """ + result = self._cursor.fetchall() + ret = [] + for r in result: + dict = {} + for i in range(len(r)): + dict[self._cursor.description[i][0]] = self.convert_to_simple_type(r[i], formatted) + ret.append(dict) + return ret + + def validate_query(self, q): + cmd = q.strip().lower().split()[0] + if cmd in ['alter', 'drop', 'truncate'] and webnotes.user.name != 'Administrator': + webnotes.msgprint('Not allowed to execute query') + raise Execption + + # ====================================================================================== + + def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0, ignore_no_table = 1, debug=0): + """ + * Execute a `query`, with given `values` + * returns as a dictionary if as_dict = 1 + * returns as a list of lists (with cleaned up dates and decimals) if as_list = 1 + """ + # in transaction validations + self.check_transaction_status(query) + + if getattr(defs,'multi_tenant',None): + query = self.add_multi_tenant_condition(query) + + # execute + if values!=(): + self._cursor.execute(query, values) + if debug: webnotes.msgprint(query % values) + + else: + self._cursor.execute(query) + if debug: webnotes.msgprint(query) + + # scrub output if required + if as_dict: + return self.fetch_as_dict(formatted) + elif as_list: + return self.convert_to_lists(self._cursor.fetchall(), formatted) + else: + return self._cursor.fetchall() + + # add condition for tenant id + # ====================================================================================== + def add_multi_tenant_condition(query): + import webnotes.multi_tenant + return webnotes.multi_tenant.query_parser.add_condition(query) + + # ====================================================================================== + + def get_description(self): + """ + Get metadata of the last query + """ + return self._cursor.description + + # ====================================================================================== + + def convert_to_simple_type(self, v, formatted=0): + try: import decimal # for decimal Python 2.5 onwards + except: pass + import datetime + from webnotes.utils import formatdate, fmt_money + + # date + if type(v)==datetime.date: + v = str(v) + if formatted: + v = formatdate(v) + + # time + elif type(v)==datetime.timedelta: + h = int(v.seconds/60/60) + v = str(h) + ':' + str(v.seconds/60 - h*60) + if v[1]==':': + v='0'+v + + # datetime + elif type(v)==datetime.datetime: + v = str(v) + + # long + elif type(v)==long: + v=int(v) + + # decimal + try: + if type(v)==decimal.Decimal: + v=float(v) + except: pass + + # convert to strings... (if formatted) + if formatted: + if type(v)==float: + v=fmt_money(v) + if type(v)==int: + v=str(v) + + return v + + # ====================================================================================== + + def convert_to_lists(self, res, formatted=0): + """ + Convert the given result set to a list of lists (with cleaned up dates and decimals) + """ + nres = [] + for r in res: + nr = [] + for c in r: + nr.append(self.convert_to_simple_type(c, formatted)) + nres.append(nr) + return nres + + # ====================================================================================== + + def replace_tab_by_test(self, query): + """ + Relace all ``tab`` + doctype to ``test`` + doctype + """ + if self.is_testing: + tl = self.get_testing_tables() + for t in tl: + query = query.replace(t, 'test' + t[3:]) + return query + + def get_testing_tables(self): + """ + Get list of all tables for which `tab` is to be replaced by `test` before a query is executed + """ + if not self.testing_tables: + testing_tables = ['tab'+r[0] for r in self.sql('SELECT name from tabDocType where docstatus<2 and (issingle=0 or issingle is null)', allow_testing = 0)] + testing_tables+=['tabSeries','tabSingles'] # tabSessions is not included here + return self.testing_tables + + # ====================================================================================== + # get a single value from a record + + def get_value(self, doctype, docname, fieldname): + """ + Get a single / multiple value from a record. + + For Single DocType, let docname be = None + """ + + fl = fieldname + if docname and (docname!=doctype or docname=='DocType'): + if type(fieldname) in (list, tuple): + fl = '`, `'.join(fieldname) + + r = self.sql("select `%s` from `tab%s` where name='%s'" % (fl, doctype, docname)) + return r and (len(r[0]) > 1 and r[0] or r[0][0]) or None + else: + if type(fieldname) in (list, tuple): + fl = "', '".join(fieldname) + + 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): + if dn and dt!=dn: + self.sql("update `tab"+dt+"` set `"+field+"`=%s where name=%s", (val, 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)) + else: + 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) + doc.fields[field] = val + + # ====================================================================================== + + def set_global(self, key, val, user='__global'): + res = self.sql('select defkey from `tabDefaultValue` where defkey=%s and parent=%s', (key, user)) + if res: + self.sql('update `tabDefaultValue` set defvalue=%s where parent=%s and defkey=%s', (str(val), user, key)) + else: + self.sql('insert into `tabDefaultValue` (name, defkey, defvalue, parent) values (%s,%s,%s,%s)', (user+'_'+key, key, str(val), user)) + + def get_global(self, key, user='__global'): + g = self.sql("select defvalue from tabDefaultValue where defkey=%s and parent=%s", (key, user)) + return g and g[0][0] or None + + # ====================================================================================== + + def begin(self): + if not self.in_transaction: + self.sql("start transaction") + + def commit(self): + self.sql("commit") + + + def rollback(self): + self.sql("ROLLBACK") + + # ====================================================================================== + + def field_exists(self, dt, fn): + """ + Returns True if `fn` exists in `DocType` `dt` + """ + return self.sql("select name from tabDocField where fieldname=%s and parent=%s", (dt, fn)) + + def exists(self, dt, dn): + """ + Returns true if the record exists + """ + try: + return self.sql('select name from `tab%s` where name=%s' % (dt, '%s'), dn) + except: + return None + + # ====================================================================================== + def close(self): + """ + Close my connection + """ + if self._conn: + self._conn.close() diff --git a/cgi-bin/webnotes/defs_template.py b/cgi-bin/webnotes/defs_template.py new file mode 100644 index 0000000000..9bfa2c7234 --- /dev/null +++ b/cgi-bin/webnotes/defs_template.py @@ -0,0 +1,86 @@ +# This file contains all the major settings regarding +# You must setup this file before running the application +# There are also settings for multiple files +# You must save this file as "defs.py" to make it live +# ================================================================================= + +# +# [IMPORTANT] - Please set your default db_name +# +default_db_name = '' +db_password = 'some_password' + +# +# map of database names to account names +# if you are running multiple database instances, then you can set "account names" to each database +# account names can be same as db_names - it is only to mask database names for security reasons +# un-comment this if you want to use db_names +# +#db_name_map = {'accountname':'dbname'} + +# +# if you are running multiple applications on one server, then you can use this to map a domain name to an +# database name. comment this if you do not want to map domain names +# +#domain_name_map = {'example.com':'dbname'} + + +# +# Path to your MySQL command account, if not directly "mysql" +# +mysql_path = '' + +# +# Attachment Files Path: This is where attachments are stored. Attachments are not stored in the database +# as they can incease backup sizes. +# It is best to keep this folder outside your www folder so that it is not accessible directly +# +files_path = 'user_files' + +# +# Modules path: This is where the module files are stored +# If this is blank, your modules files will be saved in the 'cgi-bin' forder +# +modules_path = '' + +# +# Developer Mode: If the developer_mode is set, all updates to DocTypes, Pages and Search Criteria will be +# saved to the modules folder +# +developer_mode = 0 + +# +# Time Zone: Useful if your users are across timezones +# +user_timezone = 'Asia/Calcutta' + +# +# Default Mail Server Settings +# If mail server settings are not set in the Control Panel, they are picked from here +# +mail_server = None +mail_login = None +mail_password = None +mail_port = None +use_ssl = None + +# +# Email Batching Settings +# Batching of emails is a good idea because sending an email takes a longer time in the middle of a transaction +# and locks the table. If emails are batched, you need to setup cron to call +# webnotes.utils.email_lib.EmailQueue().flush() +# +batch_emails = 0 +# email_queue = 'email_queue.py' + +# +# Logging Settings: Log using the python logger +# Error levels (in string): 'login.DEBUG', 'login.INFO', 'login.WARNING', 'logging.ERROR', 'login.CRITICAL' +# +log_file_name = 'logs/error_log.txt' +debug_log_dbs = [] +log_level = 'logging.INFO' +log_file_size = 5000 +log_file_backup_count = 5 + + diff --git a/cgi-bin/webnotes/handler.py b/cgi-bin/webnotes/handler.py new file mode 100755 index 0000000000..933784ebad --- /dev/null +++ b/cgi-bin/webnotes/handler.py @@ -0,0 +1,437 @@ +import sys, os +import webnotes +import webnotes.defs +import webnotes.utils + +form = webnotes.form +form_dict = webnotes.form_dict + +sql = None +session = None +errdoc = '' +errdoctype = '' +errmethod = '' +fw_folder = '/Users/rushabh/workbench/www/' + + +# Logs + +# refresh / start page +# ------------------------------------------------------------------------------------ + +def startup(): + import webnotes + import webnotes.session_cache + + webnotes.response.update(webnotes.session_cache.get()) + +def cleanup_docs(): + import webnotes.model.doclist + if webnotes.response.get('docs') and type(webnotes.response['docs'])!=dict: + webnotes.response['docs'] = webnotes.model.doclist.compress(webnotes.response['docs']) + +# server calls +# ------------------------------------------------------------------------------------ + +def runserverobj(arg=None): + import webnotes.widgets.form + webnotes.widgets.form.runserverobj() + +def logout(): + webnotes.login_manager.logout() + +# DocType Mapper +# ------------------------------------------------------------------------------------ + +def dt_map(): + import webnotes + import webnotes.model.doclist + from webnotes.model.code import get_obj + from webnotes.model.doc import Document + + form_dict = webnotes.form_dict + + dt_list = webnotes.model.doclist.expand(form_dict.get('docs')) + from_doctype = form_dict.get('from_doctype') + to_doctype = form_dict.get('to_doctype') + from_docname = form_dict.get('from_docname') + from_to_list = form_dict.get('from_to_list') + + dm = get_obj('DocType Mapper', from_doctype +'-' + to_doctype) + doclist = dm.dt_map(from_doctype, to_doctype, from_docname, Document(fielddata = dt_list[0]), [], from_to_list) + + webnotes.response['docs'] = doclist + +# Load Month Events +# ------------------------------------------------------------------------------------ + +def load_month_events(): + import webnotes + form = webnotes.form + + mm = form.getvalue('month') + yy = form.getvalue('year') + m_st = str(yy) + '-' + str(mm) + '-01' + m_end = str(yy) + '-' + str(mm) + '-31' + + import webnotes.widgets.event + webnotes.response['docs'] = webnotes.widgets.event.get_cal_events(m_st, m_end) + +# Data import +# ------------------------------------------------------------------------------------ + +def import_csv(): + import webnotes.model.import_docs + form = webnotes.form + from webnotes.utils import cint + + i = webnotes.model.import_docs.CSVImport() + r = i.import_csv(form.getvalue('csv_file'), form.getvalue('dateformat'), form_dict.get('overwrite', 0) and 1) + + webnotes.response['type']='iframe' + rhead = '''''' + webnotes.response['result']= rhead + r + +def get_template(): + import webnotes.model.import_docs + webnotes.model.import_docs.get_template() + + +# File Upload +# ------------------------------------------------------------------------------------ + +def uploadfile(): + 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 and 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) + + # return the upload + if fid: + webnotes.response['result'] = '' + +# File upload (from scripts) +# ------------------------------------------------------------------------------------ + +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' + + +# File download +# ------------------------------------------------------------------------------------ +def get_file(): + import webnotes.utils.file_manager + + 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') + +# 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 + + act = form_dict.get('account', '') + user = form_dict.get('user', '') + if act: + webnotes.conn.set_db(act) + + try: + p = webnotes.profile.Profile(user) + p.reset_password() + webnotes.msgprint("Password has been reset and sent to your email id.") + except Exception, e: + webnotes.msgprint(str(e)) + +# Resume session +# ------------------------------------------------------------------------------------ + +def resume_session(): + webnotes.response['message'] = webnotes.session_obj.resume() + +# ------------- +# Create Backup +# ------------- + +def backupdb(form_dict, session): + db_name = server.decrypt(form_dict.get('db_name')) + + server.backup_db(db_name) + + webnotes.response['type'] = 'download' + webnotes.response['filename'] = db_name+'.tar.gz' + webnotes.response['filecontent'] = open('../backups/' + db_name+'.tar.gz','rb').read() + +# --------------------------------------------------------------------- + +def validate_cmd(cmd): + # check if there is no direct possibility of malicious script injection + if cmd.startswith('webnotes.model.code'): + raise Exception, 'Cannot call any methods from webnotes.model.code directly from the handler' + + if cmd.startswith('webnotes.model.db_schema'): + raise Exception, 'Cannot call any methods from webnotes.model.db_schema directly from the handler' + + 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) + + # 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': + 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': + 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','')) + +# file +# ------------------------------------------------------------------- + +elif webnotes.response.get('type')=='download': + 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) + + cleanup_docs() + + # Convert to JSON + # --------------- + try: + import json + except: # python 2.4 + import simplejson as json + + try: + str_out = json.dumps(webnotes.response) + except: + str_out = str(webnotes.response).replace(', None', ', ""') + + if acceptsGzip and len(str_out)>512: + out_buf = compressBuf(str_out) + print "Content-Encoding: gzip" + print "Content-Length: %d" % (len(out_buf)) + + print "Content-Type: text/html; Charset: ISO-8859-1" + + # if there ar additional cookies defined during the request, add them here + 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 diff --git a/cgi-bin/webnotes/install_lib/__init__.py b/cgi-bin/webnotes/install_lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/webnotes/install_lib/db_init.py b/cgi-bin/webnotes/install_lib/db_init.py new file mode 100644 index 0000000000..ae76889c2f --- /dev/null +++ b/cgi-bin/webnotes/install_lib/db_init.py @@ -0,0 +1,284 @@ +""" + Create a database from scratch (wip) +""" + +class DatabaseInstance: + + def __init__(self, conn = None,db_name = None): + self.conn = conn + self.db_name = db_name + + +# def setup(self): +# self.create_db_and_user() +# self.create_base_tables() +# self.import_system_module() +# self.setup_users() + + def create_db_and_user(self): + import webnotes.defs + + # create user and db + self.conn.sql("CREATE USER '%s'@'localhost' IDENTIFIED BY '%s'" % (self.db_name, webnotes.defs.db_password)) + self.conn.sql("CREATE DATABASE IF NOT EXISTS `%s` ;" % self.db_name) + self.conn.sql("GRANT ALL PRIVILEGES ON `%s` . * TO '%s'@'localhost';" % (self.db_name, self.db_name)) + self.conn.sql("FLUSH PRIVILEGES") + self.conn.sql("SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;") + self.conn.sql("USE %s"%self.db_name) + + + + + + def create_base_tables(self): + self.create_singles() + self.create_sessions() + self.create_doctypecache() + self.create_role() + self.create_docfield() + self.create_docperm() + self.create_docformat() + self.create_doctype() + + def import_system_module(self): + docs = [ + ['DocType','Role'] + ,['Role','Administrator'] + ,['Role','Guest'] + ,['Role','All'] + ,['DocType','DocPerm'] + ,['DocType','DocFormat'] + ,['DocType','DocField'] + ,['DocType','DocType'] + ,['DocType','DefaultValue'] + ,['DocType','Profile'] + ,['DocType','UserRole'] + ] + + # import in sequence + for d in docs: + import_module.import_from_files(record_list=[['System',d[0],d[1]]]) + + # import all + import_module.import_from_files([['System']]) + + + # singles + # ------------------------------------------------------ + + def create_singles(self): + self.conn.sql("DROP TABLE IF EXISTS `tabSingles`") + self.conn.sql("""CREATE TABLE `tabSingles` ( + `doctype` varchar(40) default NULL, + `field` varchar(40) default NULL, + `value` text, + KEY `doctype` (`doctype`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # sessions + # ------------------------------------------------------ + + def create_sessions(self): + self.conn.sql("DROP TABLE IF EXISTS `tabSessions`;") + self.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 + ) ENGINE=MyISAM DEFAULT CHARSET=latin1;""") + + # doc type cache + # ------------------------------------------------------ + + def create_doctypecache(self): + self.conn.sql("DROP TABLE IF EXISTS `__DocTypeCache`") + self.conn.sql("create table `__DocTypeCache` (name VARCHAR(120), modified DATETIME, content TEXT, server_code_compiled TEXT)") + + + + + # Role + # ------------------------------------------------------ + + def create_role(self): + self.conn.sql("DROP TABLE IF EXISTS `tabRole`") + self.conn.sql("""CREATE TABLE `tabRole` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `role_name` varchar(180) default NULL, + `module` varchar(180) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocField + # ------------------------------------------------------ + + def create_docfield(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocField`") + self.conn.sql("""CREATE TABLE `tabDocField` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `fieldname` varchar(180) default NULL, + `label` varchar(180) default NULL, + `oldfieldname` varchar(180) default NULL, + `fieldtype` varchar(180) default NULL, + `oldfieldtype` varchar(180) default NULL, + `options` text, + `search_index` int(3) default NULL, + `hidden` int(3) default NULL, + `print_hide` int(3) default NULL, + `report_hide` int(3) default NULL, + `reqd` int(3) default NULL, + `no_copy` int(3) default NULL, + `allow_on_submit` int(3) default NULL, + `trigger` varchar(180) default NULL, + `depends_on` varchar(180) default NULL, + `permlevel` int(3) default NULL, + `width` varchar(180) default NULL, + `default` text, + `description` text, + `colour` varchar(180) default NULL, + `icon` varchar(180) default NULL, + `in_filter` int(3) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`), + KEY `label` (`label`), + KEY `fieldtype` (`fieldtype`), + KEY `fieldname` (`fieldname`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocPerm + # ------------------------------------------------------ + + def create_docperm(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocPerm`") + self.conn.sql("""CREATE TABLE `tabDocPerm` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `permlevel` int(11) default NULL, + `role` varchar(180) default NULL, + `match` varchar(180) default NULL, + `read` int(3) default NULL, + `write` int(3) default NULL, + `create` int(3) default NULL, + `submit` int(3) default NULL, + `cancel` int(3) default NULL, + `amend` int(3) default NULL, + `execute` int(3) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocFormat + # ------------------------------------------------------ + + def create_docformat(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocFormat`") + self.conn.sql("""CREATE TABLE `tabDocFormat` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `format` varchar(180) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocType + # ------------------------------------------------------ + + def create_doctype(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocType`") + self.conn.sql("""CREATE TABLE `tabDocType` ( + `name` varchar(180) NOT NULL default '', + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(180) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `search_fields` varchar(180) default NULL, + `issingle` int(1) default NULL, + `istable` int(1) default NULL, + `version` int(11) default NULL, + `module` varchar(180) default NULL, + `autoname` varchar(180) default NULL, + `name_case` varchar(180) default NULL, + `description` text, + `colour` varchar(180) default NULL, + `read_only` int(1) default NULL, + `in_create` int(1) default NULL, + `show_in_menu` int(3) default NULL, + `menu_index` int(11) default NULL, + `parent_node` varchar(180) default NULL, + `smallicon` varchar(180) default NULL, + `allow_print` int(1) default NULL, + `allow_email` int(1) default NULL, + `allow_copy` int(1) default NULL, + `allow_rename` int(1) default NULL, + `hide_toolbar` int(1) default NULL, + `hide_heading` int(1) default NULL, + `allow_attach` int(1) default NULL, + `use_template` int(1) default NULL, + `max_attachments` int(11) default NULL, + `section_style` varchar(180) default NULL, + `client_script` text, + `client_script_core` text, + `server_code` text, + `server_code_core` text, + `server_code_compiled` text, + `client_string` text, + `server_code_error` varchar(180) default NULL, + `print_outline` varchar(180) default NULL, + `dt_template` text, + `is_transaction_doc` int(1) default NULL, + `change_log` text, + `read_only_onload` int(1) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + def create_module_def(self): + self.conn.sql("DROP TABLE IF EXISTS `tabModule Def`") + self.conn.sql("CREATE TABLE `tabModule Def` (`name` varchar(120) NOT NULL, `creation` datetime default NULL, `modified` datetime default NULL,`modified_by` varchar(40) default NULL,`owner` varchar(40) default NULL,`docstatus` int(1) default '0', `parent` varchar(120) default NULL,`parentfield` varchar(120) default NULL, `parenttype` varchar(120) default NULL, `idx` int(8) default NULL,`module_name` varchar(180) default NULL,`doctype_list` text, PRIMARY KEY (`name`), KEY `parent` (`parent`)) ENGINE=InnoDB") + + + def post_cleanup(self): + self.conn.sql("use %s;" % self.db_name) + self.conn.sql("update tabProfile set password = password('admin') where name='Administrator'") + self.conn.sql("update tabDocType set server_code_compiled = NULL") diff --git a/cgi-bin/webnotes/install_lib/install.py b/cgi-bin/webnotes/install_lib/install.py new file mode 100755 index 0000000000..5612f36ce2 --- /dev/null +++ b/cgi-bin/webnotes/install_lib/install.py @@ -0,0 +1,232 @@ +import os,sys + +cgi_bin_path = os.path.sep.join(__file__.split(os.path.sep)[:-3]) + +sys.path.append(cgi_bin_path) + + + +# +# make a copy of defs.py (if not exists) +# +def copy_defs(): + global cgi_bin_path + if not os.path.exists(os.path.join(cgi_bin_path, 'webnotes', 'defs.py')): + ret = os.system('cp '+ os.path.join(cgi_bin_path, 'webnotes', 'defs_template.py')+\ + ' '+os.path.join(cgi_bin_path, 'webnotes', 'defs.py')) + print 'Made copy of defs.py' + +# +# Main Installer Class +# +class Installer: + def __init__(self, root_login, root_password): + + self.root_password = root_password + from webnotes.model.db_schema import DbManager + + self.conn = webnotes.db.Database(user=root_login, password=root_password) + webnotes.conn=self.conn + webnotes.session= {'user':'Administrator'} + self.dbman = DbManager(self.conn) + self.mysql_path = hasattr(defs, 'mysql_path') and webnotes.defs.mysql_path or '' + + # + # run framework related cleanups + # + def framework_cleanups(self, target): + self.dbman.drop_table('__DocTypeCache') + webnotes.conn.sql("create table `__DocTypeCache` (name VARCHAR(120), modified DATETIME, content TEXT, server_code_compiled TEXT)") + + # set the basic passwords + webnotes.conn.begin() + webnotes.conn.sql("update tabProfile set password = password('admin') where name='Administrator'") + webnotes.conn.commit() + + def import_core_module(self): + """ + Imports the "Core" module from .txt file and creates + Creates profile Administrator + """ + from webnotes.modules.import_module import import_module + from webnotes.modules.module_manager import reload_doc + + reload_doc('core','doctype','doctype') + reload_doc('core','doctype','docfield') + reload_doc('core','doctype','docperm') + + import_module('core') + + webnotes.conn.begin() + + from webnotes.model.doc import Document + p = Document('Profile') + p.name = p.first_name = 'Administrator' + p.email = 'admin@localhost' + p.save(new = 1) + + ur = Document('UserRole') + ur.parent = 'Administrator' + ur.role = 'Administrator' + ur.parenttype = 'Profile' + ur.parentfield = 'userroles' + p.enabled = 1 + ur.save(1) + + p = Document('Profile') + p.name = p.first_name = 'Guest' + p.email = 'guest@localhost' + p.enabled = 1 + p.save(new = 1) + + ur = Document('UserRole') + ur.parent = 'Guest' + ur.role = 'Guest' + ur.parenttype = 'Profile' + ur.parentfield = 'userroles' + ur.save(1) + + webnotes.conn.commit() + + # + # main script to create a database from + # + def import_from_db(self, target, source_path='', password = 'admin', verbose=0): + """ + a very simplified version, just for the time being..will eventually be deprecated once the framework stabilizes. + """ + + # get the path of the sql file to import + if not source_path: + source_path = os.path.join(os.path.sep.join(os.path.abspath(webnotes.__file__).split(os.path.sep)[:-3]), 'data', 'Framework.sql') + + # delete user (if exists) + self.dbman.delete_user(target) + + # create user and db + self.dbman.create_user(target,getattr(defs,'db_password',None)) + if verbose: print "Created user %s" % target + + # create a database + self.dbman.create_database(target) + if verbose: print "Created database %s" % target + + # grant privileges to user + self.dbman.grant_all_privileges(target,target) + if verbose: print "Granted privileges to user %s and database %s" % (target, target) + + # flush user privileges + self.dbman.flush_privileges() + + self.conn.use(target) + + # import in target + if verbose: print "Starting database import..." + self.dbman.restore_database(target, source_path, self.root_password) + if verbose: print "Imported from database %s" % source_path + + self.import_core_module() + + # framework cleanups + self.framework_cleanups(target) + if verbose: print "Ran framework startups on %s" % target + + return target + +def make_scheduler(root_login, root_password, verbose): + """ + Make the database where all scheduler events will be stored from multiple datbases + See webnotes.utils.scheduler for more information + """ + conn = webnotes.db.Database(user=root_login, password=root_password) + + from webnotes.model.db_schema import DbManager + + dbman = DbManager(conn) + + # delete user (if exists) + dbman.delete_user('master_scheduler') + + # create user and db + dbman.create_user('master_scheduler', getattr(defs,'db_password',None)) + if verbose: print "Created user master_scheduler" + + # create a database + dbman.create_database('master_scheduler') + if verbose: print "Created database master_scheduler" + + # grant privileges to user + dbman.grant_all_privileges('master_scheduler','master_scheduler') + + # flush user privileges + dbman.flush_privileges() + + conn.use('master_scheduler') + + # create events table + conn.sql("""create table Event( + `db_name` varchar(60), + `event` varchar(180), + `interval` int(20), + `next_execution` timestamp, + `recurring` int(1), + primary key (`db_name`, `event`), + index next_execution(next_execution) + )""") + + conn.sql("""create table EventLog( + `db_name` varchar(180), + `event` varchar(180), + `executed_on` timestamp, + `log` text, + index executed_on(executed_on)) + """) +# +# load the options +# +def get_parser(): + from optparse import OptionParser + + parser = OptionParser(usage="usage: %prog [options] ROOT_LOGIN ROOT_PASSWORD DBNAME") + parser.add_option("-x", "--database-password", dest="password", default="admin", help="Optional: New password for the Framework Administrator, default 'admin'") + parser.add_option("-s", "--source", dest="source_path", default=None, help="Optional: Path of the sql file from which you want to import the instance, default 'data/Framework.sql'") + + return parser + + +# +# execution here +# +if __name__=='__main__': + + parser = get_parser() + (options, args) = parser.parse_args() + + try: + + from webnotes import defs + import webnotes + import webnotes.db + except ImportError: + copy_defs() + from webnotes import defs + import webnotes + import webnotes.db + + if len(args)==3: + + root_login, root_password, db_name = args[0], args[1], args[2] + + if db_name=='master_scheduler': + make_scheduler(root_login, root_password, 1) + else: + inst = Installer(root_login, root_password) + + inst.import_from_db(db_name, source_path=options.source_path, \ + password = options.password, verbose = 1) + + + print "Database created, please edit defs.py to get started" + else: + parser.print_help() + diff --git a/cgi-bin/webnotes/model/__init__.py b/cgi-bin/webnotes/model/__init__.py new file mode 100644 index 0000000000..8a95daf0e9 --- /dev/null +++ b/cgi-bin/webnotes/model/__init__.py @@ -0,0 +1,205 @@ +# model __init__.py +import webnotes + +no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', 'Button', 'Image', 'Graph'] +default_fields = ['doctype','name','owner','creation','modified','modified_by','parent','parentfield','parenttype','idx','docstatus'] + +#================================================================================= + +def check_if_doc_is_linked(dt, dn): + """ + Raises excption if the given doc(dt, dn) is linked in another record. + """ + sql = webnotes.conn.sql + + ll = get_link_fields(dt) + for l in ll: + link_dt, link_field = l + issingle = sql("select issingle from tabDocType where name = '%s'" % link_dt) + + # no such doctype (?) + if not issingle: continue + + if issingle[0][0]: + item = sql("select doctype from `tabSingles` where field='%s' and value = '%s' and doctype = '%s' " % (link_field, dn, l[0])) + if item: + webnotes.msgprint("Cannot delete %s %s because it is linked in %s" % (dt, dn, item[0][0]), raise_exception=1) + + else: + item = sql("select name from `tab%s` where `%s`='%s' and docstatus!=2 limit 1" % (link_dt, link_field, dn)) + if item: + webnotes.msgprint("Cannot delete %s %s because it is linked in %s %s" % (dt, dn, link_dt, item[0][0]), raise_exception=1) + + +def delete_doc(doctype=None, name=None, doclist = None): + """ + Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record + """ + import webnotes.model.meta + sql = webnotes.conn.sql + + if not doctype: + doctype = webnotes.form_dict.get('dt') + name = webnotes.form_dict.get('dn') + if not doctype: + webnotes.msgprint('Nothing to delete!', raise_exception =1) + + tablefields = webnotes.model.meta.get_table_fields(doctype) + + # check if submitted + d = webnotes.conn.sql("select docstatus from `tab%s` where name=%s" % (doctype, '%s'), name) + if d and int(d[0][0]) == 1: + webnotes.msgprint("Submitted Record '%s' '%s' cannot be deleted" % (doctype, name)) + raise Exception + + # call on_trash if required + from webnotes.model.code import get_obj + if doclist: + obj = get_obj(doclist=doclist) + else: + obj = get_obj(doctype, name) + + if hasattr(obj,'on_trash'): + obj.on_trash() + + # check if links exist + check_if_doc_is_linked(doctype, name) + + try: + webnotes.conn.sql("delete from `tab%s` where name='%s' limit 1" % (doctype, name)) + for t in tablefields: + webnotes.conn.sql("delete from `tab%s` where parent = %s" % (t[0], '%s'), name) + except Exception, e: + if e.args[0]==1451: + webnotes.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name)) + + raise e + + return 'okay' + +#================================================================================= +# new feature added 9-Jun-10 to allow doctypes to have labels +def get_dt_labels(): + d = {} + try: + res = webnotes.conn.sql("select name, dt_label from `tabDocType Label`") + except: + return {} + + for r in res: + d[r[0]] = r[1] + + return d +#================================================================================= + +def get_search_criteria(dt): + import webnotes.model.doc + # load search criteria for reports (all) + dl = [] + try: # bc + sc_list = webnotes.conn.sql("select name from `tabSearch Criteria` where doc_type = '%s' or parent_doc_type = '%s' and (disabled!=1 OR disabled IS NULL)" % (dt, dt)) + for sc in sc_list: + dl += webnotes.model.doc.get('Search Criteria', sc[0]) + except Exception, e: + pass # no search criteria + return dl + + +# Rename Doc +#================================================================================= + +def get_link_fields(dt): + """ + Returns linked fields for dt as a tuple of (linked_doctype, linked_field) + """ + return webnotes.conn.sql("select parent, fieldname from tabDocField where parent not like 'old%%' and ((options = '%s' and fieldtype='Link') or (options = 'link:%s' and fieldtype='Select'))" % (dt, dt)) + +def rename(dt, old, new, is_doctype = 0): + """ + Renames a doc(dt, old) to doc(dt, new) and updates all linked fields of type "Link" or "Select" with "link:" + """ + sql = webnotes.conn.sql + + # rename doc + sql("update `tab%s` set name='%s' where name='%s'" % (dt, new, old)) + + # get child docs + ct = sql("select options from tabDocField where parent = '%s' and fieldtype='Table'" % dt) + for c in ct: + sql("update `tab%s` set parent='%s' where parent='%s'" % (c[0], new, old)) + + # get links (link / select) + ll = get_link_fields(dt) + for l in ll: + is_single = sql("select issingle from tabDocType where name = '%s'" % l[0]) + is_single = is_single and webnotes.utils.cint(is_single[0][0]) or 0 + if is_single: + sql("update `tabSingles` set value='%s' where field='%s' and value = '%s' and doctype = '%s' " % (new, l[1], old, l[0])) + else: + sql("update `tab%s` set `%s`='%s' where `%s`='%s'" % (l[0], l[1], new, l[1], old)) + + # doctype + if is_doctype: + sql("RENAME TABLE `tab%s` TO `tab%s`" % (old, new)) + + # get child docs (update parenttype) + ct = sql("select options from tabDocField where parent = '%s' and fieldtype='Table'" % new) + for c in ct: + sql("update `tab%s` set parenttype='%s' where parenttype='%s'" % (c[0], new, old)) + +#================================================================================= + +def clear_recycle_bin(): + """ + Clears temporary records that have been deleted + """ + sql = webnotes.conn.sql + + tl = sql('show tables') + total_deleted = 0 + for t in tl: + fl = [i[0] for i in sql('desc `%s`' % t[0])] + + if 'name' in fl: + total_deleted += sql("select count(*) from `%s` where name like '__overwritten:%%'" % t[0])[0][0] + sql("delete from `%s` where name like '__overwritten:%%'" % t[0]) + + if 'parent' in fl: + total_deleted += sql("select count(*) from `%s` where parent like '__oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like '__oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'old_parent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'old_parent:%%'" % t[0]) + + webnotes.msgprint("%s records deleted" % str(int(total_deleted))) + + +# Make Table Copy +#================================================================================= + +def copytables(srctype, src, srcfield, tartype, tar, tarfield, srcfields, tarfields=[]): + import webnotes.model.doc + + if not tarfields: + tarfields = srcfields + l = [] + data = webnotes.model.doc.getchildren(src.name, srctype, srcfield) + for d in data: + newrow = webnotes.model.doc.addchild(tar, tarfield, tartype, local = 1) + newrow.idx = d.idx + + for i in range(len(srcfields)): + newrow.fields[tarfields[i]] = d.fields[srcfields[i]] + + l.append(newrow) + return l + +# DB Exists +#================================================================================= + +def db_exists(dt, dn): + import webnotes + return webnotes.conn.exists(dt, dn) diff --git a/cgi-bin/webnotes/model/code.py b/cgi-bin/webnotes/model/code.py new file mode 100644 index 0000000000..dcebc823b9 --- /dev/null +++ b/cgi-bin/webnotes/model/code.py @@ -0,0 +1,223 @@ +""" +This is where all the plug-in code is executed. The standard method for DocTypes is declaration of a +standardized `DocType` class that has the methods of any DocType. When an object is instantiated using the +`get_obj` method, it creates an instance of the `DocType` class of that particular DocType and sets the +`doc` and `doclist` attributes that represent the fields (properties) of that record. + +methods in following modules are imported for backward compatibility + + * webnotes.* + * webnotes.utils.* + * webnotes.model.doc.* + * webnotes.model.doclist.* +""" +custom_class = ''' +# Please edit this list and import only required elements +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.doclist import getlist, copy_doclist +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 + +set = webnotes.conn.set +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value +in_transaction = webnotes.conn.in_transaction +convert_to_lists = webnotes.conn.convert_to_lists + +# ----------------------------------------------------------------------------------------- + +class CustomDocType(DocType): + def __init__(self, doc, doclist): + DocType.__init__(self, doc, doclist) +''' + + +#================================================================================= +# execute a script with a lot of globals - deprecated +#================================================================================= + +def execute(code, doc=None, doclist=[]): + """ + Execute the code, if doc is given, then return the instance of the `DocType` class created + """ + # functions used in server script of DocTypes + # -------------------------------------------------- + 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.doclist import getlist, copy_doclist + from webnotes import session, form, is_testing, msgprint, errprint + + import webnotes + + set = webnotes.conn.set + sql = webnotes.conn.sql + get_value = webnotes.conn.get_value + in_transaction = webnotes.conn.in_transaction + convert_to_lists = webnotes.conn.convert_to_lists + if webnotes.user: + get_roles = webnotes.user.get_roles + locals().update({'get_obj':get_obj, 'get_server_obj':get_server_obj, 'run_server_obj':run_server_obj, 'updatedb':updatedb, 'check_syntax':check_syntax}) + version = 'v170' + NEWLINE = '\n' + BACKSLASH = '\\' + + # execute it + # ----------------- + exec code in locals() + + # if doc + # ----------------- + if doc: + d = DocType(doc, doclist) + return d + + if locals().get('page_html'): + return page_html + + if locals().get('out'): + return out + +#================================================================================= +# load the DocType class from module & return an instance +#================================================================================= + +def get_custom_script(doctype, script_type): + """ + Returns custom script if set in doctype `Custom Script` + """ + import webnotes + try: + custom_script = webnotes.conn.sql("select script from `tabCustom Script` where dt=%s and script_type=%s", (doctype, script_type)) + except Exception, e: + if e.args[0]==1146: + return None + else: raise e + + if custom_script and custom_script[0][0]: + return custom_script[0][0] + +def get_server_obj(doc, doclist = [], basedoctype = ''): + """ + Returns the instantiated `DocType` object. Will also manage caching & compiling + """ + # for test + import webnotes + + + # get doctype details + module = webnotes.conn.get_value('DocType', doc.doctype, 'module') + + # no module specified (must be really old), can't get code so quit + if not module: + return + + module = module.replace(' ','_').lower() + dt = doc.doctype.replace(' ','_').lower() + + # import + try: + exec 'from %s.doctype.%s.%s import DocType' % (module, dt, dt) + except ImportError, e: + # declare it here + class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl + + # custom? + custom_script = get_custom_script(doc.doctype, 'Server') + if custom_script: + global custom_class + + exec custom_class + custom_script.replace('\t',' ') in locals() + + return CustomDocType(doc, doclist) + else: + return DocType(doc, doclist) + +#================================================================================= +# get object (from dt and/or dn or doclist) +#================================================================================= + +def get_obj(dt = None, dn = None, doc=None, doclist=[], with_children = 0): + """ + Returns the instantiated `DocType` object. Here you can pass the DocType and name (ID) to get the object. + If with_children is true, then all child records will be laoded and added in the doclist. + """ + if dt: + import webnotes.model.doc + + if not dn: + dn = dt + if with_children: + doclist = webnotes.model.doc.get(dt, dn, from_get_obj=1) + else: + doclist = webnotes.model.doc.get(dt, dn, with_children = 0, from_get_obj=1) + return get_server_obj(doclist[0], doclist) + else: + return get_server_obj(doc, doclist) + +#================================================================================= +# get object and run method +#================================================================================= + +def run_server_obj(server_obj, method_name, arg=None): + """ + Executes a method (`method_name`) from the given object (`server_obj`) + """ + if server_obj and hasattr(server_obj, method_name): + if arg: + return getattr(server_obj, method_name)(arg) + else: + return getattr(server_obj, method_name)() + else: + raise Exception, 'No method %s' % method_name + +#================================================================================= +# deprecated methods to keep v160 apps happy +#================================================================================= + +def updatedb(doctype, userfields = [], args = {}): + pass + +def check_syntax(code): + return '' + +#=================================================================================== +def get_code(module, dt, dn, extn, is_static=None, fieldname=None): + from webnotes.modules import scrub, get_module_path + import os, webnotes + + # get module (if required) + if not module: + module = webnotes.conn.sql("select module from `tab%s` where name=%s" % (dt,'%s'),dn)[0][0] + + # no module, quit + if not module: + return '' + + # file names + if scrub(dt) in ('page','doctype','search_criteria'): + dt, dn = scrub(dt), scrub(dn) + + # get file name + fname = dn + '.' + extn + if is_static: + fname = dn + '_static.' + extn + + # code + code = '' + try: + file = open(os.path.join(get_module_path(scrub(module)), dt, dn, fname), 'r') + code = file.read() + file.close() + except IOError, e: + # no file, try from db + if fieldname: + code = webnotes.conn.get_value(dt, dn, fieldname) + + return code diff --git a/cgi-bin/webnotes/model/db_schema.py b/cgi-bin/webnotes/model/db_schema.py new file mode 100644 index 0000000000..7b97a0cab2 --- /dev/null +++ b/cgi-bin/webnotes/model/db_schema.py @@ -0,0 +1,430 @@ +""" +Syncs a database table to the `DocType` (metadata) + +.. note:: This module is only used internally + +""" +import os +import webnotes + +type_map = { + 'currency': ('decimal', '14,2') + ,'int': ('int', '11') + ,'float': ('decimal', '14,6') + ,'check': ('int', '1') + ,'small text': ('text', '') + ,'long text': ('text', '') + ,'code': ('text', '') + ,'text editor': ('text', '') + ,'date': ('date', '') + ,'time': ('time', '') + ,'text': ('text', '') + ,'data': ('varchar', '180') + ,'link': ('varchar', '180') + ,'password': ('varchar', '180') + ,'select': ('varchar', '180') + ,'read only': ('varchar', '180') + ,'blob': ('longblob', '') +} + +default_columns = ['name', 'creation', 'modified', 'modified_by', 'owner', 'docstatus', 'parent',\ + 'parentfield', 'parenttype', 'idx'] + +default_shortcuts = ['_Login', '__user', '_Full Name', 'Today', '__today'] + + +from webnotes.utils import cint + +# ------------------------------------------------- +# Class database table +# ------------------------------------------------- + +class DbTable: + def __init__(self, doctype, prefix = 'tab'): + self.doctype = doctype + self.name = prefix + doctype + self.columns = {} + self.current_columns = {} + + # lists for change + self.add_column = [] + self.change_type = [] + self.add_index = [] + self.drop_index = [] + self.set_default = [] + + # load + self.get_columns_from_docfields() + + def create(self): + add_text = '' + + # columns + t = self.get_column_definitions() + if t: add_text += ',\n'.join(self.get_column_definitions()) + ',\n' + + # index + t = self.get_index_definitions() + if t: add_text += ',\n'.join(self.get_index_definitions()) + ',\n' + + # create table + webnotes.conn.sql("""create table `%s` ( + name varchar(120) not null primary key, + creation datetime, + modified datetime, + modified_by varchar(40), + owner varchar(40), + docstatus int(1) default '0', + parent varchar(120), + parentfield varchar(120), + parenttype varchar(120), + idx int(8), + %sindex parent(parent)) ENGINE=InnoDB""" % (self.name, add_text)) + + def get_columns_from_docfields(self): + fl = webnotes.conn.sql("SELECT * FROM tabDocField WHERE parent = '%s'" % self.doctype, as_dict = 1) + + for f in fl: + if not f.get('no_column'): + self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], f['fieldtype'], f.get('length'), f['default'], f['search_index'], f['options']) + + def get_columns_from_db(self): + self.show_columns = webnotes.conn.sql("desc `%s`" % self.name) + for c in self.show_columns: + self.current_columns[c[0]] = {'name': c[0], 'type':c[1], 'index':c[3], 'default':c[4]} + + def get_column_definitions(self): + column_list = [] + default_columns + ret = [] + for k in self.columns.keys(): + if k not in column_list: + d = self.columns[k].get_definition() + if d: + ret.append('`'+ k+ '` ' + d) + column_list.append(k) + return ret + + def get_index_definitions(self): + ret = [] + for k in self.columns.keys(): + if type_map.get(self.columns[k].fieldtype) and type_map.get(self.columns[k].fieldtype.lower())[0] not in ('text', 'blob'): + ret.append('index `' + k + '`(`' + k + '`)') + return ret + + + # GET foreign keys + def get_foreign_keys(self): + fk_list = [] + txt = webnotes.conn.sql("show create table `%s`" % self.name)[0][1] + for line in txt.split('\n'): + if line.strip().startswith('CONSTRAINT') and line.find('FOREIGN')!=-1: + try: + fk_list.append((line.split('`')[3], line.split('`')[1])) + except IndexError, e: + pass + + return fk_list + + # Drop foreign keys + def drop_foreign_keys(self): + if not self.drop_foreign_key: + return + + fk_list = self.get_foreign_keys() + + # make dictionary of constraint names + fk_dict = {} + for f in fk_list: + fk_dict[f[0]] = f[1] + + # drop + for col in self.drop_foreign_key: + webnotes.conn.sql("set foreign_key_checks=0") + webnotes.conn.sql("alter table `%s` drop foreign key `%s`" % (self.name, fk_dict[col.fieldname])) + webnotes.conn.sql("set foreign_key_checks=1") + + def sync(self): + if not self.name in DbManager(webnotes.conn).get_tables_list(webnotes.conn.cur_db_name): + self.create() + else: + self.alter() + + def alter(self): + self.get_columns_from_db() + for col in self.columns.values(): + col.check(self.current_columns.get(col.fieldname, None)) + + for col in self.add_column: + webnotes.conn.sql("alter table `%s` add column `%s` %s" % (self.name, col.fieldname, col.get_definition())) + + for col in self.change_type: + webnotes.conn.sql("alter table `%s` change `%s` `%s` %s" % (self.name, col.fieldname, col.fieldname, col.get_definition())) + + for col in self.add_index: + webnotes.conn.sql("alter table `%s` add index `%s`(`%s`)" % (self.name, col.fieldname, col.fieldname)) + + for col in self.drop_index: + if col.fieldname != 'name': # primary key + webnotes.conn.sql("alter table `%s` drop index `%s`" % (self.name, col.fieldname)) + + + for col in self.set_default: + webnotes.conn.sql("alter table `%s` alter column `%s` set default %s" % (self.name, col.fieldname, '%s'), col.default) + + +# ------------------------------------------------- +# Class database column +# ------------------------------------------------- + +class DbColumn: + def __init__(self, table, fieldname, fieldtype, length, default, set_index, options): + self.table = table + self.fieldname = fieldname + self.fieldtype = fieldtype + self.length = length + self.set_index = set_index + self.default = default + self.options = options + + def get_definition(self, with_default=1): + d = type_map.get(self.fieldtype.lower()) + + if not d: + return + + ret = d[0] + if d[1]: + ret += '(' + d[1] + ')' + if with_default and self.default and (self.default not in default_shortcuts): + ret += ' default "' + self.default.replace('"', '\"') + '"' + return ret + + def check(self, current_def): + column_def = self.get_definition(0) + + # no columns + if not column_def: + return + + # to add? + if not current_def: + self.fieldname = validate_column_name(self.fieldname) + self.table.add_column.append(self) + return + + # type + if current_def['type'] != column_def: + self.table.change_type.append(self) + + # index + else: + if (current_def['index'] and not self.set_index): + self.table.drop_index.append(self) + + if (not current_def['index'] and self.set_index and not (column_def in ['text','blob'])): + self.table.add_index.append(self) + + # default + if (self.default and (current_def['default'] != self.default) and (self.default not in default_shortcuts) and not (column_def in ['text','blob'])): + self.table.set_default.append(self) + + +class DbManager: + """ + Basically, a wrapper for oft-used mysql commands. like show tables,databases, variables etc... + + #TODO: + 0. Simplify / create settings for the restore database source folder + 0a. Merge restore database and extract_sql(from webnotes_server_tools). + 1. Setter and getter for different mysql variables. + 2. Setter and getter for mysql variables at global level?? + """ + def __init__(self,conn): + """ + Pass root_conn here for access to all databases. + """ + if conn: + self.conn = conn + + + def get_variables(self,regex): + """ + Get variables that match the passed pattern regex + """ + return list(self.conn.sql("SHOW VARIABLES LIKE '%s'"%regex)) + + + def drop_all_databases(self): + """ + Danger: will delete all databases except test,mysql. + """ + db_list = self.get_database_list() + for db in db_list: + self.drop_database(db) + + def get_table_schema(self,table): + """ + Just returns the output of Desc tables. + """ + return list(self.conn.sql("DESC %s"%table)) + + + def get_tables_list(self,target): + """ + + """ + try: + self.conn.use(target) + res = self.conn.sql("SHOW TABLES;") + table_list = [] + for table in res: + table_list.append(table[0]) + return table_list + + except Exception,e: + raise e + + def create_user(self,user,password): + #Create user if it doesn't exist. + try: + if password: + self.conn.sql("CREATE USER '%s'@'localhost' IDENTIFIED BY '%s';" % (user[:16], password)) + else: + self.conn.sql("CREATE USER '%s'@'localhost';"%user[:16]) + except Exception, e: + raise e + + + def delete_user(self,target): + # delete user if exists + try: + self.conn.sql("DROP USER '%s'@'localhost';" % target) + except Exception, e: + if e.args[0]==1396: + pass + else: + raise e + + def create_database(self,target): + + try: + self.conn.sql("CREATE DATABASE IF NOT EXISTS `%s` ;" % target) + except Exception,e: + raise e + + + def drop_database(self,target): + try: + self.conn.sql("DROP DATABASE IF EXISTS `%s`;"%target) + except Exception,e: + raise e + + def grant_all_privileges(self,target,user): + try: + self.conn.sql("GRANT ALL PRIVILEGES ON `%s` . * TO '%s'@'localhost';" % (target, user)) + except Exception,e: + raise e + + def grant_select_privilges(self,db,table,user): + try: + if table: + self.conn.sql("GRANT SELECT ON %s.%s to '%s'@'localhost';" % (db,table,user)) + else: + self.conn.sql("GRANT SELECT ON %s.* to '%s'@'localhost';" % (db,user)) + except Exception,e: + raise e + + def flush_privileges(self): + try: + self.conn.sql("FLUSH PRIVILEGES") + except Exception,e: + raise e + + + def get_database_list(self): + try: + db_list = [] + ret_db_list = self.conn.sql("SHOW DATABASES") + for db in ret_db_list: + if db[0] not in ['information_schema', 'mysql', 'test', 'accounts']: + db_list.append(db[0]) + return db_list + except Exception,e: + raise e + + def restore_database(self,target,source,root_password): + import webnotes.defs + mysql_path = getattr(webnotes.defs, 'mysql_path', None) + mysql = mysql_path and os.path.join(mysql_path, 'mysql') or 'mysql' + + try: + ret = os.system("%s -u root -p%s %s < %s"%(mysql, root_password, target, source)) + except Exception,e: + raise e + + def drop_table(self,table_name): + try: + self.conn.sql("DROP TABLE IF EXISTS %s "%(table_name)) + except Exception,e: + raise e + + def set_transaction_isolation_level(self,scope='SESSION',level='READ COMMITTED'): + #Sets the transaction isolation level. scope = global/session + try: + self.conn.sql("SET %s TRANSACTION ISOLATION LEVEL %s"%(scope,level)) + except Exception,e: + raise e + + + +# ------------------------------------------------- +# validate column name to be code-friendly +# ------------------------------------------------- + +def validate_column_name(n): + n = n.replace(' ','_').strip().lower() + import re + if not re.match("[a-zA-Z_][a-zA-Z0-9_]*$", n): + webnotes.msgprint('err:%s is not a valid fieldname.
A valid name must contain letters / numbers / spaces.
Tip: You can change the Label after the fieldname has been set' % n) + raise Exception + return n + +# ------------------------------------------------- +# sync table - called from form.py +# ------------------------------------------------- + +def updatedb(dt, archive=0): + """ + Syncs a `DocType` to the table + * creates if required + * updates columns + * updates indices + """ + res = webnotes.conn.sql("select ifnull(issingle, 0) from tabDocType where name=%s", dt) + if not res: + raise Exception, 'Wrong doctype "%s" in updatedb' % dt + + if not res[0][0]: + webnotes.conn.commit() + tab = DbTable(dt, archive and 'arc' or 'tab') + tab.sync() + webnotes.conn.begin() + +# patch to remove foreign keys +# ---------------------------- + +def remove_all_foreign_keys(): + webnotes.conn.sql("set foreign_key_checks = 0") + webnotes.conn.commit() + for t in webnotes.conn.sql("select name from tabDocType where ifnull(issingle,0)=0"): + dbtab = webnotes.model.db_schema.DbTable(t[0]) + try: + fklist = dbtab.get_foreign_keys() + except Exception, e: + if e.args[0]==1146: + fklist = [] + else: + raise e + + for f in fklist: + webnotes.conn.sql("alter table `tab%s` drop foreign key `%s`" % (t[0], f[1])) diff --git a/cgi-bin/webnotes/model/doc.py b/cgi-bin/webnotes/model/doc.py new file mode 100644 index 0000000000..f6dc31bbca --- /dev/null +++ b/cgi-bin/webnotes/model/doc.py @@ -0,0 +1,671 @@ +""" +Contains the Document class representing an object / record +""" + +import webnotes +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. + Stores,Retrieves,Updates the record in the corresponding table. + Runs the triggers required. + + The `Document` class represents the basic Object-Relational Mapper (ORM). The object type is defined by + `DocType` and the object ID is represented by `name`:: + + Please note the anamoly in the Web Notes Framework that `ID` is always called as `name` + + If both `doctype` and `name` are specified in the constructor, then the object is loaded from the database. + If only `doctype` is given, then the object is not loaded + If `fielddata` is specfied, then the object is created from the given dictionary. + + **Note 1:** + + The getter and setter of the object are overloaded to map to the fields of the object that + are loaded when it is instantiated. + + For example: doc.name will be the `name` field and doc.owner will be the `owner` field + + **Note 2 - Standard Fields:** + + * `name`: ID / primary key + * `owner`: creator of the record + * `creation`: datetime of creation + * `modified`: datetime of last modification + * `modified_by` : last updating user + * `docstatus` : Status 0 - Saved, 1 - Submitted, 2- Cancelled + * `parent` : if child (table) record, this represents the parent record + * `parenttype` : type of parent record (if any) + * `parentfield` : table fieldname of parent record (if any) + * `idx` : Index (sequence) of the child record + """ + + def __init__(self, doctype = '', name = '', fielddata = {}, prefix='tab'): + self._roles = [] + self._perms = [] + self._user_defaults = {} + self._prefix = prefix + + if fielddata: + self.fields = fielddata + else: + self.fields = {} + + if not self.fields.has_key('name'): + self.fields['name']='' # required on save + if not self.fields.has_key('doctype'): + self.fields['doctype']='' # required on save + if not self.fields.has_key('owner'): + self.fields['owner']='' # required on save + + if doctype: + self.fields['doctype'] = doctype + if name: + self.fields['name'] = name + self.__initialized = 1 + + if (doctype and name): + self._loadfromdb(doctype, name) + + def __nonzero__(self): + return True + + def __str__(self): + return str(self.fields) + + # Load Document + # --------------------------------------------------------------------------- + + def _loadfromdb(self, doctype = None, name = None): + if name: self.name = name + if doctype: self.doctype = doctype + + if webnotes.model.meta.is_single(self.doctype): + self._loadsingle() + else: + dataset = webnotes.conn.sql('select * from `%s%s` where name="%s"' % (self._prefix, self.doctype, self.name.replace('"', '\"'))) + if not dataset: + webnotes.msgprint('%s %s does not exist' % (self.doctype, self.name), 1) + raise Exception, '[WNF] %s %s does not exist' % (self.doctype, self.name) + self._load_values(dataset[0], webnotes.conn.get_description()) + + # Load Fields from dataset + # --------------------------------------------------------------------------- + + def _load_values(self, data, description): + for i in range(len(description)): + v = data[i] + self.fields[description[i][0]] = webnotes.conn.convert_to_simple_type(v) + + def _merge_values(self, data, description): + for i in range(len(description)): + v = data[i] + if v: # only if value, over-write + self.fields[description[i][0]] = webnotes.conn.convert_to_simple_type(v) + + # Load Single Type + # --------------------------------------------------------------------------- + + def _loadsingle(self): + self.name = self.doctype + dataset = webnotes.conn.sql("select field, value from tabSingles where doctype='%s'" % self.doctype) + for d in dataset: self.fields[d[0]] = d[1] + + # Setter + # --------------------------------------------------------------------------- + + def __setattr__(self, name, value): + # normal attribute + if not self.__dict__.has_key('_Document__initialized'): + self.__dict__[name] = value + elif self.__dict__.has_key(name): + self.__dict__[name] = value + else: + # field attribute + f = self.__dict__['fields'] + f[name] = value + + # Getter + # --------------------------------------------------------------------------- + + def __getattr__(self, name): + if self.__dict__.has_key(name): + return self.__dict__[name] + elif self.fields.has_key(name): + return self.fields[name] + else: + return '' + + # Get Amendement number + # --------------------------------------------------------------------------- + + def _get_amended_name(self): + am_id = 1 + am_prefix = self.amended_from + if webnotes.conn.sql('select amended_from from `tab%s` where name = "%s"' % (self.doctype, self.amended_from))[0][0] or '': + am_id = cint(self.amended_from.split('-')[-1]) + 1 + am_prefix = '-'.join(self.amended_from.split('-')[:-1]) # except the last hyphen + + self.name = am_prefix + '-' + str(am_id) + + # Set Name + # --------------------------------------------------------------------------- + + def _set_name(self, autoname, istable): + self.localname = self.name + + # get my object + import webnotes.model.code + so = webnotes.model.code.get_server_obj(self, []) + + # 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') + if r: return r + + # based on a field + elif autoname and autoname.startswith('field:'): + n = self.fields[autoname[6:]] + if not n: + raise Exception, 'Name is required' + self.name = n.strip() + + # based on expression + elif autoname and autoname.startswith('eval:'): + doc = self # for setting + self.name = eval(autoname[5:]) + + # call the method! + elif autoname and autoname!='Prompt': + self.name = make_autoname(autoname, self.doctype) + + # given + elif self.fields.get('__newname',''): + self.name = self.fields['__newname'] + + # default name for table + elif istable: + self.name = make_autoname('#########', self.doctype) + + # Validate Name + # --------------------------------------------------------------------------- + + def _validate_name(self, case): + + if webnotes.conn.sql('select name from `tab%s` where name=%s' % (self.doctype,'%s'), self.name): + raise NameError, 'Name %s already exists' % self.name + + # no name + if not self.name: return 'No Name Specified for %s' % self.doctype + + # new.. + if self.name.startswith('New '+self.doctype): + return 'There were some errors setting the name, please contact the administrator' + + if case=='Title Case': self.name = self.name.title() + if case=='UPPER CASE': self.name = self.name.upper() + + self.name = self.name.strip() # no leading and trailing blanks + + forbidden = ['%', "'", '"', ',', '#', '*', '?', '&', '`'] + for f in forbidden: + if f in self.name: + webnotes.msgprint('%s not allowed in ID (name)' % f, raise_exception =1) + + # Insert + # --------------------------------------------------------------------------- + + def _makenew(self, autoname, istable, case='', make_autoname=1): + # set owner + if not self.owner: self.owner = webnotes.session['user'] + + # set name + if make_autoname: + self._set_name(autoname, istable) + + # validate name + self._validate_name(case) + + # insert! + webnotes.conn.sql("""insert into `tab%s` (name, owner, creation, modified, modified_by) values ('%s', '%s', '%s', '%s', '%s')""" % (self.doctype, self.name, webnotes.session['user'], now(), now(), webnotes.session['user'])) + + + # Update Values + # --------------------------------------------------------------------------- + + def _update_single(self, link_list): + update_str = ["(%s, 'modified', %s)",] + values = [self.doctype, now()] + + webnotes.conn.sql("delete from tabSingles where doctype='%s'" % self.doctype) + for f in self.fields.keys(): + if not (f in ('modified', 'doctype', 'name', 'perm', 'localname', 'creation'))\ + and (not f.startswith('__')): # fields not saved + + # validate links + if link_list and link_list.get(f): + self.fields[f] = self._validate_link(link_list[f][0], self.fields[f]) + + if self.fields[f]==None: + update_str.append("(%s,%s,NULL)") + values.append(self.doctype) + values.append(f) + else: + update_str.append("(%s,%s,%s)") + values.append(self.doctype) + values.append(f) + values.append(self.fields[f]) + webnotes.conn.sql("insert into tabSingles(doctype, field, value) values %s" % (', '.join(update_str)), values) + + # Validate Links + # --------------------------------------------------------------------------- + + def validate_links(self, link_list): + err_list = [] + for f in self.fields.keys(): + # validate links + old_val = self.fields[f] + if link_list and link_list.get(f): + self.fields[f] = self._validate_link(link_list[f][0], self.fields[f]) + + if old_val and not self.fields[f]: + s = link_list[f][1] + ': ' + old_val + err_list.append(s) + + return err_list + + def make_link_list(self): + res = webnotes.model.meta.get_link_fields(self.doctype) + + link_list = {} + for i in res: link_list[i[0]] = (i[1], i[2]) # options, label + return link_list + + def _validate_link(self, dt, dn): + if not dt: return dn + if not dn: return None + if dt.lower().startswith('link:'): + dt = dt[5:] + if '\n' in dt: + dt = dt.split('\n')[0] + tmp = webnotes.conn.sql("""SELECT name FROM `tab%s` WHERE name = %s""" % (dt, '%s'), dn) + return tmp and tmp[0][0] or ''# match case + + # Update query + # --------------------------------------------------------------------------- + + def _update_values(self, issingle, link_list, ignore_fields=0): + if issingle: + self._update_single(link_list) + else: + update_str, values = [], [] + # set modified timestamp + self.modified = now() + self.modified_by = webnotes.session['user'] + for f in self.fields.keys(): + if (not (f in ('doctype', 'name', 'perm', 'localname', 'creation','_user_tags'))) \ + and (not f.startswith('__')): # fields not saved + + # validate links + if link_list and link_list.get(f): + self.fields[f] = self._validate_link(link_list[f][0], self.fields[f]) + + if self.fields[f]==None or self.fields[f]=='': + update_str.append("`%s`=NULL" % f) + if ignore_fields: + try: r = webnotes.conn.sql("update `tab%s` set `%s`=NULL where name=%s" % (self.doctype, f, '%s'), self.name) + except: pass + else: + values.append(self.fields[f]) + update_str.append("`%s`=%s" % (f, '%s')) + if ignore_fields: + try: r = webnotes.conn.sql("update `tab%s` set `%s`=%s where name=%s" % (self.doctype, f, '%s', '%s'), (self.fields[f], self.name)) + except: pass + if values: + if not ignore_fields: + # update all in one query + r = webnotes.conn.sql("update `tab%s` set %s where name='%s'" % (self.doctype, ', '.join(update_str), self.name), values) + + # Save values + # --------------------------------------------------------------------------- + + def save(self, new=0, check_links=1, ignore_fields=0, make_autoname = 1): + """ + Saves the current record in the database. If new = 1, creates a new instance of the record. + Also clears temperory fields starting with `__` + + * if check_links is set, it validates all `Link` fields + * if ignore_fields is sets, it does not throw an exception for any field that does not exist in the + database table + """ + res = webnotes.model.meta.get_dt_values(self.doctype, 'autoname, issingle, istable, name_case', as_dict=1) + res = res and res[0] or {} + + # if required, make new + if new or (not new and self.fields.get('__islocal')) and (not res.get('issingle')): + r = self._makenew(res.get('autoname'), res.get('istable'), res.get('name_case'), make_autoname) + if r: + return r + + # save the values + self._update_values(res.get('issingle'), check_links and self.make_link_list() or {}, ignore_fields) + self._clear_temp_fields() + + # check permissions + # --------------------------------------------------------------------------- + + def _get_perms(self): + if not self._perms: + self._perms = webnotes.conn.sql("select role, `match` from tabDocPerm where parent=%s and ifnull(`read`,0) = 1 and ifnull(permlevel,0)=0", self.doctype) + + def _get_roles(self): + # check if roles match/ + if not self._roles: + if webnotes.user: + self._roles = webnotes.user.get_roles() + else: + self._roles = ['Guest'] + + def _get_user_defaults(self): + if not self._user_defaults: + self._user_defaults = webnotes.user.get_defaults() + + def check_perm(self, verbose=0): + import webnotes + + # find roles with read access for this record at 0 + self._get_perms() + self._get_roles() + self._get_user_defaults() + + has_perm, match = 0, [] + + # loop through everything to find if there is a match + for r in self._perms: + if r[0] in self._roles: + has_perm = 1 + if r[1] and match != -1: + match.append(r[1]) # add to match check + else: + match = -1 # has permission and no match, so match not required! + + if has_perm and match and match != -1: + for m in match: + if self.fields.get(m, 'no value') in self._user_defaults.get(m, 'no default'): + has_perm = 1 + break # permission found! break + else: + has_perm = 0 + if verbose: + webnotes.msgprint("Value not allowed: '%s' for '%s'" % (self.fields.get(m, 'no value'), m)) + + + # check for access key + if webnotes.form and webnotes.form.has_key('akey'): + import webnotes.utils.encrypt + if webnotes.utils.encrypt.decrypt(webnotes.form.getvalue('akey')) == self.name: + has_perm = 1 + webnotes.response['print_access'] = 1 + + return has_perm + + # Cleanup + # --------------------------------------------------------------------------- + + def _clear_temp_fields(self): + # clear temp stuff + keys = self.fields.keys() + for f in keys: + if f.startswith('__'): + del self.fields[f] + + # Table methods + # --------------------------------------------------------------------------- + + def clear_table(self, doclist, tablefield, save=0): + """ + Clears the child records from the given `doclist` for a particular `tablefield` + """ + import webnotes.model.doclist + + for d in webnotes.model.doclist.getlist(doclist, tablefield): + d.fields['__oldparent'] = d.parent + d.parent = 'old_parent:' + d.parent # for client to send it back while saving + d.docstatus = 2 + if save and not d.fields.get('__islocal'): + d.save() + self.fields['__unsaved'] = 1 + + def addchild(self, fieldname, childtype = '', local=0, doclist=None): + """ + Returns a child record of the give `childtype`. + + * if local is set, it does not save the record + * if doclist is passed, it append the record to the doclist + """ + if not childtype: + childtype = db_getchildtype(self.doctype, fieldname) + + d = Document() + d.parent = self.name + d.parenttype = self.doctype + d.parentfield = fieldname + d.doctype = childtype + d.docstatus = 0; + d.name = '' + d.owner = webnotes.session['user'] + + if local: + d.fields['__islocal'] = '1' # for Client to identify unsaved doc + else: + d.save(new=1) + + if doclist != None: + doclist.append(d) + + return d + +def addchild(parent, fieldname, childtype = '', local=0, doclist=None): + """ + + Create a child record to the parent doc. + + Example:: + + c = Document('Contact','ABC') + d = addchild(c, 'contact_updates', 'Contact Update', local = 1) + d.last_updated = 'Phone call' + 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 +# ------ +def make_autoname(key, doctype=''): + """ + Creates an autoname from the given key: + + **Autoname rules:** + + * The key is separated by '.' + * '####' represents a series. The string before this part becomes the prefix: + Example: ABC.#### creates a series ABC0001, ABC0002 etc + * 'MM' represents the current month + * 'YY' and 'YYYY' represent the current year + + + *Example:* + + * DE/./.YY./.MM./.##### will create a series like + DE/09/01/0001 where 09 is the year, 01 is the month and 0001 is the series + """ + n = '' + l = key.split('.') + for e in l: + en = '' + if e.startswith('#'): + digits = len(e) + en = getseries(n, digits, doctype) + elif e=='YY': + import time + en = time.strftime('%y') + elif e=='MM': + import time + en = time.strftime('%m') + elif e=='YYYY': + import time + en = time.strftime('%Y') + else: en = e + n+=en + return n + +# Get Series for Autoname +# ----------------------- +def getseries(key, digits, doctype=''): + # series created ? + if webnotes.conn.sql("select name from tabSeries where name='%s'" % key): + + # yes, update it + webnotes.conn.sql("update tabSeries set current = current+1 where name='%s'" % key) + + # find the series counter + r = webnotes.conn.sql("select current from tabSeries where name='%s'" % key) + n = r[0][0] + else: + + # no, create it + webnotes.conn.sql("insert into tabSeries (name, current) values ('%s', 1)" % key) + n = 1 + return ('%0'+str(digits)+'d') % n + + +# Get Children +# ------------ + +def getchildren(name, childtype, field='', parenttype='', from_doctype=0, prefix='tab'): + import webnotes + + tmp = '' + + if field: + tmp = ' and parentfield="%s" ' % field + 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)) + desc = webnotes.conn.get_description() + except Exception, e: + if prefix=='arc' and e.args[0]==1146: + return [] + else: + raise e + + l = [] + + for i in dataset: + d = Document() + d.doctype = childtype + d._load_values(i, desc) + l.append(d) + + return l + +# Check if "Guest" is allowed to view this page +# --------------------------------------------- + +def check_page_perm(doc): + if doc.name=='Login Page': + return + if doc.publish: + return + + if not webnotes.conn.sql("select name from `tabPage Role` where parent=%s and role='Guest'", doc.name): + webnotes.response['exc_type'] = 'PermissionError' + raise Exception, '[WNF] No read permission for %s %s' % ('Page', doc.name) + +def get_report_builder_code(doc): + if doc.doctype=='Search Criteria': + from webnotes.model.code import get_code + + if doc.standard != 'No': + doc.report_script = get_code(doc.module, 'Search Criteria', doc.name, 'js') + doc.custom_query = get_code(doc.module, 'Search Criteria', doc.name, 'sql') + + +# called from everywhere +# load a record and its child records and bundle it in a list - doclist +# --------------------------------------------------------------------- + +def get(dt, dn='', with_children = 1, from_get_obj = 0, prefix = 'tab'): + """ + Returns a doclist containing the main record and all child records + """ + import webnotes + import webnotes.model + import webnotes.defs + + dn = dn or dt + + # load the main doc + doc = Document(dt, dn, prefix=prefix) + + # check permission - for doctypes, pages + if (dt in ('DocType', 'Page', 'Control Panel', 'Search Criteria')) or (from_get_obj and webnotes.session.get('user') != 'Guest'): + if dt=='Page' and webnotes.session['user'] == 'Guest': + check_page_perm(doc) + else: + if not doc.check_perm(): + webnotes.response['exc_type'] = 'PermissionError' + raise webnotes.ValidationError, '[WNF] No read permission for %s %s' % (dt, dn) + + # import report_builder code + get_report_builder_code(doc) + + if not with_children: + # done + return [doc,] + + # get all children types + tablefields = webnotes.model.meta.get_table_fields(dt) + + # load chilren + doclist = [doc,] + for t in tablefields: + doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix) + + return doclist diff --git a/cgi-bin/webnotes/model/doclist.py b/cgi-bin/webnotes/model/doclist.py new file mode 100644 index 0000000000..aff1ebbc6c --- /dev/null +++ b/cgi-bin/webnotes/model/doclist.py @@ -0,0 +1,191 @@ +import webnotes +import webnotes.model +import webnotes.model.doc + +def xzip(a,b): + d = {} + for i in range(len(a)): + d[a[i]] = b[i] + return d + +def expand(docs): + """ + Expand a doclist sent from the client side. (Internally used by the request handler) + """ + from webnotes.utils import load_json + + docs = load_json(docs) + clist = [] + for d in docs['_vl']: + doc = xzip(docs['_kl'][d[0]], d); + clist.append(doc) + return clist + +def compress(doclist): + """ + Compress a doclist before sending it to the client side. (Internally used by the request handler) + + """ + if doclist and hasattr(doclist[0],'fields'): + docs = [d.fields for d in doclist] + else: + docs = doclist + + kl, vl = {}, [] + for d in docs: + dt = d['doctype'] + if not (dt in kl.keys()): + fl = d.keys() + forbidden = ['server_code_compiled'] + nl = ['doctype','localname','__oldparent','__unsaved'] + + # add client script for doctype, doctype due to ambiguity + if dt=='DocType': nl.append('__client_script') + + for f in fl: + if not (f in nl) and not (f in forbidden): + nl.append(f) + kl[dt] = nl + + ## values + fl = kl[dt] + nl = [] + for f in fl: + v = d.get(f) + + if type(v)==long: + v=int(v) + nl.append(v) + vl.append(nl) + #errprint(str({'_vl':vl,'_kl':kl})) + return {'_vl':vl,'_kl':kl} + +# Get Children List (for scripts utility) +# --------------------------------------- + +def getlist(doclist, field): + """ + Filter a list of records for a specific field from the full doclist + + Example:: + + # find all phone call details + dl = getlist(self.doclist, 'contact_updates') + pl = [] + for d in dl: + if d.type=='Phone': + pl.append(d) + """ + + l = [] + for d in doclist: + if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field: + l.append(d) + return l + +# Copy doclist +# ------------ + +def copy_doclist(doclist, no_copy = []): + """ + Save & return a copy of the given doclist + Pass fields that are not to be copied in `no_copy` + """ + from webnotes.model.doc import Document + + cl = [] + + # main doc + c = Document(fielddata = doclist[0].fields.copy()) + + # clear no_copy fields + for f in no_copy: + if c.fields.has_key(f): + c.fields[f] = None + + c.name = None + c.save(1) + cl.append(c) + + # new parent name + parent = c.name + + # children + for d in doclist[1:]: + c = Document(fielddata = d.fields.copy()) + c.name = None + + # clear no_copy fields + for f in no_copy: + if c.fields.has_key(f): + c.fields[f] = None + + c.parent = parent + c.save(1) + cl.append(c) + + return cl + +# Validate Multiple Links +# ----------------------- + +def validate_links_doclist(doclist): + """ + Validate link fields and return link fields that are not correct. + Calls the `validate_links` function on the Document object + """ + ref, err_list = {}, [] + for d in doclist: + if not ref.get(d.doctype): + ref[d.doctype] = d.make_link_list() + + err_list += d.validate_links(ref[d.doctype]) + return ', '.join(err_list) + +# Get list of field values +# ------------------------ + +def getvaluelist(doclist, fieldname): + """ + Returns a list of values of a particualr fieldname from all Document object in a doclist + """ + l = [] + for d in doclist: + l.append(d.fields[fieldname]) + return l + +def _make_html(doc, link_list): + + from webnotes.utils import cstr + out = '' + for k in doc.fields.keys(): + if k!='server_code_compiled': + v = cstr(doc.fields[k]) + + # link field + if v and (k in link_list.keys()): + dt = link_list[k] + if type(dt)==str and dt.startswith('link:'): + dt = dt[5:] + v = '%s' % (dt, v, v) + + out += '\t\n' % (cstr(k), v) + + out += '
%s%s
' + return out + +def to_html(doclist): + """ +Return a simple HTML format of the doclist + """ + out = '' + link_lists = {} + + for d in doclist: + if not link_lists.get(d.doctype): + link_lists[d.doctype] = d.make_link_list() + + out += _make_html(d, link_lists[d.doctype]) + + return out + diff --git a/cgi-bin/webnotes/model/doctype.py b/cgi-bin/webnotes/model/doctype.py new file mode 100644 index 0000000000..ce61b3c8fd --- /dev/null +++ b/cgi-bin/webnotes/model/doctype.py @@ -0,0 +1,282 @@ +""" + DocType module + ============== + + This module has the DocType class that represents a "DocType" as metadata. + This is usually called by the form builder or report builder. + + Key functions: + * manage cache - read / write + * merge client-side scripts + * update properties from the modules .txt files + + Cache management: + * Cache is stored in __DocTypeCache +""" + +import webnotes +import webnotes.model +import webnotes.model.doclist +import webnotes.model.doc + +from webnotes.utils import cstr + +class _DocType: + """ + The _DocType object is created internally using the module's `get` method. + """ + def __init__(self, name): + self.name = name + + # is cache modified ? + # ================================================================= + + def is_modified(self): + """ + Returns true if modified + """ + try: + # doctype modified + modified = webnotes.conn.sql("select modified from tabDocType where name=%s", self.name)[0][0] + + # cache modified + cache_modified = webnotes.conn.sql("SELECT modified from `__DocTypeCache` where name='%s'" % self.name)[0][0] + + except IndexError, e: + return 1 + + return cache_modified != modified + + # write to cache + # ================================================================= + + def _update_cache(self, doclist): + import zlib + + if webnotes.conn.sql("SELECT name FROM __DocTypeCache WHERE name=%s", self.name): + webnotes.conn.sql("UPDATE `__DocTypeCache` SET `modified`=%s, `content`=%s WHERE name=%s", (doclist[0].modified, zlib.compress(str([d.fields for d in doclist]),2), self.name)) + else: + webnotes.conn.sql("INSERT INTO `__DocTypeCache` (`name`, `modified`, `content`) VALUES (%s, %s, %s)" , (self.name, doclist[0].modified, zlib.compress(str([d.fields for d in doclist])))) + + # read from cache + # ================================================================= + + def _load_from_cache(self): + import zlib + + doclist = eval(zlib.decompress(webnotes.conn.sql("SELECT content from `__DocTypeCache` where name=%s", self.name)[0][0])) + return [webnotes.model.doc.Document(fielddata = d) for d in doclist] + + + # load options for "link:" type 'Select' fields + # ================================================================= + + def _load_select_options(self, doclist): + for d in doclist: + if d.doctype=='DocField' and d.fieldtype=='Select' and d.options and d.options[:5].lower()=='link:': + op = d.options.split('\n') + if len(op)>1 and op[1][:4].lower() == 'sql:': + ol = webnotes.conn.sql(op[1][4:].replace('__user', webnotes.session['user'])) + else: + t = op[0][5:].strip() + op = op[1:] + op = [oc.replace('__user', webnotes.session['user']) for oc in op] + + try: + # select options will always come from the user db + ol = webnotes.conn.sql("select name from `tab%s` where %s docstatus!=2 order by name asc" % (t, op and (' AND '.join(op) + ' AND ') or '')) + except: + ol = [] + ol = [''] + [o[0] or '' for o in ol] + d.options = '\n'.join(ol) + + # clear un-necessary code from going to the client side + # ================================================================= + + def _clear_code(self, doclist): + if self.name != 'DocType': + if doclist[0].server_code: doclist[0].server_code = None + if doclist[0].server_code_core: doclist[0].server_code_core = None + if doclist[0].client_script: doclist[0].client_script = None + if doclist[0].client_script_core: doclist[0].client_script_core = None + doclist[0].server_code_compiled = None + + # build a list of all the records required for the DocType + # ================================================================= + + def _get_last_update(self, dt): + """ + Returns last update timestamp + """ + try: + last_update = webnotes.conn.sql("select _last_update from tabDocType where name=%s", dt)[0][0] + except Exception, e: + if e.args[0]==1054: + self._setup_last_update(dt) + last_update = None + + return last_update + + def _setup_last_update(self, doctype): + """ + Adds _last_update column to tabDocType + + """ + webnotes.conn.commit() + webnotes.conn.sql("alter table `tabDocType` add column _last_update varchar(32)") + webnotes.conn.begin() + + def _get_fields(self, file_name): + """ + Returns a dictionary of DocFields by fieldname or label + """ + try: + doclist = open(file_name, 'r').read() + except: + return + doclist = eval(doclist) + fields = {} + for d in doclist: + if d['doctype']=='DocField': + if d['fieldname'] or d['label']: + fields[d['fieldname'] or d['label']] = d + return fields + + def _update_field_properties(self, doclist): + """ + Updates properties like description, depends on from the database based on the timestamp + of the .txt file. Adds a column _last_updated if not exists in the database and uses + it to update the file.. + + This feature is built because description is changed / updated quite often and is tedious to + write a patch every time. Can be extended to cover more updates + """ + + update_fields = ('description', 'depends_on') + + from webnotes.modules import get_file_timestamp, get_item_file + + doc = doclist[0] # main doc + file_name = get_item_file(doc.module, 'DocType', doc.name) + time_stamp = get_file_timestamp(file_name) + last_update = self._get_last_update(doc.name) + + # this is confusing because we are updating the fields of fields + + if last_update != time_stamp: + + # there are updates! + fields = self._get_fields(file_name) + if fields: + for d in doclist: + + # for each field in teh outgoing doclist + if d.doctype=='DocField': + key = d.fieldname or d.label + + # if it has a fieldname or label + if key and key in fields: + + # update the values + for field_to_update in update_fields: + new_value = fields[key][field_to_update] + + # in doclist + d.fields[field_to_update] = new_value + + # in database + webnotes.conn.sql("update tabDocField set `%s` = %s where parent=%s and `%s`=%s" % \ + (field_to_update, '%s', '%s', (d.fieldname and 'fieldname' or 'label'), '%s'), \ + (new_value, doc.name, key)) + + webnotes.conn.sql("update tabDocType set _last_update=%s where name=%s", (time_stamp, doc.name)) + + def _override_field_properties(self, doclist): + """ + Override field properties that are updated by "Property Setter" + The term "property" is used to define a fieldname of a field to avoid confusing + terminology + """ + # load field properties and add them to a dictionary + property_dict = {} + dt = doclist[0].name + try: + for f in webnotes.conn.sql("select doc_name, property, property_type, value from `tabProperty Setter` where doc_type=%s", dt, as_dict=1): + if not f['doc_name'] in property_dict: + property_dict[f['doc_name']] = [] + property_dict[f['doc_name']].append(f) + except Exception, e: + if e.args[0]==1146: + # no override table + pass + else: + raise e + + # loop over fields and override property + for d in doclist: + if d.doctype=='DocField' and d.name in property_dict: + for p in property_dict[d.name]: + if p['property_type']=='Check': + d.fields[p['property']] = int(p['value']) + else: + d.fields[p['property']] = p['value'] + + # override properties in the main doctype + if dt in property_dict: + for p in property_dict[self.name]: + doclist[0].fields[p['property']] = p['value'] + + + def make_doclist(self): + """ + returns the :term:`doclist` for consumption by the client + + * it cleans up the server code + * executes all `$import` tags in client code + * replaces `link:` in the `Select` fields + * loads all related `Search Criteria` + * updates the cache + """ + from webnotes.modules import compress + + tablefields = webnotes.model.meta.get_table_fields(self.name) + + if self.is_modified(): + # yes + doclist = webnotes.model.doc.get('DocType', self.name, 1) + + self._update_field_properties(doclist) + self._override_field_properties(doclist) + + # table doctypes + for t in tablefields: + table_doclist = webnotes.model.doc.get('DocType', t[0], 1) + + self._override_field_properties(table_doclist) + doclist += table_doclist + + # don't save compiled server code + + else: + doclist = self._load_from_cache() + + doclist[0].fields['__client_script'] = compress.get_doctype_js(self.name) + self._load_select_options(doclist) + self._clear_code(doclist) + + return doclist + +def clear_cache(): + webnotes.conn.sql("delete from __DocTypeCache") + +# Load "DocType" - called by form builder, report buider and from code.py (when there is no cache) +#================================================================================================= + +def get(dt): + """ + Load "DocType" - called by form builder, report buider and from code.py (when there is no cache) + """ + doclist = _DocType(dt).make_doclist() + + return doclist + diff --git a/cgi-bin/webnotes/model/import_docs.py b/cgi-bin/webnotes/model/import_docs.py new file mode 100644 index 0000000000..44c872c920 --- /dev/null +++ b/cgi-bin/webnotes/model/import_docs.py @@ -0,0 +1,415 @@ +import webnotes + +def import_docs(docs = []): + from webnotes.model.doc import Document + import webnotes.model.code + + doc_list = {} + created_docs = [] + already_exists = [] + + out, tmp ="", "" + + for d in docs: + cur_doc = Document(fielddata = d) + if not cur_doc.parent in already_exists: # parent should not exist + try: + cur_doc.save(1) + out += "Created: " + cur_doc.name + "\n" + created_docs.append(cur_doc) + + # make in groups + if cur_doc.parent: + if not doc_list.has_key(cur_doc.parent): + doc_list[cur_doc.parent] = [] + doc_list[cur_doc.parent].append(cur_doc) + + except Exception, e: + out += "Creation Warning/Error: " + cur_doc.name + " :"+ str(e) + "\n" + already_exists.append(cur_doc.name) + + # Run scripts for main docs + for m in created_docs: + if doc_list.has_key(m.name): + tmp = webnotes.model.code.run_server_obj(webnotes.model.code.get_server_obj(m, doc_list.get(m.name, [])),'on_update') + + # update database (in case of DocType) + if m.doctype=='DocType': + import webnotes.model.doctype + try: webnotes.model.doctype.update_doctype(doc_list.get(m.name, [])) + except: pass + out += 'Executed: '+ str(m.name) + ', Err:' + str(tmp) + "\n" + + return out + +#====================================================================================================================================== + +import webnotes +import webnotes.utils +sql = webnotes.conn.sql +flt = webnotes.utils.flt +cint = webnotes.utils.cint +cstr = webnotes.utils.cstr + +class CSVImport: + def __init__(self): + self.msg = [] + self.csv_data = None + self.import_date_format = None + + def validate_doctype(self, dt_list): + cl, tables, self.dt_list, self.prompt_autoname_flag = 0, [t[0] for t in sql("show tables")], [], 0 + self.msg.append('

Identifying Documents

') + dtd = sql("select name, istable, autoname from `tabDocType` where name = '%s' " % dt_list[0]) + if dtd and dtd[0][0]: + self.msg.append('
Identified Document: ' + dt_list[0] + '
') + self.dt_list.append(dt_list[0]) + if dtd[0][2] and 'Prompt' in dtd[0][2]: self.prompt_autoname_flag = 1 + if flt(dtd[0][1]): + res1 = sql("select parent, fieldname from tabDocField where options='%s' and fieldtype='Table' and docstatus!=2" % self.dt_list[0]) + if res1 and res1[0][0] == dt_list[1]: + self.msg.append('
Identified Document: ' + dt_list[1] + '
') + self.dt_list.append(dt_list[1]) + else : + self.msg.append('
Error: At Row 1, Column 2 => %s is not a valid Document
' % dt_list[1]) + self.validate_success = 0 + + if res1 and res1[0][1] == dt_list[2]: + self.msg.append('
Identified Document Fieldname: ' + dt_list[2] + '
') + self.dt_list.append(dt_list[2]) + else : + self.msg.append('
Error: At Row 1, Column 3 => %s is not a valid Fieldname
' % dt_list[2]) + self.validate_success = 0 + elif dt_list[1]: + self.msg.append('
Error: At Row 1, Column 1 => %s is not a Table.
' % dt_list[0]) + self.validate_success = 0 + else: + self.msg.append('
Error: At Row 1, Column 1 => %s is not a valid Document
' % dt_list[0]) + self.validate_success = 0 + + + def validate_fields(self, lb_list): + self.msg.append('

Checking fieldnames for %s

' % self.dt_list[0]) + if len(self.dt_list) > 1 and self.overwrite: + self.msg.append('
Error: Overwrite is not possible for Document %s
' % self.dt_list[0]) + self.validate_success = 0 + return + + elif self.overwrite and 'Name' != lb_list[0]: + self.msg.append('
Error : At Row 4 and Column 1: To Overwrite fieldname should be Name
') + self.validate_success = 0 + return + # labelnames + res = self.validate_success and [d[0] for d in sql("select label from tabDocField where parent='%s' and docstatus!=2 and ifnull(hidden,'') in ('',0)" % self.dt_list[0])] or [] + + if len(self.dt_list) > 1 and self.dt_list[1]: + self.fields.append('parent') + lb_list.pop(lb_list.index(self.dt_list[1])) + + dtd = sql("select autoname from `tabDocType` where name = '%s' " % self.dt_list[0])[0][0] + if self.prompt_autoname_flag or self.overwrite: + self.fields.append('name') + res.append('Name') + lb_list.pop(lb_list.index('Name')) + + cl = 1 + for l in lb_list: + try: + if l: + if not (l in res): + self.msg.append('
Error : At Row 4 and Column %s Field %s is not present in %s
' % (cl, l, self.dt_list[0])) + self.validate_success = 0 + # this condition is for child doctype + + else: self.fields.append(sql("select fieldname from tabDocField where parent ='%s' and label = '%s' and ifnull(fieldname,'') !='' " % (self.dt_list[0], l))[0][0] or '') + except Exception, e: + self.msg.append('
At Row 4 and Column %s : =>ERROR: %s
' % ( cl, e)) + self.validate_success = 0 + cl = cl + 1 + + if not self.overwrite: + # get_reqd_fields + reqd_list = [d[0] for d in sql("select label from `tabDocField` where parent = '%s' and ifnull(reqd,'') not in ('', 0) and docstatus !=2" % self.dt_list[0]) if d[0] not in lb_list] or [] + + # Check if Reqd field not present in self.fields + if reqd_list: + self.msg.append('
Error : At Row 4 Mandatory Fields %s of Document %s are Required.
' %(reqd_list , self.dt_list[0])) + self.validate_success = 0 + if self.validate_success: + self.msg.append('
Fields OK for %s
' % self.dt_list[0]) + + def validate_headers(self): + self.validate_doctype(self.doctype_data) + if self.validate_success: + self.validate_fields(self.labels) + + # Date parsing + # -------------------------------------------------------------------- + def parse_date(self, r, c, d): + out = '' + try: + if self.import_date_format=='yyyy-mm-dd': + tmpd = d.split('-') + + if len(tmpd)==3: + out = tmpd[0] + '-'+tmpd[1] + '-' + tmpd[2] + + elif d and self.import_date_format=='dd-mm-yyyy': + tmpd = d.split('-') + + if len(tmpd)==3: + out = tmpd[2]+'-'+tmpd[1]+'-'+tmpd[0] + + elif d and self.import_date_format=='mm/dd/yyyy': + tmpd = d.split('/') + + if len(tmpd)==3: + out = tmpd[2]+'-'+tmpd[0]+'-'+tmpd[1] + + elif d and self.import_date_format=='mm/dd/yy': + tmpd = d.split('/') + + if len(tmpd)==3: + out = '20'+tmpd[2]+'-'+tmpd[0]+'-'+tmpd[1] + + elif d and self.import_date_format=='dd/mm/yyyy': + tmpd = d.split('/') + if len(tmpd)==3: + out = tmpd[2]+'-'+tmpd[1]+'-'+tmpd[0] + + elif d and self.import_date_format=='dd/mm/yy': + tmpd = d.split('/') + if len(tmpd)==3: + out = '20'+tmpd[2]+'-'+tmpd[1]+'-'+tmpd[0] + + if len(tmpd) != 3: + self.msg.append('
At Row %s and Column %s : => Date Format selected as %s does not match with Date Format in File
' % (r, c, str(self.import_date_format))) + self.validate_success = 0 + else: + + import datetime + dt = out.split('-') + datetime.date(int(dt[0]),int(dt[1]), int(dt[2])) + except Exception, e: + self.msg.append('
At Row %s and Column %s : =>ERROR: %s
' % (r, c, e)) + self.validate_success = 0 + self.msg.append(out) + return out + + def check_select_link_data(self, r, c, f, d, s = '', l = ''): + options = '' + try: + if d and f: + dt = sql("select options, label from `tabDocField` where fieldname ='%s' and parent = '%s' " % (f, self.dt_list[0])) + dt, lbl = (dt and dt[0][0] and dt[0][0].strip() or None), dt and dt[0][1].strip() + if dt: + options = l and dt and [n[0] for n in sql("select name from `tab%s` " % (('link:' in dt and dt[5:]) or dt))] or s and dt.split('\n') or '' + if options and d not in options : + msg = '
At Row ' + str(r) + ' and Column ' + str(c)+ ' : => Data "' + str(d) + '" in field ['+ str(lbl) +'] Not Found in ' + msg = msg.__add__( s and str( 'Select Options [' +str(dt.replace('\n', ',')) +']' ) or str('Master ' + str('link:' in dt and dt[5:] or dt))) + msg = msg.__add__('
\n') + self.msg.append(msg) + + self.validate_success = 0 + except Exception, e: + self.msg.append('
ERROR: %s
' % (str(webnotes.utils.getTraceback()))) + self.validate_success = 0 + return d + + + def get_field_type_list(self): + # get_date_fields + date_list = [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and fieldtype='Date' and docstatus !=2" % self.dt_list[0])] + + # get_link_fields + link_list = [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and ((fieldtype='Link' and ifnull(options,'') != '') or (fieldtype='Select' and ifnull(options,'') like '%%link:%%')) and docstatus !=2 " % self.dt_list[0])] + + # get_select_fileds + select_list = [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and fieldtype='Select' and ifnull(options,'') not like '%%link:%%' and docstatus !=2" % self.dt_list[0])] + + # get_reqd_fields + reqd_list = self.overwrite and ['name'] or [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and ifnull(reqd,'') not in ('', 0) and docstatus !=2" % self.dt_list[0])] + + if len(self.dt_list)> 1 and 'parent' not in reqd_list: reqd_list.append('parent') + + if self.prompt_autoname_flag and 'name' not in reqd_list: reqd_list.append('name') + + return date_list, link_list, select_list, reqd_list + + + def validate_data(self): + self.msg.append('

Checking Data for %s

' % self.dt_list[0]) + date_list, link_list, select_list, reqd_list = self.get_field_type_list() + + + # load data + row = 5 + for d in self.data: + self.validate_success, fd, col = 1, {}, 1 + self.msg.append('

Checking Row %s

' % (row)) + for i in range(len(d)): + if i < len(self.fields): + f = self.fields[i] + try: + # Check Reqd Fields + if (f in reqd_list) and not d[i]: + self.msg.append('
Error: At Row %s and Column %s, Field %s is Mandatory.
' % (row, col, f)) + self.validate_success = 0 + + # Check Date Fields + if d[i] and f and f in date_list : fd[f] = self.parse_date(row, col, d[i]) + + # Check Link Fields + elif d[i] and f in link_list: + fd[f] = self.check_select_link_data(row, col, f, d[i], l='Link') + + # Check Select Fields + elif d[i] and f in select_list: + fd[f] = self.check_select_link_data(row, col, f, d[i], s= 'Select') + + # Need To Perform Check For Other Data Type Too + else: fd[f] = d[i] + + except Exception: + self.msg.append('
ERROR: %sData:%s and %s and %s and %s
' % (str(webnotes.utils.getTraceback()) + '\n', str(d), str(f), str(date_list), str(link_list))) + self.validate_success = 0 + elif d[i]: + self.validate_success = 0 + self.msg.append('
At Row %s and Column %s
' % (row,col)) + self.msg.append('
Ignored
') + col = col + 1 + if self.validate_success: + self.msg.append('
At Row %s and Column %s, Data Verification Completed
' % (row,col)) + self.update_data(fd,row) + row = row + 1 + + def update_data(self, fd, row): + # load metadata + from webnotes.model.doc import Document + cur_doc = Document(fielddata = fd) + cur_doc.doctype, cur_doc.parenttype, cur_doc.parentfield = self.dt_list[0], len(self.dt_list) > 1 and self.dt_list[1] or '', len(self.dt_list) > 1 and self.dt_list[2] or '' + obj = '' + # save the document + try: + if webnotes.conn.in_transaction: + sql("COMMIT") + sql("START TRANSACTION") + if cur_doc.name and webnotes.conn.exists(self.dt_list[0], cur_doc.name): + if self.overwrite: + cur_doc.save() + obj = webnotes.model.code.get_obj(cur_doc.parent and cur_doc.parent_type or cur_doc.doctype, cur_doc.parent or cur_doc.name, with_children = 1) + self.msg.append('
Row %s => Over-written: %s
' % (row, cur_doc.name)) + else: + self.msg.append('
Row %s => Ignored: %s
' % (row, cur_doc.name)) + else: + if cur_doc.parent and webnotes.conn.exists(cur_doc.parenttype, cur_doc.parent) or not cur_doc.parent: + cur_doc.save(1) + obj = webnotes.model.code.get_obj(cur_doc.parent and cur_doc.parenttype or cur_doc.doctype, cur_doc.parent or cur_doc.name, with_children = 1) + self.msg.append('
Row %s => Created: %s
' % (row, cur_doc.name)) + else: + self.msg.append('
Row %s => Invalid %s : %s
' % (row, cur_doc.parenttype, cur_doc.parent)) + except Exception: + self.msg.append('
Validation: %s
' % str(webnotes.utils.getTraceback())) + try: + if obj: + if hasattr(obj, 'validate') : obj.validate() + if hasattr(obj, 'on_update') : obj.on_update() + if hasattr(obj, 'on_submit') : obj.on_submit() + sql("COMMIT") + + except Exception: + sql("ROLLBACK") + self.msg.append('
Validation: %s
' % str(webnotes.message_log[-1:])) + + # do import + # -------------------------------------------------------------------- + def import_csv(self, csv_data, import_date_format = 'yyyy-mm-dd', overwrite = 0): + import csv + self.validate_success, self.csv_data = 1, self.convert_csv_data_into_list(csv.reader(csv_data.splitlines())) + self.import_date_format, self.overwrite = import_date_format, overwrite + if len(self.csv_data) > 4: + + self.doctype_data, self.labels, self.data = self.csv_data[0][:4], self.csv_data[3], self.csv_data[4:] + self.fields = [] + + import webnotes.model.code + from webnotes.model.doc import Document + sql = webnotes.conn.sql + + self.validate_headers() + if self.validate_success: + self.validate_data() + else: + self.msg.append('

No data entered in file.

') + return '\n'.join(self.msg) + + def convert_csv_data_into_list(self,csv_data): + st_list = [] + for s in csv_data: + st_list.append([d.strip() for d in s]) + return st_list + +# Get Template method +# ----------------------------------------------------------------- + +def get_template(): + import webnotes.model + + from webnotes.utils import getCSVelement + + form = webnotes.form + sql = webnotes.conn.sql + # get form values + dt = form.getvalue('dt') + overwrite = cint(form.getvalue('overwrite')) or 0 + + pt, pf = '', '' + tmp_lbl, tmp_ml = [],[] + + # is table? + dtd = sql("select istable, autoname from tabDocType where name='%s'" % dt) + if dtd and dtd[0][0]: + res1 = sql("select parent, fieldname from tabDocField where options='%s' and fieldtype='Table' and docstatus!=2" % dt) + if res1: + pt, pf = res1[0][0], res1[0][1] + + # line 1 + dset = [] + if pt and pf: + lbl, ml = [pt], ['[Mandatory]'] + line1 = '%s,%s,%s' % (getCSVelement(dt), getCSVelement(pt), getCSVelement(pf)) + line2 = ',,,,,,Please fill valid %(p)s No in %(p)s column.' % {'p':getCSVelement(pt)} + else: + if dtd[0][1]=='Prompt' or overwrite: + lbl, ml= ['Name'], ['[Mandatory][Special Characters are not allowed]'] + else: + lbl, ml= [], [] + line1 = '%s' % getCSVelement(dt) + line2 = (overwrite and ',,,,,,Please fill valid %(d)s No in %(n)s' % {'d':dt,'n': 'Name'}) or ',,' + + # Help on Line + line1 = line1 + ',,,Please fill columns which are Mandatory., Please do not modify the structure' + + # fieldnames + res = sql("select fieldname, fieldtype, label, reqd, hidden from tabDocField where parent='%s' and docstatus!=2" % dt) + + for r in res: + # restrict trash_reason field, hidden and required fields + if not r[1] in webnotes.model.no_value_fields and r[0] != 'trash_reason' and not r[4] and not r[3]: + tmp_lbl.append(getCSVelement(r[2])) + tmp_ml.append('') + # restrict trash_reason field and hidden fields and add Mandatory indicator for required fields + elif not r[1] in webnotes.model.no_value_fields and r[0] != 'trash_reason' and not r[4] and r[3]: + lbl.append(getCSVelement(r[2])) + ml.append(getCSVelement('[Mandatory]')) + + dset.append(line1) + dset.append(line2) + dset.append(','.join(ml + tmp_ml)) + dset.append(','.join(lbl + tmp_lbl)) + + txt = '\n'.join(dset) + webnotes.response['result'] = txt + webnotes.response['type'] = 'csv' + webnotes.response['doctype'] = dt + diff --git a/cgi-bin/webnotes/model/meta.py b/cgi-bin/webnotes/model/meta.py new file mode 100644 index 0000000000..f9fa156e33 --- /dev/null +++ b/cgi-bin/webnotes/model/meta.py @@ -0,0 +1,57 @@ +# metadata + +import webnotes + +#================================================================================= + +def get_dt_values(doctype, fields, as_dict = 0): + return webnotes.conn.sql('SELECT %s FROM tabDocType WHERE name="%s"' % (fields, doctype), as_dict = as_dict) + +def set_dt_value(doctype, field, value): + return webnotes.conn.set_value('DocType', doctype, field, value) + +def is_single(doctype): + try: + return get_dt_values(doctype, 'issingle')[0][0] + except IndexError, e: + raise Exception, 'Cannot determine whether %s is single' % doctype + +#================================================================================= + +def get_parent_dt(dt): + parent_dt = webnotes.conn.sql('select parent from tabDocField where fieldtype="Table" and options="%s" and (parent not like "old_parent:%%") limit 1' % dt) + return parent_dt and parent_dt[0][0] or '' + +#================================================================================= + +def set_fieldname(field_id, fieldname): + webnotes.conn.set_value('DocField', field_id, 'fieldname', fieldname) + +#================================================================================= + +def get_link_fields(doctype): + return webnotes.conn.sql("SELECT fieldname, options, label FROM tabDocField WHERE parent='%s' and (fieldtype='Link' or (fieldtype='Select' and `options` like 'link:%%'))" % (doctype)) + +#================================================================================= + +def get_table_fields(doctype): + return webnotes.conn.sql("select options, fieldname from tabDocField where parent='%s' and fieldtype='Table'" % doctype) + +#================================================================================= + +def get_search_criteria(dt): + import webnotes.model.doc + # load search criteria for reports (all) + dl = [] + sc_list = webnotes.conn.sql("select name from `tabSearch Criteria` where doc_type = '%s' or parent_doc_type = '%s' and (disabled!=1 OR disabled IS NULL)" % (dt, dt)) + for sc in sc_list: + if sc[0]: + dl += webnotes.model.doc.get('Search Criteria', sc[0]) + return dl + +#================================================================================= + +def get_print_format_html(name): + html = webnotes.conn.sql('select html from `tabPrint Format` where name="%s"' % name) + return html and html[0][0] or '' + \ No newline at end of file diff --git a/cgi-bin/webnotes/model/modules.py b/cgi-bin/webnotes/model/modules.py new file mode 100644 index 0000000000..f979273a39 --- /dev/null +++ b/cgi-bin/webnotes/model/modules.py @@ -0,0 +1,26 @@ +# Modules +# ----------- + +def get_module_items(mod, only_dt=0): + dl = [] + if only_dt: + transfer_types = ['DocType'] + else: + transfer_types = ['Role', 'Page', 'DocType', 'DocType Mapper', 'Search Criteria'] + dl = ['Module Def,'+mod] + + for dt in transfer_types: + try: + dl2 = sql('select name from `tab%s` where module="%s"' % (dt,mod)) + dl += [(dt+','+e[0]) for e in dl2] + except: + pass + + if not only_dt: + dl1 = sql('select doctype_list from `tabModule Def` where name=%s', mod) + dl += dl1[0][0].split('\n') + + # build finally + dl = [e.split(',') for e in dl] + dl = [[e[0].strip(), e[1].strip()] for e in dl] # remove blanks + return dl \ No newline at end of file diff --git a/cgi-bin/webnotes/model/triggers.py b/cgi-bin/webnotes/model/triggers.py new file mode 100644 index 0000000000..34654492dc --- /dev/null +++ b/cgi-bin/webnotes/model/triggers.py @@ -0,0 +1,68 @@ +""" +Add, manage, fire triggers (events / observers) +Standard events called by the framework are "save, submit, cancel" +""" + +import webnotes + +def insert_trigger(doctype, docname, event_name, method): + "inserts a new trigger record" + + from webnotes.model.doc import Document + d = Document('DocTrigger') + d.doc_type = doctype + d.doc_name = docname + d.event_name = event_name + d.method = method + d.save(1) + +def add_trigger(doctype, docname, event_name, method): + """Add a trigger to an event on a doctype, docname. The specified method will be called. + Wild card '*' is allowed in doctype, docname and/or event_name""" + + try: + if not trigger_exists(doctype, docname, event_name, method): + insert_trigger(doctype, docname, event_name, method) + except Exception, e: + if e.args[0]==1146: + setup() + insert_trigger(doctype, docname, event_name, method) + else: raise e + +def trigger_exists(doctype, docname, event_name, method): + "returns true if trigger exists" + return webnotes.conn.sql("select name from tabDocTrigger where doc_name=%s and doc_type=%s and event_name=%s and method=%s", \ + (doctype, docname, event_name, method)) + +def remove_trigger(doctype, docname, event_name, method): + "Remove a trigger on an event" + webnotes.conn.sql("delete from tabDocTrigger where doc_name=%s and doc_type=%s and event_name=%s and method=%s", \ + (doctype, docname, event_name, method)) + +def fire_event(doc, event_name): + "Fire all triggers on an event and passes the doc to the trigger" + try: + tl = webnotes.conn.sql("""select method from tabDocTrigger + where (doc_type=%s or doc_type='*') + and (doc_name=%s or doc_name='*') + and (event_name=%s or event_name='*')""", (doc.doctype, doc.name, event_name)) + except Exception, e: + if e.args[0]==1146: + setup() + tl = [] + else: raise e + + for t in tl: + module, method = '.'.join(t[0].split('.')[:-1]), t[0].split('.')[-1] + exec 'from %s import %s' % (module, method) in locals() + locals()[method](doc) +# +# setup +# +def setup(): + "creates the DocTrigger table from core" + webnotes.conn.commit() + from webnotes.modules.module_manager import reload_doc + reload_doc('core','doctype','doctrigger') + webnotes.conn.begin() + \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/__init__.py b/cgi-bin/webnotes/modules/__init__.py new file mode 100644 index 0000000000..665c77013c --- /dev/null +++ b/cgi-bin/webnotes/modules/__init__.py @@ -0,0 +1,65 @@ +""" + Utilities for using modules +""" + +transfer_types = ['Role', 'Print Format','DocType','Page','DocType Mapper','GL Mapper','Search Criteria', 'Patch'] + +def scrub(txt): + return txt.replace(' ','_').replace('-', '_').replace('/', '_').lower() + +def scrub_dt_and_dn(dt, dn): + """ + Returns in lowercase and code friendly names of doctype and name for certain types + """ + ndt, ndn = dt, dn + if dt.lower() in ('doctype', 'search criteria', 'page'): + ndt, ndn = scrub(dt), scrub(dn) + + return ndt, ndn + +def get_item_file(module, dt, dn): + """ + Returns the path of the item file + """ + import os + ndt, ndn = scrub_dt_and_dn(dt, dn) + + return os.path.join(get_module_path(module), ndt, ndn, ndn + '.txt') + +def get_item_timestamp(module, dt, dn): + """ + Return ths timestamp of the given item (if exists) + """ + return get_file_timestamp(get_item_file(module, dt, dn)) + +def get_file_timestamp(fn): + """ + Returns timestamp of the given file + """ + import os + from webnotes.utils import cint + + try: + return str(cint(os.stat(fn).st_mtime)) + except OSError, e: + if e.args[0]!=2: + raise e + else: + return None + +def get_module_path(module): + """ + Returns path of the given module (imports it and reads it from __file__) + """ + import webnotes.defs, os, os.path + + try: + exec ('import ' + scrub(module)) in locals() + modules_path = eval(scrub(module) + '.__file__') + + modules_path = os.path.sep.join(modules_path.split(os.path.sep)[:-1]) + except ImportError, e: + # get module path by importing the module + modules_path = os.path.join(webnotes.defs.modules_path, scrub(module)) + + return modules_path \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/compress.py b/cgi-bin/webnotes/modules/compress.py new file mode 100644 index 0000000000..04bd96bc23 --- /dev/null +++ b/cgi-bin/webnotes/modules/compress.py @@ -0,0 +1,342 @@ +""" +Load compressed .js page scripts + +Will also replace $import(page) or $import(module.page) with the relevant js files +""" + + +# load "compressed" js code from modules +#============================================================================== + +def get_js_code(fn, extn='js'): + """ + Get js code from a file (uncompressed) + """ + import webnotes + from webnotes.modules import scrub, get_file_timestamp + + src_file_name = fn + '.' + extn + + # src_timestamp = get_file_timestamp(src_file_name) + + # if no source, return + #if not src_timestamp: + # return '' + + # if timestamps are not same, compress + #if src_timestamp != get_file_timestamp(comp_file_name): + # compress(src_file_name, comp_file_name) + + # get the code + try: + file = open(src_file_name, 'r') + except IOError, e: + return '' + + code = file.read() + file.close() + + # return + return code + +# get doctype client +#============================================================================== + +def sub_get_doctype_js(match): + name = match.group('name') + return get_doctype_js(name) + +def get_doctype_js(dt): + """ + Returns the client-side (js) code of the DocType. + Adds custom script + and replaces $import(dt) with the code of that DocType + """ + import webnotes, os + from webnotes.modules import scrub, get_module_path + from webnotes.model.code import get_custom_script + + module = scrub(webnotes.conn.get_value('DocType',dt,'module')) + + code = get_js_code(os.path.join(get_module_path(scrub(module)), 'doctype', scrub(dt), scrub(dt))) \ + + '\n' + (get_custom_script(dt, 'Client') or '') + + # compile for import + if code.strip(): + import re + p = re.compile('\$import\( (?P [^)]*) \)', re.VERBOSE) + + code = p.sub(sub_get_doctype_js, code) + + return code + +# get page client +#============================================================================== + +def sub_get_page_js(match): + from webnotes.model.doc import Document + + name = match.group('name') + + if '.' in name: + name = name.split('.') + return get_page_js(name[1], name[0]) + + return get_page_js(Document('Page', name)) + +def get_page_js(page, module=None): + """ + Returns the js code of a page. Will replace $import (page) or $import(module.page) + with the code from the file + """ + import webnotes, os + from webnotes.modules import scrub, get_module_path + + if type(page)==str: + page_name = page + else: + page_name, module = page.name, page.module + + code = get_js_code(os.path.join(get_module_path(module), 'page', scrub(page_name), scrub(page_name))) + + if not code and type(page)!=str: + code = page.script + + # compile for import + if code and code.strip(): + import re + p = re.compile('\$import\( (?P [^)]*) \)', re.VERBOSE) + + code = p.sub(sub_get_page_js, code) + + return code + + +# compress +#============================================================================== + +def compress(src, comp): + out = open(comp, 'w') + + jsm = JavascriptMinify() + jsm.minify(open(src,'r'), out) + + out.close() + + + + +#============================================================================== +#============================================================================== +# +# This code is original from jsmin by Douglas Crockford, it was translated to +# Python by Baruch Even. The original code had the following copyright and +# license. +# +# /* jsmin.c +# 2007-05-22 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# The Software shall be used for Good, not Evil. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# */ + +from StringIO import StringIO + +def jsmin(js): + ins = StringIO(js) + outs = StringIO() + JavascriptMinify().minify(ins, outs) + str = outs.getvalue() + if len(str) > 0 and str[0] == '\n': + str = str[1:] + return str + +def isAlphanum(c): + """return true if the character is a letter, digit, underscore, + dollar sign, or non-ASCII character. + """ + return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or + (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126)); + +class UnterminatedComment(Exception): + pass + +class UnterminatedStringLiteral(Exception): + pass + +class UnterminatedRegularExpression(Exception): + pass + +class JavascriptMinify(object): + + def _outA(self): + self.outstream.write(self.theA) + def _outB(self): + self.outstream.write(self.theB) + + def _get(self): + """return the next character from stdin. Watch out for lookahead. If + the character is a control character, translate it to a space or + linefeed. + """ + c = self.theLookahead + self.theLookahead = None + if c == None: + c = self.instream.read(1) + if c >= ' ' or c == '\n': + return c + if c == '': # EOF + return '\000' + if c == '\r': + return '\n' + return ' ' + + def _peek(self): + self.theLookahead = self._get() + return self.theLookahead + + def _next(self): + """get the next character, excluding comments. peek() is used to see + if an unescaped '/' is followed by a '/' or '*'. + """ + c = self._get() + if c == '/' and self.theA != '\\': + p = self._peek() + if p == '/': + c = self._get() + while c > '\n': + c = self._get() + return c + if p == '*': + c = self._get() + while 1: + c = self._get() + if c == '*': + if self._peek() == '/': + self._get() + return ' ' + if c == '\000': + raise UnterminatedComment() + + return c + + def _action(self, action): + """do something! What you do is determined by the argument: + 1 Output A. Copy B to A. Get the next B. + 2 Copy B to A. Get the next B. (Delete A). + 3 Get the next B. (Delete B). + action treats a string as a single character. Wow! + action recognizes a regular expression if it is preceded by ( or , or =. + """ + if action <= 1: + self._outA() + + if action <= 2: + self.theA = self.theB + if self.theA == "'" or self.theA == '"': + while 1: + self._outA() + self.theA = self._get() + if self.theA == self.theB: + break + if self.theA <= '\n': + raise UnterminatedStringLiteral() + if self.theA == '\\': + self._outA() + self.theA = self._get() + + + if action <= 3: + self.theB = self._next() + if self.theB == '/' and (self.theA == '(' or self.theA == ',' or + self.theA == '=' or self.theA == ':' or + self.theA == '[' or self.theA == '?' or + self.theA == '!' or self.theA == '&' or + self.theA == '|' or self.theA == ';' or + self.theA == '{' or self.theA == '}' or + self.theA == '\n'): + self._outA() + self._outB() + while 1: + self.theA = self._get() + if self.theA == '/': + break + elif self.theA == '\\': + self._outA() + self.theA = self._get() + elif self.theA <= '\n': + raise UnterminatedRegularExpression() + self._outA() + self.theB = self._next() + + + def _jsmin(self): + """Copy the input to the output, deleting the characters which are + insignificant to JavaScript. Comments will be removed. Tabs will be + replaced with spaces. Carriage returns will be replaced with linefeeds. + Most spaces and linefeeds will be removed. + """ + self.theA = '\n' + self._action(3) + + while self.theA != '\000': + if self.theA == ' ': + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + elif self.theA == '\n': + if self.theB in ['{', '[', '(', '+', '-']: + self._action(1) + elif self.theB == ' ': + self._action(3) + else: + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + else: + if self.theB == ' ': + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + elif self.theB == '\n': + if self.theA in ['}', ']', ')', '+', '-', '"', '\'']: + self._action(1) + else: + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + else: + self._action(1) + + def minify(self, instream, outstream): + self.instream = instream + self.outstream = outstream + self.theA = '\n' + self.theB = None + self.theLookahead = None + + self._jsmin() + self.instream.close() \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/export_module.py b/cgi-bin/webnotes/modules/export_module.py new file mode 100644 index 0000000000..b1232bd316 --- /dev/null +++ b/cgi-bin/webnotes/modules/export_module.py @@ -0,0 +1,237 @@ +# ============================================================================== +# export to files +# ============================================================================== + +updated_modules = [] + +from webnotes.modules import scrub, get_module_path + +def export_to_files(modules = [], record_list=[], from_db=None, from_ac=None, verbose=1, record_module=None): + # Multiple doctype and multiple modules export to be done + # for Module Def, right now using a hack..should consider table update in the next version + # all modules transfer not working, because source db not known + # get the items + + global updated_modules + + if from_ac or from_db: + init_db_login(from_ac, from_db) + + out = [] + import webnotes.model.doc + module_doclist =[] + if record_list: + for record in record_list: + module_doclist.append([d.fields for d in webnotes.model.doc.get(record[0], record[1])]) + + # build the doclist + if modules: + for m in modules: + module_doclist +=get_module_doclist(m) + + # write files + for doclist in module_doclist: + if verbose: + out.append("Writing for " + doclist[0]['doctype'] + " / " + doclist[0]['name']) + write_document_file(doclist, record_module) + + # write out attachments + for m in modules: + write_attachments(m) + + return out + +# ============================================================================== +# write module.info file with last updated timestamp +# ============================================================================== + +def write_attachments(m): + import webnotes, os + from webnotes.utils.file_manager import get_file + + try: + fl = webnotes.conn.sql("select name from `tabFile Data` where module=%s", m) + except Exception, e: + if e.args[0]==1054: # no field called module + return + else: + raise e + + # write the files + if fl: + folder = os.path.join(webnotes.defs.modules_path, m, 'files') + webnotes.create_folder(folder) + for f in fl: + file_det = get_file(f) + file = open(os.path.join(folder, file_det[0]), 'w+') + file.write(file_det[1]) + file.close() + + +# ============================================================================== +# write module.info file with last updated timestamp +# ============================================================================== + +def write_module_info(mod): + import webnotes.utils, os + + file = open(os.path.join(get_module_path(mod), 'module.info'), 'w') + file.write(str({'update_date': webnotes.utils.now()})) + file.close() + +# ============================================================================== +# prepare a list of items in a module +# ============================================================================== + +def get_module_items(mod): + import webnotes + from webnotes.modules import transfer_types + from webnotes.modules import scrub + + dl = [] + for dt in transfer_types: + try: + dl2 = webnotes.conn.sql('select name, modified from `tab%s` where module="%s"' % (dt,mod)) + for e in dl2: + dl += [dt + ',' + e[0] + ',0'] + + if e[0] == 'Control Panel': + dl += [e[0]+','+e[0]+',1'] + except: + pass + dl1 = webnotes.conn.sql('select doctype_list from `tabModule Def` where name=%s', mod) + dl1 = dl1 and dl1[0][0] or '' + if dl1: + dl1 = dl1.split('\n') + dl += [t+',1' for t in dl1] + dl += ['Module Def,'+mod+',0'] + # build finally + dl = [e.split(',') for e in dl] + dl = [[e[0].strip(), e[1].strip(), e[2]] for e in dl] # remove blanks + return dl + + +# ============================================================================== +# build a list of doclists of items in that module and send them +# ============================================================================== + +def get_module_doclist(module): + import webnotes + import webnotes.model.doc + item_list = get_module_items(module) + + # build the super_doclist + super_doclist = [] + for i in item_list: + dl = webnotes.model.doc.get(i[0], i[1]) + if i[2]=='1': + dl[0].module = module + # remove compiled code (if any) + if dl[0].server_code_compiled: + dl[0].server_code_compiled = None + + # add to super + super_doclist.append([d.fields for d in dl]) + + return super_doclist + +# ============================================================================== +# Create __init__.py files +# ============================================================================== + +def create_init_py(modules_path, dt, dn): + import os + from webnotes.modules import scrub + + # in module + if not '__init__.py' in os.listdir(modules_path): + open(os.path.join(modules_path, '__init__.py'), 'w').close() + + # in type and name folders + if dt in ['doctype', 'page', 'search_criteria']: + if not '__init__.py' in os.listdir(os.path.join(modules_path, dt)): + open(os.path.join(modules_path, dt, '__init__.py'), 'w').close() + + if not '__init__.py' in os.listdir(os.path.join(modules_path, dt, dn)): + open(os.path.join(modules_path, dt, dn, '__init__.py'), 'w').close() + + +# ============================================================================== +# Create module folders +# ============================================================================== + +def create_folder(module, dt, dn): + import webnotes, os + + # get module path by importing the module + modules_path = get_module_path(module) + + code_type = dt in ['DocType', 'Page', 'Search Criteria'] + + # create folder + folder = os.path.join(modules_path, code_type and scrub(dt) or dt, code_type and scrub(dn) or dn) + + webnotes.create_folder(folder) + + # create init_py_files + if code_type: + create_init_py(modules_path, scrub(dt), scrub(dn)) + + return folder + +# ============================================================================== +# Write doclist into file +# ============================================================================== + +def write_document_file(doclist, record_module=None): + import os + from webnotes.utils import pprint_dict + + global updated_modules + + # module name + if doclist[0]['doctype'] == 'Module Def': + module = doclist[0]['name'] + elif doclist[0]['doctype']=='Control Panel': + module = 'System' + elif record_module: + module = record_module + else: + module = doclist[0]['module'] + + updated_modules.append(module) + + # create the folder + code_type = doclist[0]['doctype'] in ['DocType','Page','Search Criteria'] + + # create folder + folder = create_folder(module, doclist[0]['doctype'], doclist[0]['name']) + + # separate code files + clear_code_fields(doclist, folder, code_type) + + # write the data file + fname = (code_type and scrub(doclist[0]['name'])) or doclist[0]['name'] + dict_list = [pprint_dict(d) for d in doclist] + + txtfile = open(os.path.join(folder, fname +'.txt'),'w+') + txtfile.write('[\n' + ',\n'.join(dict_list) + '\n]') + txtfile.close() + + +# ============================================================================== +# Create seperate files for code +# ============================================================================== + +def clear_code_fields(doclist, folder, code_type): + + import os + import webnotes + # code will be in the parent only + code_fields = webnotes.code_fields_dict.get(doclist[0]['doctype'], []) + + for code_field in code_fields: + if doclist[0].get(code_field[0]): + + doclist[0][code_field[0]] = None + diff --git a/cgi-bin/webnotes/modules/import_module.py b/cgi-bin/webnotes/modules/import_module.py new file mode 100644 index 0000000000..d0cb048bdd --- /dev/null +++ b/cgi-bin/webnotes/modules/import_module.py @@ -0,0 +1,278 @@ +""" +Imports Documents from modules (.txt) files in the filesystem +""" + +import webnotes + +# +# imports / updates all files in a module into the database +# +def import_module(module, verbose=0): + "imports the all the records and files from the given module" + from webnotes.modules import get_module_path + import os + + not_module = ('startup', 'event_handlers', 'files', 'patches') + if module in not_module: + if verbose: webnotes.msgprint('%s is not a module' % module) + return + + path = get_module_path(module) + + doctypes = listfolders(path, 1) + if 'doctype' in doctypes: + doctypes.remove('doctype') + doctypes = ['doctype'] + doctypes + + for doctype in doctypes: + for docname in listfolders(os.path.join(path, doctype), 1): + import_file(module, doctype, docname, path) + if verbose: webnotes.msgprint('Imported %s/%s/%s' % (module, doctype, docname)) + + import_attachments(module) + +# +# get doclist from file +# +def get_doclist(path, doctype, docname): + "returns a doclist (list of dictionaries) of multiple records for the given parameters" + import os + do_not_import = ('control_panel') + + fname = os.path.join(path,doctype,docname,docname+'.txt') + if os.path.exists(fname) and (doctype not in do_not_import): + f = open(fname,'r') + dl = eval(f.read()) + f.close() + return dl + else: + return None + +# +# import a file into the database +# +def import_file(module, doctype, docname, path=None): + "imports a given file into the database" + + if not path: + from webnotes.modules import get_module_path + path = get_module_path(module) + + doclist = get_doclist(path, doctype, docname) + + if doclist: + from webnotes.utils.transfer import set_doc + set_doc(doclist, 1, 1, 1) + +# +# list folders in a dir +# +def listfolders(path, only_name=0): + """returns the list of folders (with paths) in the given path, + if only_name is set, it returns only the folder names""" + + import os + out = [] + for each in os.listdir(path): + dirname = each.split(os.path.sep)[-1] + fullpath = os.path.join(path, dirname) + + if os.path.isdir(fullpath) and not dirname.startswith('.'): + out.append(only_name and dirname or fullname) + return out + + + + + + + +# ============================================================================== +# Import from files +# ============================================================================= +def import_from_files(modules = [], record_list = [], sync_cp = 0, target_db=None, target_ac=None): + + if target_db or target_ac: + init_db_login(target_ac, target_db) + + from webnotes.utils import transfer + # Get paths of folder which will be imported + folder_list = get_folder_paths(modules, record_list) + ret = [] + + if folder_list: + # get all doclist + all_doclist = get_all_doclist(folder_list) + + # import doclist + ret += accept_module(all_doclist) + + # import attachments + for m in modules: + import_attachments(m) + + # sync control panel + if sync_cp: + ret.append(sync_control_panel()) + else: + ret.append("Module/Record not found") + + return ret + + +# ============================================================================== +# Get list of folder path +# ============================================================================= +# record_list in format [[module,dt,dn], ..] +def get_folder_paths(modules, record_list): + import os + import webnotes + import fnmatch + import webnotes.defs + from webnotes.modules import transfer_types, get_module_path, scrub + + folder_list=[] + + # get the folder list + if record_list: + for record in record_list: + if scrub(record[1]) in ('doctype', 'page', 'search_criteria'): + record[1], record[2] = scrub(record[1]), scrub(record[2]) + + folder_list.append(os.path.join(get_module_path(scrub(record[0])), \ + record[1], record[2].replace('/','_'))) + + if modules: + # system modules will be transferred in a predefined order and before all other modules + sys_mod_ordered_list = ['roles', 'core','application_internal', 'mapper', 'settings'] + all_mod_ordered_list = [t for t in sys_mod_ordered_list if t in modules] + list(set(modules).difference(sys_mod_ordered_list)) + + for module in all_mod_ordered_list: + mod_path = get_module_path(module) + types_list = listfolders(mod_path, 1) + + # list of types + types_list = list(set(types_list).difference(['control_panel'])) + all_transfer_types =[t for t in transfer_types if t in types_list] + list(set(types_list).difference(transfer_types)) + + # build the folders + for d in all_transfer_types: + if d not in ('files', 'startup', 'patches'): + # get all folders inside type + folder_list+=listfolders(os.path.join(mod_path, d)) + + return folder_list + + +# ============================================================================== +# Get doclist for all folder +# ============================================================================= + + +def get_all_doclist(folder_list): + import fnmatch + import os + + doclist = [] + all_doclist = [] + + # build into doclist + for folder in folder_list: + # get the doclist + file_list = os.listdir(folder) + for each in file_list: + + if fnmatch.fnmatch(each,'*.txt'): + doclist = eval(open(os.path.join(folder,each),'r').read()) + # add code + all_doclist.append(doclist) + + return all_doclist + + +# ============================================================================== +# accept a module coming from a remote server +# ============================================================================== +def accept_module(super_doclist): + import webnotes + import webnotes.utils + from webnotes.utils import transfer + msg, i = [], 0 + + for dl in super_doclist: + if dl[0]['doctype']!='Control Panel': + msg.append(transfer.set_doc(dl, 1, 1, 1)) + + if dl[0]['doctype']=='Module Def': + update_module_timestamp(dl[0]['name']) + + if not webnotes.conn.in_transaction: + webnotes.conn.sql("START TRANSACTION") + + # clear cache + webnotes.conn.sql("DELETE from __DocTypeCache") + webnotes.conn.sql("COMMIT") + + return msg + +# ============================================================================= +# Update timestamp in Module Def table +# ============================================================================= +def update_module_timestamp(mod): + import webnotes, webnotes.defs, os + + try: + file = open(os.path.join(webnotes.defs.modules_path, mod, 'module.info'), 'r') + except Exception, e: + if e.args[0]==2: + return # module.info + else: + raise e + + module_info = eval(file.read()) + file.close() + +# ============================================================================= + +def update_module_timestamp_query(mod, timestamp): + import webnotes + webnotes.conn.sql("start transaction") + webnotes.conn.sql("update `tabModule Def` set last_updated_date=%s where name=%s", (timestamp, mod)) + webnotes.conn.sql("commit") + + +# ============================================================================= +# Import Attachments +# ============================================================================= + +def import_attachments(m): + import os, webnotes.defs + import webnotes.utils.file_manager + from webnotes.modules import get_module_path + + out = [] + + # get list + try: + folder = os.path.join(get_module_path(m), 'files') + fl = os.listdir(folder) + except OSError, e: + if e.args[0]==2: + return + else: + raise e + + # import files + for f in fl: + if not os.path.isdir(os.path.join(folder, f)): + # delete + webnotes.utils.file_manager.delete_file(f) + + # import + file = open(os.path.join(folder, f),'r') + webnotes.utils.file_manager.save_file(f, file.read(), m) + file.close() + + out.append(f) + + return out diff --git a/cgi-bin/webnotes/modules/module_manager.py b/cgi-bin/webnotes/modules/module_manager.py new file mode 100644 index 0000000000..90679df0b2 --- /dev/null +++ b/cgi-bin/webnotes/modules/module_manager.py @@ -0,0 +1,187 @@ +#============================================================================== +# script to change the module name in the database & update svn +#============================================================================== + +def change_module(dt, dn, from_module, to_module): + import os, webnotes.defs + from webnotes.modules import scrub + + # change in db + webnotes.conn.sql("update `tab%s` set module=%s where name=%s" % (dt, '%s', '%s'), (to_module, dn)) + + # export files + from webnotes.modules.export_module import export_to_files + export_to_files(record_list = [[dt, dn]]) + + if dt in ['DocType','Page','Search Criteria']: + dt, dn = scrub(dt), scrub(dn) + + # svn add + webnotes.msgprint(os.popen("svn add %s" % os.path.join(webnotes.defs.modules_path, scrub(to_module), dt, dn)).read()) + + # svn remove + webnotes.msgprint(os.popen("svn remove %s" % os.path.join(webnotes.defs.modules_path, scrub(from_module), dt, dn)).read()) + + + +#============================================================================== +# SYNC +#============================================================================== +def reload_doc(module, dt, dn): + "alias for webnotes.modules.import_module.import_file" + from webnotes.modules.import_module import import_file + + import_file(module, dt, dn) + +# +# get list of doctypes and their last update times +# +def get_doc_list(dt): + """ + returns the list of records and their last update times from the table + if the column _last_update does not exist, it will add it to the table + """ + + import webnotes + module = dt=='Module Def' and 'name' or 'module' + q = "select %s, name, _last_update from `tab%s`" % (module, dt) + try: + return webnotes.conn.sql(q) + except Exception, e: + if e.args[0]==1054: + webnotes.conn.commit() + webnotes.conn.sql("alter table `tab%s` add column _last_update varchar(32)" % dt) + webnotes.conn.begin() + return webnotes.conn.sql(q) + elif e.args[0]==1146: + return [] + else: + raise e + +# +# sync dt +# +def sync_one_doc(d, dt, ts): + import webnotes + from webnotes.model.db_schema import updatedb + reload_doc(d[0], dt, d[1]) + + # update schema(s) + if dt=='DocType': + updatedb(d[1]) + webnotes.conn.sql("update `tab%s` set _last_update=%s where name=%s" % (dt, '%s', '%s'), (ts, d[1])) + +# +# sync doctypes, mappers and +# +def sync_meta(): + import webnotes, os + from webnotes.modules import scrub, get_module_path + from webnotes.utils import cint + + tl = ['DocType', 'DocType Mapper', 'Module Def'] + + for dt in tl: + dtl = get_doc_list(dt) + + for d in filter(lambda x: x[0], dtl): + try: + ndt, ndn = dt, d[1] + if dt == 'DocType': + ndt, ndn = scrub(dt), scrub(d[1]) + + mp = get_module_path(scrub(d[0])) + ts = cint(os.stat(os.path.join(mp, ndt, ndn, ndn + '.txt')).st_mtime) + + if d[2] != str(ts): + sync_one_doc(d, dt, ts) + except OSError, e: + pass + + + + + + +#============================================================================== + +def get_module_details(m): + from export_module import get_module_items + return {'in_files': get_module_items_from_files(m), \ + 'in_system':[[i[0], i[1], get_modified(i[0], i[1])] for i in get_module_items(m)]} + +#============================================================================== + +def get_modified(dt, dn): + import webnotes + try: + return str(webnotes.conn.sql("select modified from `tab%s` where replace(name,' ','_')=%s" % (dt,'%s'), dn)[0][0]) + except: + pass + +#============================================================================== + +def get_module_items_from_files(m): + import os, webnotes.defs + from import_module import listfolders + + items = [] + for item_type in listfolders(os.path.join(webnotes.defs.modules_path, m), 1): + for item_name in listfolders(os.path.join(webnotes.defs.modules_path, m, item_type), 1): + # read the file + file = open(os.path.join(webnotes.defs.modules_path, m, item_type, item_name, item_name)+'.txt','r') + doclist = eval(file.read()) + file.close() + + # append + items.append([item_type, item_name, doclist[0]['modified']]) + + return items + +#============================================================================== + +def get_last_update_for(mod): + import webnotes + try: + return webnotes.conn.sql("select last_updated_date from `tabModule Def` where name=%s", mod)[0][0] + except: + return '' + +#============================================================================== + +def init_db_login(ac_name, db_name): + import webnotes + import webnotes.db + import webnotes.profile + + if ac_name: + webnotes.conn = webnotes.db.Database(ac_name = ac_name) + webnotes.conn.use(webnotes.conn.user) + elif db_name: + webnotes.conn = webnotes.db.Database(user=db_name) + webnotes.conn.use(db_name) + else: + webnotes.conn = webnotes.db.Database(use_default=1) + + webnotes.session = {'user':'Administrator'} + webnotes.user = webnotes.profile.Profile() + +#============================================================================== +# Return module names present in File System +#============================================================================== +def get_modules_from_filesystem(): + import os, webnotes.defs + from import_module import listfolders + + modules = listfolders(webnotes.defs.modules_path, 1) + out = [] + modules.sort() + modules = filter(lambda x: x!='patches', modules) + + for m in modules: + file = open(os.path.join(webnotes.defs.modules_path, m, 'module.info'), 'r') + out.append([m, eval(file.read()), get_last_update_for(m), \ + webnotes.conn.exists('Module Def',m) and 'Installed' or 'Not Installed']) + file.close() + + return out \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/patch.py b/cgi-bin/webnotes/modules/patch.py new file mode 100644 index 0000000000..401510b3c2 --- /dev/null +++ b/cgi-bin/webnotes/modules/patch.py @@ -0,0 +1,36 @@ +# patch manager + +def run(log_exception=1): + import webnotes + from patches import patch + from webnotes.utils import cint + + next_patch = cint(webnotes.conn.get_global('next_patch')) + + if next_patch <= patch.last_patch: + for i in range(next_patch, patch.last_patch+1): + webnotes.conn.begin() + if log_exception: + try: + patch.execute(i) + except Exception, e: + write_log() + return + else: + patch.execute(i) + + webnotes.conn.set_global('next_patch', str(i+1)) + webnotes.conn.commit() + +def write_log(): + import os + import webnotes.defs + import webnotes + + patch_log = open(os.path.join(webnotes.defs.modules_path, 'patches', 'patch.log'), 'a') + patch_log.write(('\n\nError in %s:\n' % webnotes.conn.cur_db_name) + webnotes.getTraceback()) + patch_log.close() + + webnotes.msgprint("There were errors in running patches, please call the Administrator") + + diff --git a/cgi-bin/webnotes/multi_tenant/__init__.py b/cgi-bin/webnotes/multi_tenant/__init__.py new file mode 100644 index 0000000000..f29b0ef95a --- /dev/null +++ b/cgi-bin/webnotes/multi_tenant/__init__.py @@ -0,0 +1 @@ +shared_tables = ['DocType','DocPerm','DocField','Role','Print Format','Module Def'] diff --git a/cgi-bin/webnotes/multi_tenant/query_parser.py b/cgi-bin/webnotes/multi_tenant/query_parser.py new file mode 100644 index 0000000000..2bbf7447e2 --- /dev/null +++ b/cgi-bin/webnotes/multi_tenant/query_parser.py @@ -0,0 +1,38 @@ +import sqlparse +import webnotes +import webnotes.query_parser + +def get_tables(parsed): + start = 0 + for t in parsed[0].tokens: + if str(t.ttype)=='Token.Keyword' and t.value.lower()=='from': + start = 1 + if start and type(t).__name__=='Identifier': + return [(str(t.get_real_name())),] + + if start and type(t).__name__=='IdentifierList': + return [str(i.get_real_name()) for i in t.get_identifiers()] + + return tl + +def add_condition(query): + parsed = sqlparse.parse(query) + + # get the tables + tl = get_tables(parsed) + + # rebuild the query till the where clause + q = '' + for t in parsed[0].tokens: + q += str(t) + + # where clause comes here + if type(t).__name__=='Where': + + # add the conditions for the tables + for t in tl: + if t not in webnotes.query_parser.shared_tables: + q += ' and %s._tenant_id=%s' % (t, webnotes.tenant_id) + + return q + diff --git a/cgi-bin/webnotes/multi_tenant/setup.py b/cgi-bin/webnotes/multi_tenant/setup.py new file mode 100644 index 0000000000..5d9b9e3bd5 --- /dev/null +++ b/cgi-bin/webnotes/multi_tenant/setup.py @@ -0,0 +1,19 @@ +import webnotes + +# setup all tables for multi-tenant +# --------------------------------- +def setup_tables(): + import webnotes.multi_tenant + + tl = webnotes.conn.sql("show tables") + for t in tl: + add_tenant_id(t[0]) + change_primary_key(t[0]) + +def add_tenant_id(tname): + webnotes.conn.sql("alter table `%s` add column _tenant_id int(10) default 0 not null") + +def change_primary_key(tname): + webnotes.conn.sql("alter table `%s` drop primary key name") + webnotes.conn.sql("alter table `%s` add primary key (name, _tenant_id)") + diff --git a/cgi-bin/webnotes/profile.py b/cgi-bin/webnotes/profile.py new file mode 100644 index 0000000000..b20c93282e --- /dev/null +++ b/cgi-bin/webnotes/profile.py @@ -0,0 +1,239 @@ +import webnotes + +class Profile: + """ + A profile object is created at the beginning of every request with details of the use. + The global profile object is `webnotes.user` + """ + def __init__(self, name=''): + self.name = name or webnotes.session.get('user') + self.roles = [] + + self.can_create = [] + self.can_read = [] + self.can_write = [] + self.can_get_report = [] + + def _load_roles(self): + res = webnotes.conn.sql('select role from tabUserRole where parent = "%s"' % self.name) + self.roles = [] + for t in res: + if t[0]: self.roles.append(t[0]) + if webnotes.session.get('user') == 'Guest': + self.roles.append('Guest') + else: + self.roles.append('All') + + return self.roles + + def get_roles(self): + """ + get list of roles + """ + if self.roles: + return self.roles + + return self._load_roles() + + def get_allow_list(self, key): + """ + Internal - get list of DocType where `key` is allowed. Key is either 'read', 'write' or 'create' + """ + conn = webnotes.conn + roles = self.get_roles() + return [r[0] for r in conn.sql('SELECT DISTINCT t1.parent FROM `tabDocPerm` t1, tabDocType t2 WHERE t1.`%s`=1 AND t1.parent not like "old_parent:%%" AND t1.parent = t2.name AND IFNULL(t2.istable,0) = 0 AND t1.role in ("%s") order by t1.parent' % (key, '", "'.join(roles)))] + + def get_create_list(self): + """ + Get list of DocTypes the user can create. Will filter DocTypes tagged with 'not_in_create' and table + """ + cl = self.get_allow_list('create') + conn = webnotes.conn + no_create_list = [r[0] for r in conn.sql('select name from tabDocType where ifnull(in_create,0)=1 or ifnull(istable,0)=1 or ifnull(issingle,0)=1')] + self.can_create = filter(lambda x: x not in no_create_list, cl) + return self.can_create + + def get_read_list(self): + """ + Get list of DocTypes the user can read + """ + self.can_read = list(set(self.get_allow_list('read') + self.get_allow_list('write'))) + return self.can_read + + def get_report_list(self): + + conn = webnotes.conn + + # get all tables list + res = conn.sql('SELECT parent, options from tabDocField where fieldtype="Table"') + table_types, all_tabletypes = {}, [] + + # make a dictionary fo all table types + for t in res: + all_tabletypes.append(t[1]) + if not table_types.has_key(t[0]): + table_types[t[0]] = [] + table_types[t[0]].append(t[1]) + + no_search_list = [r[0] for r in conn.sql('SELECT name FROM tabDocType WHERE read_only = 1 ORDER BY name')] + # make the lists + for f in self.can_read: + tl = table_types.get(f, None) + if tl: + for t in tl: + if t and (not t in self.can_get_report) and (not t in no_search_list): + self.can_get_report.append(t) + + if f and (not f in self.can_get_report) and (not f in no_search_list): + self.can_get_report.append(f) + + return self.can_get_report + + def get_write_list(self): + """ + Get list of DocTypes the user can write + """ + self.can_write = self.get_allow_list('write') + return self.can_write + + def get_home_page(self): + """ + Get the name of the user's home page from the `Control Panel` + """ + try: + 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 self.get_roles(): + return h[1] + except: + pass + return webnotes.conn.get_value('Control Panel',None,'home_page') + + def get_defaults(self): + """ + Get the user's default values based on user and role profile + """ + roles = self.get_roles() + [self.name] + res = webnotes.conn.sql('select defkey, defvalue from `tabDefaultValue` where parent in ("%s")' % '", "'.join(roles)) + + self.defaults = {'owner': [self.name,]} + + for rec in res: + if not self.defaults.has_key(rec[0]): + self.defaults[rec[0]] = [] + self.defaults[rec[0]].append(rec[1] or '') + + return self.defaults + + def get_hide_tips(self): + try: + return webnotes.conn.sql("select hide_tips from tabProfile where name=%s", self.name)[0][0] or 0 + except: + return 0 + + def get_random_password(self): + """ + Generate a random password + """ + import string + from random import choice + + size = 9 + pwd = ''.join([choice(string.letters + string.digits) for i in range(size)]) + return pwd + + def reset_password(self): + """ + Reset the user's password and send an email + """ + pwd = self.get_random_password() + + # get profile + profile = webnotes.conn.sql("SELECT name, email, first_name, last_name FROM tabProfile WHERE name=%s OR email=%s",(self.name, self.name)) + + if not profile: + raise Exception, "Profile %s not found" % self.name + + # update tab Profile + webnotes.conn.sql("UPDATE tabProfile SET password=password(%s) WHERE name=%s", (pwd, profile[0][0])) + + self.send_email("Password Reset", "

Dear %s%s,

your password has been changed to %s

[Automatically Generated]

" % (profile[0][2], (profile[0][3] and (' ' + profile[0][3]) or ''), pwd), profile[0][1]) + + def send_email(self, subj, mess, email): + import webnotes.utils.email_lib + + webnotes.utils.email_lib.sendmail(email, msg=mess, subject=subj) + + # update recent documents + def update_recent(self, dt, dn): + """ + Update the user's `Recent` list with the given `dt` and `dn` + """ + conn = webnotes.conn + + # get list of child tables, so we know what not to add in the recent list + child_tables = [t[0] for t in conn.sql('select name from tabDocType where istable = 1')] + if not (dt in ['Print Format', 'Start Page', 'Event', 'ToDo Item', 'Search Criteria']) and not webnotes.is_testing and not (dt in child_tables): + r = webnotes.conn.sql("select recent_documents from tabProfile where name=%s", self.name)[0][0] or '' + new_str = dt+'~~~'+dn + '\n' + if new_str in r: + r = r.replace(new_str, '') + + self.recent = new_str + r + + if len(self.recent.split('\n')) > 50: + self.recent = '\n'.join(self.recent.split('\n')[:50]) + + webnotes.conn.sql("update tabProfile set recent_documents=%s where name=%s", (self.recent, self.name)) + + def load_profile(self): + """ + Return a dictionary of user properites to be stored in the session + """ + t = webnotes.conn.sql('select email, first_name, last_name, recent_documents from tabProfile where name = %s', self.name)[0] + + d = {} + d['name'] = self.name + d['email'] = t[0] or '' + d['first_name'] = t[1] or '' + d['last_name'] = t[2] or '' + d['recent'] = t[3] or '' + + d['hide_tips'] = self.get_hide_tips() + + d['roles'] = self.get_roles() + d['defaults'] = self.get_defaults() + + d['can_create'] = self.get_create_list() + d['can_read'] = self.get_read_list() + d['can_write'] = self.get_write_list() + d['can_get_report'] = self.get_report_list() + + return d + + def load_from_session(self, d): + """ + Setup the user profile from the dictionary saved in the session (generated by `load_profile`) + """ + self.can_create = d['can_create'] + self.can_read = d['can_read'] + self.can_write = d['can_write'] + self.can_get_report = d['can_get_report'] + + self.roles = d['roles'] + self.defaults = d['defaults'] + +def get_user_img(): + if not webnotes.form.getvalue('username'): + webnotes.response['message'] = 'no_img_m' + return + + f = webnotes.conn.sql("select file_list from tabProfile where name=%s", webnotes.form.getvalue('username','')) + if f: + if f[0][0]: + lst = f[0][0].split('\n') + webnotes.response['message'] = lst[0].split(',')[1] + else: + webnotes.response['message'] = 'no_img_m' + else: + webnotes.response['message'] = 'no_img_m' diff --git a/cgi-bin/webnotes/session_cache.py b/cgi-bin/webnotes/session_cache.py new file mode 100644 index 0000000000..70e539e91f --- /dev/null +++ b/cgi-bin/webnotes/session_cache.py @@ -0,0 +1,183 @@ +# session_cache.py + +# clear cache +# ================================================== + +def clear(): + clear_cache() + + import webnotes + webnotes.response['message'] = "Cache Cleared" + +def clear_cache(user=''): + import webnotes + try: + if user: + webnotes.conn.sql("delete from __SessionCache where user=%s", user) + else: + webnotes.conn.sql("delete from __SessionCache") + except Exception, e: + if e.args[0]==1146: + make_cache_table() + else: + raise e + +# load cache +# ================================================== + +def get(): + import webnotes + import webnotes.defs + + + # get country + country = webnotes.session['data'].get('ipinfo', {}).get('countryName', 'Unknown Country') + + # run patches + try: + import webnotes.modules.patch + webnotes.modules.patch.run() + except ImportError, e: + pass # no patches - do nothing + + # check if cache exists + if not getattr(webnotes.defs,'auto_cache_clear',None): + cache = load(country) + if cache: + return cache + + # if not create it + sd = build() + dump(sd, country) + + # update profile from cache + webnotes.session['data']['profile'] = sd['profile'] + + return sd + +# load cache +# ================================================== + +def load(country): + import webnotes + + try: + sd = webnotes.conn.sql("select cache from __SessionCache where user='%s' %s" % (webnotes.session['user'], (country and (" and country='%s'" % country) or ''))) + if sd: + return eval(sd[0][0]) + else: + return None + except Exception, e: + if e.args[0]==1146: + make_cache_table() + else: + raise e + +# make the cache table +# ================================================== + +def make_cache_table(): + import webnotes + webnotes.conn.commit() + webnotes.conn.sql("create table `__SessionCache` (user VARCHAR(120), country VARCHAR(120), cache LONGTEXT)") + webnotes.conn.begin() + +# dump session to cache +# ================================================== + +def dump(sd, country): + import webnotes + import webnotes.model.doclist + + if sd.get('docs'): + sd['docs'] = webnotes.model.doclist.compress(sd['docs']) + + # delete earlier (?) + webnotes.conn.sql("delete from __SessionCache where user=%s and country=%s", (webnotes.session['user'], country)) + + # make new + webnotes.conn.sql("insert into `__SessionCache` (user, country, cache) VALUES (%s, %s, %s)", (webnotes.session['user'], country, str(sd))) + +# ================================================== + +def get_letter_heads(): + import webnotes + try: + lh = {} + ret = webnotes.conn.sql("select name, content from `tabLetter Head` where ifnull(disabled,0)=0") + for r in ret: + lh[r[0]] = r[1] + return lh + except Exception, e: + if e.args[0]==1146: + return {} + else: + raise Exception, e + +# ================================================== +# load startup.js and startup.css from the modules/startup folder + +def load_startup(cp): + from webnotes.modules import compress + + try: from webnotes.defs import modules_path + except ImportError: return + + import os + + try: + cp.startup_code = compress.get_js_code(os.path.join(modules_path, 'startup', 'startup')) + startup_css = open(os.path.join(modules_path, 'startup', 'startup.css'), 'r') + cp.startup_css = startup_css.read() + startup_css.close() + except IOError, e: + if e.args[0]!=2: # no startup module! + raise e + +# build it +# ================================================== + +def build(): + sd = {} + + import webnotes + import webnotes.model + import webnotes.model.doc + import webnotes.model.doctype + import webnotes.widgets.page + import webnotes.widgets.menus + import webnotes.profile + import webnotes.defs + + sql = webnotes.conn.sql + + webnotes.conn.begin() + sd['profile'] = webnotes.user.load_profile() + + doclist = [] + doclist += webnotes.model.doc.get('Control Panel') + cp = doclist[0] + load_startup(cp) + + doclist += webnotes.model.doctype.get('Event') + doclist += webnotes.model.doctype.get('Search Criteria') + home_page = webnotes.user.get_home_page() + + if home_page: + doclist += webnotes.widgets.page.get(home_page) + + sd['account_name'] = cp.account_id or '' + sd['sysdefaults'] = webnotes.utils.get_defaults() + sd['n_online'] = int(sql("SELECT COUNT(DISTINCT user) FROM tabSessions")[0][0] or 0) + sd['docs'] = doclist + sd['letter_heads'] = get_letter_heads() + sd['home_page'] = home_page or '' + sd['start_items'] = webnotes.widgets.menus.get_menu_items() + if webnotes.session['data'].get('ipinfo'): + sd['ipinfo'] = webnotes.session['data']['ipinfo'] + + webnotes.session['data']['profile'] = sd['profile'] + sd['dt_labels'] = webnotes.model.get_dt_labels() + webnotes.conn.commit() + + return sd diff --git a/cgi-bin/webnotes/settings/__init__.py b/cgi-bin/webnotes/settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/webnotes/settings/account_map_template.py b/cgi-bin/webnotes/settings/account_map_template.py new file mode 100644 index 0000000000..dd634cd2ba --- /dev/null +++ b/cgi-bin/webnotes/settings/account_map_template.py @@ -0,0 +1,10 @@ +# Account/Domain Name to Database Mapping file +# -------------------------------------------- +# last updated on: 2011-02-02 14:31:14 + +default_db_name = "webnotesdb" + +db_name_map = {'wnframework':'webnotesdb'} +#{'main_acc_name';'db_name'} +domain_name_map = {'localhost':'webnotesdb'} + diff --git a/cgi-bin/webnotes/utils/__init__.py b/cgi-bin/webnotes/utils/__init__.py new file mode 100644 index 0000000000..c40b9cab24 --- /dev/null +++ b/cgi-bin/webnotes/utils/__init__.py @@ -0,0 +1,550 @@ +# util __init__.py + +import webnotes + +user_time_zone = None +month_name = ['','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] +month_name_full = ['','January','February','March','April','May','June','July','August','September','October','November','December'] +no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', 'Button', 'Image', 'Graph'] +default_fields = ['doctype','name','owner','creation','modified','modified_by','parent','parentfield','parenttype','idx','docstatus'] + +def getCSVelement(v): + """ + Returns the CSV value of `v`, For example: + + * apple becomes "apple" + * hi"there becomes "hi""there" + """ + v = cstr(v) + if not v: return '' + if (',' in v) or ('\n' in v) or ('"' in v): + if '"' in v: v = v.replace('"', '""') + return '"'+v+'"' + else: return v or '' + +def validate_email_add(email_str): + """ + Validates the email string + """ + s = email_str + if '<' in s: + s = s.split('<')[1].split('>')[0] + if s: s = s.strip().lower() + import re + #return re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email_str) + return re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", s) + +def sendmail(recipients, sender='', msg='', subject='[No Subject]', parts=[], cc=[], attach=[]): + """ + Send an email. For more details see :func:`email_lib.sendmail` + """ + import webnotes.utils.email_lib + return email_lib.sendmail(recipients, sender, msg, subject, parts, cc, attach) + +def generate_hash(): + """ + Generates reandom hash for session id + """ + import sha, time + return sha.new(str(time.time())).hexdigest() + +def db_exists(dt, dn): + return webnotes.conn.sql('select name from `tab%s` where name="%s"' % (dt, dn)) + +def load_json(arg): + + # already a dictionary? + if type(arg)!=str: + return arg + + try: import json + except: import simplejson as json + + #return json.loads(unicode(arg, 'iso-8859-15')) + return json.loads(arg) + +# Get Traceback +# ============================================================================== + +def getTraceback(): + """ + Returns the traceback of the Exception + """ + import sys, traceback, string + type, value, tb = sys.exc_info() + + body = "Traceback (innermost last):\n" + list = traceback.format_tb(tb, None) + traceback.format_exception_only(type, value) + body = body + "%-20s %s" % (string.join(list[:-1], ""), list[-1]) + + if webnotes.logger: + webnotes.logger.error('Db:'+(webnotes.conn and webnotes.conn.cur_db_name or '') + ' - ' + body) + + return body + +# Log +# ============================================================================== + +def log(event, details): + webnotes.logger.info(details) + +# Date and Time +# ============================================================================== + + +def getdate(string_date): + """ + Coverts string date (yyyy-mm-dd) to datetime.date object + """ + import datetime + + if type(string_date)==unicode: + string_date = str(string_date) + + if type(string_date) in (datetime.datetime, datetime.date): + return string_date + + if ' ' in string_date: + string_date = string_date.split(' ')[0] + t = string_date.split('-') + if len(t)==3: + return datetime.date(cint(t[0]), cint(t[1]), cint(t[2])) + else: + return '' + +def add_days(date, days): + """ + Adds `days` to the given `string_date` + """ + import datetime + if not date: + date = now_datetime() + + if type(date) not in (datetime.datetime, datetime.date): + date = getdate(date) + + return (date + datetime.timedelta(days)).strftime('%Y-%m-%d') + +def add_months(string_date, months): + import datetime + return webnotes.conn.sql("select DATE_ADD('%s',INTERVAL '%s' MONTH)" % (getdate(string_date),months))[0][0] + +def add_years(string_date, years): + import datetime + return webnotes.conn.sql("select DATE_ADD('%s',INTERVAL '%s' YEAR)" % (getdate(string_date),years))[0][0] + +def date_diff(string_ed_date, string_st_date=None): + import datetime + return webnotes.conn.sql("SELECT DATEDIFF('%s','%s')" %(getdate(string_ed_date), getdate(string_st_date)))[0][0] + +def now_datetime(): + global user_time_zone + from datetime import datetime + from pytz import timezone + + # get localtime + if not user_time_zone: + user_time_zone = webnotes.conn.get_value('Control Panel', None, 'time_zone') or 'Asia/Calcutta' + + # convert to UTC + utcnow = timezone('UTC').localize(datetime.utcnow()) + + # convert to user time zone + return utcnow.astimezone(timezone(user_time_zone)) + +def now(): + """ + Returns `time.strftime('%Y-%m-%d %H:%M:%S')` + """ + return now_datetime().strftime('%Y-%m-%d %H:%M:%S') + +def nowdate(): + """ + Returns time.strftime('%Y-%m-%d') + """ + return now_datetime().strftime('%Y-%m-%d') + +def get_first_day(dt, d_years=0, d_months=0): + """ + Returns the first day of the month for the date specified by date object + Also adds `d_years` and `d_months` if specified + """ + import datetime + # d_years, d_months are "deltas" to apply to dt + y, m = dt.year + d_years, dt.month + d_months + a, m = divmod(m-1, 12) + return datetime.date(y+a, m+1, 1) + +def get_last_day(dt): + """ + Returns last day of the month using: + `get_first_day(dt, 0, 1) + datetime.timedelta(-1)` + """ + import datetime + return get_first_day(dt, 0, 1) + datetime.timedelta(-1) + +user_format = None +""" + User format specified in :term:`Control Panel` + + Examples: + + * dd-mm-yyyy + * mm-dd-yyyy + * dd/mm/yyyy +""" + +def formatdate(string_date): + """ + Convers the given string date to :data:`user_format` + """ + global user_format + if not user_format: + user_format = webnotes.conn.get_value('Control Panel', None, 'date_format') + d = string_date.split('-'); + out = user_format + return out.replace('dd', ('%.2i' % cint(d[2]))).replace('mm', ('%.2i' % cint(d[1]))).replace('yyyy', d[0]) + +def dict_to_str(args, sep='&'): + """ + Converts a dictionary to URL + """ + import urllib + t = [] + for k in args.keys(): + t.append(str(k)+'='+urllib.quote(str(args[k] or ''))) + return sep.join(t) + +def timestamps_equal(t1, t2): + """Returns true if same the two string timestamps are same""" + scrub = lambda x: x.replace(':', ' ').replace('-',' ').split() + + t1, t2 = scrub(t1), scrub(t2) + + if len(t1) != len(t2): + return + + for i in range(len(t1)): + if t1[i]!=t2[i]: + return + return 1 + +def global_date_format(date): + import datetime + + if type(date) in (str, unicode): + date = getdate(date) + + return date.strftime('%d') + ' ' + month_name_full[int(date.strftime('%m'))] + ' ' + date.strftime('%Y') + + + + +# Datatype +# ============================================================================== + +def isNull(v): + """ + Returns true if v='' or v is `None` + """ + return (v=='' or v==None) + +def has_common(l1, l2): + """ + Returns true if there are common elements in lists l1 and l2 + """ + for l in l1: + if l in l2: + return 1 + return 0 + +def flt(s): + """ + Convert to float (ignore commas) + """ + if type(s)==str: # if string + s = s.replace(',','') + try: tmp = float(s) + except: tmp = 0 + return tmp + +def cint(s): + """ + Convert to integer + """ + try: tmp = int(float(s)) + except: tmp = 0 + return tmp + +def cstr(s): + """ + Convert to string + """ + if s==None: + return '' + else: + if hasattr(s, 'encode'): + try: + s = s.encode('utf-8', 'ignore') + except: + pass + return str(s) + +def str_esc_quote(s): + """ + Escape quotes + """ + if s==None:return '' + return s.replace("'","\'") + +def replace_newlines(s): + """ + Replace newlines by '
' + """ + if s==None:return '' + return s.replace("\n","
") + + +# ============================================================================== + +def parse_val(v): + """ + Converts to simple datatypes from SQL query results + """ + import datetime + + try: import decimal # for decimal Python 2.5 (?) + except: pass + + if type(v)==datetime.date: + v = str(v) + elif type(v)==datetime.timedelta: + v = ':'.join(str(v).split(':')[:2]) + elif type(v)==datetime.datetime: + v = str(v) + elif type(v)==long: v=int(v) + + try: + if type(v)==decimal.Decimal: v=float(v) + except: pass + + return v + +# ============================================================================== + +def fmt_money(amount, fmt = '%.2f'): + """ + Convert to string with commas for thousands, millions etc + """ + curr = webnotes.conn.get_value('Control Panel', None, 'currency_format') or 'Millions' + + val = 2 + if curr == 'Millions': val = 3 + + if cstr(amount).find('.') == -1: temp = '00' + else: temp = cstr(amount).split('.')[1] + + l = [] + minus = '' + if flt(amount) < 0: minus = '-' + + amount = ''.join(cstr(amount).split(',')) + amount = cstr(abs(flt(amount))).split('.')[0] + + # main logic + if len(cstr(amount)) > 3: + nn = amount[len(amount)-3:] + l.append(nn) + amount = amount[0:len(amount)-3] + while len(cstr(amount)) > val: + nn = amount[len(amount)-val:] + l.insert(0,nn) + amount = amount[0:len(amount)-val] + + if len(amount) > 0: l.insert(0,amount) + + amount = ','.join(l)+'.'+temp + amount = minus + amount + return amount + +# +# convet currency to words +# +def money_in_words(number, main_currency = None, fraction_currency=None): + """ + Returns string in words with currency and fraction currency. + """ + + d = get_defaults() + if not main_currency: + main_currency = d.get('currency', 'INR') + if not fraction_currency: + fraction_currency = d.get('fraction_currency', 'paise') + + n = str(flt(number)) + main, fraction = n.split('.') + if len(fraction)==1: fraction += '0' + + out = main_currency + ' ' + in_words(main).title() + if cint(fraction): + out = out + ' and ' + in_words(fraction).title() + ' ' + fraction_currency + + return out + ' only.' + +# +# convert number to words +# +def in_words(integer): + """ + Returns string in words for the given integer. + """ + + in_million = webnotes.conn.get_value('Control Panel',None,'currency_format')=='Millions' and 1 or 0 + + + n=int(integer) + known = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', + 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', + 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'} + + def psn(n, known, xpsn): + import sys; + if n in known: return known[n] + bestguess, remainder = str(n), 0 + + if n<=20: + print >>sys.stderr, n, "How did this happen?" + assert 0 + elif n < 100: + bestguess= xpsn((n//10)*10, known, xpsn) + '-' + xpsn(n%10, known, xpsn) + return bestguess + elif n < 1000: + bestguess= xpsn(n//100, known, xpsn) + ' ' + 'hundred' + remainder = n%100 + else: + if in_million: + if n < 1000000: + bestguess= xpsn(n//1000, known, xpsn) + ' ' + 'thousand' + remainder = n%1000 + elif n < 1000000000: + bestguess= xpsn(n//1000000, known, xpsn) + ' ' + 'million' + remainder = n%1000000 + else: + bestguess= xpsn(n//1000000000, known, xpsn) + ' ' + 'billion' + remainder = n%1000000000 + else: + if n < 100000: + bestguess= xpsn(n//1000, known, xpsn) + ' ' + 'thousand' + remainder = n%1000 + elif n < 10000000: + bestguess= xpsn(n//100000, known, xpsn) + ' ' + 'lakh' + remainder = n%100000 + else: + bestguess= xpsn(n//10000000, known, xpsn) + ' ' + 'crore' + remainder = n%10000000 + if remainder: + if remainder >= 100: + comma = ',' + else: + comma = '' + return bestguess + comma + ' ' + xpsn(remainder, known, xpsn) + else: + return bestguess + + return psn(n, known, psn) + + +# Get Defaults +# ============================================================================== + +def get_defaults(key=None): + """ + Get dictionary of default values from the :term:`Control Panel`, or a value if key is passed + """ + if key: + res = webnotes.conn.sql('select defvalue from `tabDefaultValue` where parent = "Control Panel" where defkey=%s', key) + return res and res[0][0] or None + else: + res = webnotes.conn.sql('select defkey, defvalue from `tabDefaultValue` where parent = "Control Panel"') + d = {} + for rec in res: + d[rec[0]] = rec[1] or '' + return d + +def set_default(key, val): + """ + Set / add a default value to :term:`Control Panel` + """ + res = webnotes.conn.sql('select defkey from `tabDefaultValue` where defkey="%s" and parent = "Control Panel"' % key) + if res: + webnotes.conn.sql('update `tabDefaultValue` set defvalue="%s" where parent = "Control Panel" and defkey="%s"' % (val, key)) + else: + from webnotes.model.doc import Document + d = Document('DefaultValue') + d.parent = 'Control Panel' + d.parenttype = 'Control Panel' + d.parentfield = 'system_defaults' + d.defkey = key + d.defvalue = val + d.save(1) + +# +# Clear recycle bin +# +def clear_recycle_bin(): + sql = webnotes.conn.sql + + tl = sql('show tables') + total_deleted = 0 + for t in tl: + fl = [i[0] for i in sql('desc `%s`' % t[0])] + + if 'name' in fl: + total_deleted += sql("select count(*) from `%s` where name like '__overwritten:%%'" % t[0])[0][0] + sql("delete from `%s` where name like '__overwritten:%%'" % t[0]) + + if 'parent' in fl: + total_deleted += sql("select count(*) from `%s` where parent like '__oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like '__oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'old_parent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'old_parent:%%'" % t[0]) + + return "%s records deleted" % str(int(total_deleted)) + + +# Send Error Report +# ============================================================================== + +def send_error_report(): + sql = webnotes.conn.sql + m = '' + acc_id = webnotes.conn.get_value('Control Panel',None,'account_id') or '' + if acc_id: m = 'Account Id : '+acc_id + form = webnotes.form + err_msg = ''' + %s
+ Comment: %s + Err Msg : %s + ''' % (m, form.getvalue('msg') or '', form.getvalue('err_msg')) + sendmail([webnotes.conn.get_value('Control Panel',None,'support_email_id') or 'support@iwebnotes.com'], sender=webnotes.session['user'], msg=err_msg, subject='Error Report '+m) + +# pretty print a dict +# ============================================================================== + +def pprint_dict(d, level=1): + indent = '' + for i in range(0,level): + indent += '\t' + lines = [] + kl = d.keys() + kl.sort() + for key in kl: + tmp = {key: d[key]} + lines.append(indent + str(tmp)[1:-1] ) + return indent + '{\n' \ + + indent + ',\n\t'.join(lines) \ + + '\n' + indent + '}' diff --git a/cgi-bin/webnotes/utils/archive.py b/cgi-bin/webnotes/utils/archive.py new file mode 100644 index 0000000000..de945f58d6 --- /dev/null +++ b/cgi-bin/webnotes/utils/archive.py @@ -0,0 +1,107 @@ +import webnotes + +sql = webnotes.conn.sql + +# main function +# ------------------------- + +def archive_doc(doctype, name, restore=0): + archive_record(doctype, name, restore) + + tables = sql("select options from tabDocField where parent=%s and fieldtype='Table'", doctype) + for t in tables: + try: + rec_list = sql("select name from `%s%s` where parent=%s" % ((restore and 'arc' or 'tab') ,t[0], '%s'), name) + except Exception,e: + if e.args[0]==1146: # no child table + rec_list = [] + else: + raise e + + for r in rec_list: + archive_record(t[0], r[0], restore) + +# archive individual record +# ------------------------- + +def archive_record(doctype, name, restore = 0): + src_tab = (restore and 'arc' or 'tab') + doctype + tar_tab = (restore and 'tab' or 'arc') + doctype + + # get the record + try: + rec = sql("select * from `%s` where name=%s for update" % (src_tab, '%s'), name, as_dict=1)[0] + except Exception, e: + if e.args[0]==1146: + return # source table does not exist + else: + raise e + + # insert the record + insert_record(doctype, tar_tab, name) + + # put it field by field (ignore missing columns) + for field in rec.keys(): + if rec.get(field): + update_value(src_tab, tar_tab, name, rec, field) + + # delete from main + try: + sql("delete from `%s` where name=%s limit 1" % (src_tab, '%s'), name) + except Exception, e: + if e.args[0]==1451: + webnotes.msgprint("Cannot archive %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name)) + + # delete from target, as it will create a double copy! + sql("delete from `%s` where name=%s limit 1" % (tar_tab, '%s'), name) + +# insert the record +# ------------------------- + +def insert_record_name(tab, name): + sql("insert ignore into `%s` (name) values (%s)" % (tab, '%s'), name) + +# insert record +# ------------------------- + +def insert_record(doctype, tar_tab, name): + try: + insert_record_name(tar_tab, name) + except Exception, e: + if e.args[0]==1146: + # missing table - create it + from webnotes.model.db_schema import updatedb + updatedb(doctype, 1) + + # again + insert_record_name(tar_tab, name) + else: + raise e + +# update single value +# ------------------------- + +def update_single_value(tab, field, value, name): + sql("update `%s` set `%s`=%s where name=%s" % (tab, field, '%s', '%s'), (value, name)) + + +# update value +# ------------------------- + +def update_value(src_tab, tar_tab, name, rec, field): + try: + update_single_value(tar_tab, field, rec[field], name) + except Exception, e: + if e.args[0]==1054: + # column missing.... add it? + ftype = sql("show columns from `%s` like '%s'" % (src_tab, field))[0][1] + + webnotes.conn.commit() # causes implict commit + sql("alter table `%s` add column `%s` %s" % (tar_tab, field, ftype)) + webnotes.conn.begin() + + # again + update_single_value(tar_tab, field, rec[field], name) + else: + raise e + diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py new file mode 100644 index 0000000000..804750fa29 --- /dev/null +++ b/cgi-bin/webnotes/utils/backups.py @@ -0,0 +1,107 @@ +import webnotes + +backup_folder = '/backups' +mysql_path = '' +download_folder = 'backups' + +def mysqldump(db, folder=''): + global mysql_path + import os + import webnotes.defs + + os.system('%(path)smysqldump %(db)s > %(folder)s%(db)s.sql -u %(db)s -p%(pwd)s --ignore-table=%(db)s.__DocTypeCache' % {'path':mysql_path, 'db':db, 'pwd':webnotes.defs.db_password, 'folder':folder}) + +def backup_db(db, conn, from_all=0): + import os + global backup_folder + + try: + # Check processlist + if from_all or len(conn.sql("show processlist")) == 1: + p = backup_folder + if from_all: p = backup_folder + '/dumps' + + # clear old file + os.system('rm %s/%s.tar.gz' % (p,db)) + + # dump + mysqldump(db, p+'/') + + # zip + os.system('tar czf %s/%s.tar.gz %s/%s.sql' % (p, db, p, db)) + os.system('rm %s/%s.sql' % (p, db)) + else: + print("Another process is running in database. Please try again") + except Exception, e: + #sql('unlock tables') + raise e + +def backup_all(): + # backups folder + import os + import webnotes.db + global backup_folder + + conn = webnotes.db.Database(use_default=1) + dblist = conn.sql('select db_name from tabAccount') + + # backup -all in /backups folder + for d in (('accounts',),) + dblist: + backup_db(d[0], conn, 1) + + conn.close() + + # dump all in /daily folder + import time, datetime + fname = 'daily-' + time.strftime('%Y-%m-%d') + '.tar.gz' + + # daily dump + os.system('tar czf %s/daily/%s %s/dumps' % (backup_folder, fname, backup_folder)) + + # keep only three files + if len(os.listdir(backup_folder + '/daily')) > 3: + delete_oldest_file(backup_folder + '/daily') + + # if sunday, then copy to weekly + if datetime.datetime.now().weekday()==6: + os.system('cp '+backup_folder+'/daily/'+fname+' '+backup_folder+'/weekly/'+fname) + + # keep only three files + if len(os.listdir(backup_folder + '/weekly')) > 3: + delete_oldest_file(backup_folder + '/weekly') + +def delete_oldest_file(folder): + import os + a = sorted(os.listdir(folder), key=lambda fn: os.stat(folder+'/'+fn).st_mtime, reverse=False) + if a: + os.system('rm %s/%s' % (folder, a[0])) + +def get_backup(): + import webnotes + import os, time + + global backup_folder, download_folder + + # get the last nightly backup file from the backups folder + os.chdir(download_folder) + + if webnotes.conn.cur_db_name: + fname = webnotes.conn.cur_db_name + '.tar.gz' + + # rename it + from random import choice + lnd='0123456789' + new_name = ''.join(map(lambda x,y=lnd: choice(y), range(8))) + '.sql.gz' + folder = backup_folder + '/dumps/' + + # get the newest file + if os.path.exists(folder): + os.system('cp '+ folder + webnotes.conn.cur_db_name+'.sql.gz' + ' ./' + new_name) + webnotes.msgprint('Your nightly backup is available for download by clicking here (only for the next few hours)') + + # delete any files older than a day + now = time.time() + for f in os.listdir('.'): + if os.stat(f).st_mtime < (now - 86400): + if os.path.isfile(f): + os.remove(f) diff --git a/cgi-bin/webnotes/utils/cache.py b/cgi-bin/webnotes/utils/cache.py new file mode 100644 index 0000000000..a77427eada --- /dev/null +++ b/cgi-bin/webnotes/utils/cache.py @@ -0,0 +1,57 @@ +""" +Simple Caching: + +Stores key-value pairs in database and enables simple caching + +get_item(key).get() returns the cached value if not expired (else returns null) +get_item(key).set(interval = 60000) sets a value to cache, expiring after x seconds +get_item(key).clear() clears an old value +setup() sets up cache +""" + +import webnotes + +class CacheItem: + def __init__(self, key): + """create a new cache""" + self.key = key + + 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] + except Exception: + return None + + def set(self, value, interval=6000): + """set a new value, with interval""" + try: + 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)) + except Exception, e: + if e.args[0]==1146: + setup() + self.set(value, interval) + else: raise e + + def clear(self): + """clear the item""" + webnotes.conn.sql("delete from __CacheItem where `key`=%s", self.key) + +def setup(): + webnotes.conn.commit() + webnotes.conn.sql("""create table __CacheItem( + `key` VARCHAR(180) NOT NULL PRIMARY KEY, + `value` TEXT, + `expires_on` TIMESTAMP + )""") + webnotes.conn.begin() + +def get_item(key): + """returns get CacheItem object""" + return CacheItem(key) + pass \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/email_lib/__init__.py b/cgi-bin/webnotes/utils/email_lib/__init__.py new file mode 100644 index 0000000000..abda347923 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/__init__.py @@ -0,0 +1,88 @@ +import webnotes + +def sendmail_html(sender, recipients, subject, html, text=None, template=None, send_now=1, reply_to=None): + """ + Send an html mail with alternative text and using Page Templates + """ + sendmail(recipients, sender, html, subject, send_now = send_now, reply_to = reply_to, template = template) + +def make_html_body(content, template = None): + """ + Generate html content from a Page Template object + """ + template_html = '%(content)s' + + if template: + from webnotes.model.code import get_code + template_html = get_code(webnotes.conn.get_value('Page Template', template, 'module'), 'Page Template', template, 'html', fieldname='template') + + return template_html % {'content': content} + + +def sendmail(recipients, sender='', msg='', subject='[No Subject]', parts=[], cc=[], attach=[], send_now=1, reply_to=None, template=None): + """ + send an html email as multipart with attachments and all + """ + + from webnotes.utils.email_lib.html2text import html2text + from webnotes.utils.email_lib.send import EMail + + email = EMail(sender, recipients, subject, reply_to=reply_to) + email.cc = cc + + if msg: + if template: + msg = make_html_body(msg, template) + else: + # if not html, then lets put some whitespace + if (not '
' in msg) or (not '

' in msg): + msg = msg.replace('\n','
') + + footer = get_footer() + msg = msg + (footer or '') + email.set_text(html2text(msg)) + email.set_html(msg) + for p in parts: + email.set_message(p[1]) + for a in attach: + email.attach(a) + + email.send(send_now) + + +def get_footer(): + """ + Returns combination of footer from globals and Control Panel + """ + + footer = webnotes.conn.get_value('Control Panel',None,'mail_footer') or '' + footer += (webnotes.conn.get_global('global_mail_footer') or '') + return footer + + +def send_form(): + """ + Emails a print format (form) + Called from form UI + """ + + from webnotes.utils.email_lib.form_email import FormEmail + FormEmail().send() + + +def get_contact_list(): + """ + Returns contacts (from autosuggest) + """ + import webnotes + + cond = ['`%s` like "%s%%"' % (f, webnotes.form.getvalue('txt')) for f in webnotes.form.getvalue('where').split(',')] + cl = webnotes.conn.sql("select `%s` from `tab%s` where %s" % ( + webnotes.form.getvalue('select') + ,webnotes.form.getvalue('from') + ,' OR '.join(cond) + ) + ) + webnotes.response['cl'] = filter(None, [c[0] for c in cl]) + + diff --git a/cgi-bin/webnotes/utils/email_lib/form_email.py b/cgi-bin/webnotes/utils/email_lib/form_email.py new file mode 100644 index 0000000000..5bd3be8007 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/form_email.py @@ -0,0 +1,160 @@ +import webnotes +from webnotes.utils import cint + +form = webnotes.form + +from webnotes.utils.email_lib import get_footer +from webnotes.utils.email_lib.send import EMail + +class FormEmail: + """ + Represents an email sent from a Form + """ + def __init__(self): + """ + Get paramteres from the cgi form object + """ + self.__dict__.update(webnotes.form_dict) + + self.recipients = None + if self.sendto: + self.recipients = self.sendto.replace(';', ',') + self.recipients = self.recipients.split(',') + + def update_contacts(self): + """ + Add new email contact to database + """ + import webnotes + from webnotes.model.doc import Document + + for r in self.recipients: + r = r.strip() + try: + if not webnotes.conn.sql("select email_id from tabContact where email_id=%s", r): + d = Document('Contact') + d.email_id = r + d.save(1) + except Exception, e: + if e.args[0]==1146: pass # no table + else: raise e + + def make_full_links(self): + """ + Adds server name the relative links, so that images etc can be seen correctly + """ + # only domain + if not self.__dict__.get('full_domain'): + return + + def make_full_link(match): + import os + link = match.group('name') + if not link.startswith('http'): + link = os.path.join(self.full_domain, link) + return 'src="%s"' % link + + import re + p = re.compile('src[ ]*=[ ]*" (?P [^"]*) "', re.VERBOSE) + self.body = p.sub(make_full_link, self.body) + + p = re.compile("src[ ]*=[ ]*' (?P [^']*) '", re.VERBOSE) + self.body = p.sub(make_full_link, self.body) + + def get_form_link(self): + """ + Returns publicly accessible form link + """ + public_domain = webnotes.conn.get_value('Control Panel', None, 'public_domain') + from webnotes.utils.encrypt import encrypt + + if not public_domain: + return '' + + args = { + 'dt': self.dt, + 'dn':self.dn, + 'acx': webnotes.conn.get_value('Control Panel', None, 'account_id'), + 'server': public_domain, + 'akey': encrypt(self.dn) + } + return '

If you are unable to view the form below click here to see it in your browser
' % args + + def set_attachments(self): + """ + Set attachments to the email from the form + """ + al = [] + try: + al = webnotes.conn.sql('select file_list from `tab%s` where name="%s"' % (form.getvalue('dt'), form.getvalue('dn'))) + if al: + al = (al[0][0] or '').split('\n') + except Exception, e: + if e.args[0]==1146: + pass # no attachments in single types! + else: + raise Exception, e + return al + + def build_message(self): + """ + Builds the message object + """ + + self.email = EMail(self.sendfrom, self.recipients, self.subject, alternative = 1) + + from webnotes.utils.email_lib.html2text import html2text + + self.make_full_links() + + # message + if not self.__dict__.get('message'): + self.message = 'Please find attached %s: %s\n' % (self.dt, self.dn) + + html_message = text_message = self.message.replace('\n','
') + + # separator + html_message += '
' + + # form itself (only in the html message) + html_message += self.body + + # form link + html_message += self.get_form_link() + text_message += self.get_form_link() + + # footer + footer = get_footer() + if footer: + html_message += footer + text_message += footer + + # message as text + self.email.set_text(html2text(text_message)) + self.email.set_html(html_message) + + def send(self): + """ + Send the form with html attachment + """ + + if not self.recipients: + webnotes.msgprint('No one to send to!') + return + + self.build_message() + + # print format (as attachment also - for text-only clients) + self.email.add_attachment(self.dn.replace(' ','').replace('/','-') + '.html', self.body) + + # attachments + if cint(self.with_attachments): + for a in self.set_attachments(): + a and self.email.attach(a.split(',')[0]) + + # cc + if self.cc: + self.email.cc = [self.cc] + + self.email.send(send_now=1) + webnotes.msgprint('Sent') \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/email_lib/html2text.py b/cgi-bin/webnotes/utils/email_lib/html2text.py new file mode 100644 index 0000000000..66258d2477 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/html2text.py @@ -0,0 +1,491 @@ +#!/usr/bin/env python +"""html2text: Turn HTML into equivalent Markdown-structured text.""" +__version__ = "3.02" +__author__ = "Aaron Swartz (me@aaronsw.com)" +__copyright__ = "(C) 2004-2008 Aaron Swartz. GNU GPL 3." +__contributors__ = ["Martin 'Joey' Schulze", "Ricardo Reyes", "Kevin Jay North"] + +# TODO: +# Support decoded entities with unifiable. + +try: + True +except NameError: + setattr(__builtins__, 'True', 1) + setattr(__builtins__, 'False', 0) + +def has_key(x, y): + if hasattr(x, 'has_key'): return x.has_key(y) + else: return y in x + +try: + import htmlentitydefs + import urlparse + import HTMLParser +except ImportError: #Python3 + import html.entities as htmlentitydefs + import urllib.parse as urlparse + import html.parser as HTMLParser +try: #Python3 + import urllib.request as urllib +except: + import urllib +import optparse, re, sys, codecs, types + +try: from textwrap import wrap +except: pass + +# Use Unicode characters instead of their ascii psuedo-replacements +UNICODE_SNOB = 0 + +# Put the links after each paragraph instead of at the end. +LINKS_EACH_PARAGRAPH = 0 + +# Wrap long lines at position. 0 for no wrapping. (Requires Python 2.3.) +BODY_WIDTH = 78 + +# Don't show internal links (href="#local-anchor") -- corresponding link targets +# won't be visible in the plain text file anyway. +SKIP_INTERNAL_LINKS = False + +### Entity Nonsense ### + +def name2cp(k): + if k == 'apos': return ord("'") + if hasattr(htmlentitydefs, "name2codepoint"): # requires Python 2.3 + return htmlentitydefs.name2codepoint[k] + else: + k = htmlentitydefs.entitydefs[k] + if k.startswith("&#") and k.endswith(";"): return int(k[2:-1]) # not in latin-1 + return ord(codecs.latin_1_decode(k)[0]) + +unifiable = {'rsquo':"'", 'lsquo':"'", 'rdquo':'"', 'ldquo':'"', +'copy':'(C)', 'mdash':'--', 'nbsp':' ', 'rarr':'->', 'larr':'<-', 'middot':'*', +'ndash':'-', 'oelig':'oe', 'aelig':'ae', +'agrave':'a', 'aacute':'a', 'acirc':'a', 'atilde':'a', 'auml':'a', 'aring':'a', +'egrave':'e', 'eacute':'e', 'ecirc':'e', 'euml':'e', +'igrave':'i', 'iacute':'i', 'icirc':'i', 'iuml':'i', +'ograve':'o', 'oacute':'o', 'ocirc':'o', 'otilde':'o', 'ouml':'o', +'ugrave':'u', 'uacute':'u', 'ucirc':'u', 'uuml':'u'} + +unifiable_n = {} + +for k in unifiable.keys(): + unifiable_n[name2cp(k)] = unifiable[k] + +def charref(name): + if name[0] in ['x','X']: + c = int(name[1:], 16) + else: + c = int(name) + + if not UNICODE_SNOB and c in unifiable_n.keys(): + return unifiable_n[c] + else: + try: + return unichr(c) + except NameError: #Python3 + return chr(c) + +def entityref(c): + if not UNICODE_SNOB and c in unifiable.keys(): + return unifiable[c] + else: + try: name2cp(c) + except KeyError: return "&" + c + ';' + else: + try: + return unichr(name2cp(c)) + except NameError: #Python3 + return chr(name2cp(c)) + +def replaceEntities(s): + s = s.group(1) + if s[0] == "#": + return charref(s[1:]) + else: return entityref(s) + +r_unescape = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") +def unescape(s): + return r_unescape.sub(replaceEntities, s) + +### End Entity Nonsense ### + +def onlywhite(line): + """Return true if the line does only consist of whitespace characters.""" + for c in line: + if c is not ' ' and c is not ' ': + return c is ' ' + return line + +def optwrap(text): + """Wrap all paragraphs in the provided text.""" + if not BODY_WIDTH: + return text + + assert wrap, "Requires Python 2.3." + result = '' + newlines = 0 + for para in text.split("\n"): + if len(para) > 0: + if para[0] != ' ' and para[0] != '-' and para[0] != '*': + for line in wrap(para, BODY_WIDTH): + result += line + "\n" + result += "\n" + newlines = 2 + else: + if not onlywhite(para): + result += para + "\n" + newlines = 1 + else: + if newlines < 2: + result += "\n" + newlines += 1 + return result + +def hn(tag): + if tag[0] == 'h' and len(tag) == 2: + try: + n = int(tag[1]) + if n in range(1, 10): return n + except ValueError: return 0 + +class _html2text(HTMLParser.HTMLParser): + def __init__(self, out=None, baseurl=''): + HTMLParser.HTMLParser.__init__(self) + + if out is None: self.out = self.outtextf + else: self.out = out + try: + self.outtext = unicode() + except NameError: # Python3 + self.outtext = str() + self.quiet = 0 + self.p_p = 0 + self.outcount = 0 + self.start = 1 + self.space = 0 + self.a = [] + self.astack = [] + self.acount = 0 + self.list = [] + self.blockquote = 0 + self.pre = 0 + self.startpre = 0 + self.lastWasNL = 0 + self.abbr_title = None # current abbreviation definition + self.abbr_data = None # last inner HTML (for abbr being defined) + self.abbr_list = {} # stack of abbreviations to write later + self.baseurl = baseurl + + def outtextf(self, s): + self.outtext += s + + def close(self): + HTMLParser.HTMLParser.close(self) + + self.pbr() + self.o('', 0, 'end') + + return self.outtext + + def handle_charref(self, c): + self.o(charref(c)) + + def handle_entityref(self, c): + self.o(entityref(c)) + + def handle_starttag(self, tag, attrs): + self.handle_tag(tag, attrs, 1) + + def handle_endtag(self, tag): + self.handle_tag(tag, None, 0) + + def previousIndex(self, attrs): + """ returns the index of certain set of attributes (of a link) in the + self.a list + + If the set of attributes is not found, returns None + """ + if not has_key(attrs, 'href'): return None + + i = -1 + for a in self.a: + i += 1 + match = 0 + + if has_key(a, 'href') and a['href'] == attrs['href']: + if has_key(a, 'title') or has_key(attrs, 'title'): + if (has_key(a, 'title') and has_key(attrs, 'title') and + a['title'] == attrs['title']): + match = True + else: + match = True + + if match: return i + + def handle_tag(self, tag, attrs, start): + #attrs = fixattrs(attrs) + + if hn(tag): + self.p() + if start: self.o(hn(tag)*"#" + ' ') + + if tag in ['p', 'div']: self.p() + + if tag == "br" and start: self.o(" \n") + + if tag == "hr" and start: + self.p() + self.o("* * *") + self.p() + + if tag in ["head", "style", 'script']: + if start: self.quiet += 1 + else: self.quiet -= 1 + + if tag in ["body"]: + self.quiet = 0 # sites like 9rules.com never close + + if tag == "blockquote": + if start: + self.p(); self.o('> ', 0, 1); self.start = 1 + self.blockquote += 1 + else: + self.blockquote -= 1 + self.p() + + if tag in ['em', 'i', 'u']: self.o("_") + if tag in ['strong', 'b']: self.o("**") + if tag == "code" and not self.pre: self.o('`') #TODO: `` `this` `` + if tag == "abbr": + if start: + attrsD = {} + for (x, y) in attrs: attrsD[x] = y + attrs = attrsD + + self.abbr_title = None + self.abbr_data = '' + if has_key(attrs, 'title'): + self.abbr_title = attrs['title'] + else: + if self.abbr_title != None: + self.abbr_list[self.abbr_data] = self.abbr_title + self.abbr_title = None + self.abbr_data = '' + + if tag == "a": + if start: + attrsD = {} + for (x, y) in attrs: attrsD[x] = y + attrs = attrsD + if has_key(attrs, 'href') and not (SKIP_INTERNAL_LINKS and attrs['href'].startswith('#')): + self.astack.append(attrs) + self.o("[") + else: + self.astack.append(None) + else: + if self.astack: + a = self.astack.pop() + if a: + i = self.previousIndex(a) + if i is not None: + a = self.a[i] + else: + self.acount += 1 + a['count'] = self.acount + a['outcount'] = self.outcount + self.a.append(a) + self.o("][" + str(a['count']) + "]") + + if tag == "img" and start: + attrsD = {} + for (x, y) in attrs: attrsD[x] = y + attrs = attrsD + if has_key(attrs, 'src'): + attrs['href'] = attrs['src'] + alt = attrs.get('alt', '') + i = self.previousIndex(attrs) + if i is not None: + attrs = self.a[i] + else: + self.acount += 1 + attrs['count'] = self.acount + attrs['outcount'] = self.outcount + self.a.append(attrs) + self.o("![") + self.o(alt) + self.o("]["+ str(attrs['count']) +"]") + + if tag == 'dl' and start: self.p() + if tag == 'dt' and not start: self.pbr() + if tag == 'dd' and start: self.o(' ') + if tag == 'dd' and not start: self.pbr() + + if tag in ["ol", "ul"]: + if start: + self.list.append({'name':tag, 'num':0}) + else: + if self.list: self.list.pop() + + self.p() + + if tag == 'li': + if start: + self.pbr() + if self.list: li = self.list[-1] + else: li = {'name':'ul', 'num':0} + self.o(" "*len(self.list)) #TODO: line up
  1. s > 9 correctly. + if li['name'] == "ul": self.o("* ") + elif li['name'] == "ol": + li['num'] += 1 + self.o(str(li['num'])+". ") + self.start = 1 + else: + self.pbr() + + if tag in ["table", "tr"] and start: self.p() + if tag == 'td': self.pbr() + + if tag == "pre": + if start: + self.startpre = 1 + self.pre = 1 + else: + self.pre = 0 + self.p() + + def pbr(self): + if self.p_p == 0: self.p_p = 1 + + def p(self): self.p_p = 2 + + def o(self, data, puredata=0, force=0): + if self.abbr_data is not None: self.abbr_data += data + + if not self.quiet: + if puredata and not self.pre: + data = re.sub('\s+', ' ', data) + if data and data[0] == ' ': + self.space = 1 + data = data[1:] + if not data and not force: return + + if self.startpre: + #self.out(" :") #TODO: not output when already one there + self.startpre = 0 + + bq = (">" * self.blockquote) + if not (force and data and data[0] == ">") and self.blockquote: bq += " " + + if self.pre: + bq += " " + data = data.replace("\n", "\n"+bq) + + if self.start: + self.space = 0 + self.p_p = 0 + self.start = 0 + + if force == 'end': + # It's the end. + self.p_p = 0 + self.out("\n") + self.space = 0 + + + if self.p_p: + self.out(('\n'+bq)*self.p_p) + self.space = 0 + + if self.space: + if not self.lastWasNL: self.out(' ') + self.space = 0 + + if self.a and ((self.p_p == 2 and LINKS_EACH_PARAGRAPH) or force == "end"): + if force == "end": self.out("\n") + + newa = [] + for link in self.a: + if self.outcount > link['outcount']: + self.out(" ["+ str(link['count']) +"]: " + urlparse.urljoin(self.baseurl, link['href'])) + if has_key(link, 'title'): self.out(" ("+link['title']+")") + self.out("\n") + else: + newa.append(link) + + if self.a != newa: self.out("\n") # Don't need an extra line when nothing was done. + + self.a = newa + + if self.abbr_list and force == "end": + for abbr, definition in self.abbr_list.items(): + self.out(" *[" + abbr + "]: " + definition + "\n") + + self.p_p = 0 + self.out(data) + self.lastWasNL = data and data[-1] == '\n' + self.outcount += 1 + + def handle_data(self, data): + if r'\/script>' in data: self.quiet -= 1 + self.o(data, 1) + + def unknown_decl(self, data): pass + +def wrapwrite(text): + text = text.encode('utf-8') + try: #Python3 + sys.stdout.buffer.write(text) + except AttributeError: + sys.stdout.write(text) + +def html2text_file(html, out=wrapwrite, baseurl=''): + h = _html2text(out, baseurl) + h.feed(html) + h.feed("") + return h.close() + +def html2text(html, baseurl=''): + return optwrap(html2text_file(html, None, baseurl)) + +if __name__ == "__main__": + baseurl = '' + + p = optparse.OptionParser('%prog [(filename|url) [encoding]]', + version='%prog ' + __version__) + args = p.parse_args()[1] + if len(args) > 0: + file_ = args[0] + encoding = None + if len(args) == 2: + encoding = args[1] + if len(args) > 2: + p.error('Too many arguments') + + if file_.startswith('http://') or file_.startswith('https://'): + baseurl = file_ + j = urllib.urlopen(baseurl) + text = j.read() + if encoding is None: + try: + from feedparser import _getCharacterEncoding as enc + except ImportError: + enc = lambda x, y: ('utf-8', 1) + encoding = enc(j.headers, text)[0] + if encoding == 'us-ascii': + encoding = 'utf-8' + data = text.decode(encoding) + + else: + data = open(file_, 'rb').read() + if encoding is None: + try: + from chardet import detect + except ImportError: + detect = lambda x: {'encoding': 'utf-8'} + encoding = detect(data)['encoding'] + data = data.decode(encoding) + else: + data = sys.stdin.read() + wrapwrite(html2text(data, baseurl)) diff --git a/cgi-bin/webnotes/utils/email_lib/receive.py b/cgi-bin/webnotes/utils/email_lib/receive.py new file mode 100644 index 0000000000..3827fa46e3 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/receive.py @@ -0,0 +1,142 @@ +""" + This module contains classes for managing incoming emails +""" + +class IncomingMail: + """ + Single incoming email object. Extracts, text / html and attachments from the email + """ + def __init__(self, content): + """ + Parse the incoming mail content + """ + import email + + self.mail = email.message_from_string(content) + self.text_content = '' + self.html_content = '' + self.attachments = [] + self.parse() + + def get_text_content(self): + """ + Returns the text parts of the email. If None, then HTML parts + """ + return self.text_content or self.html_content + + def get_charset(self, part): + """ + Guesses character set + """ + charset = part.get_content_charset() + if not charset: + import chardet + charset = chardet.detect(str(part))['encoding'] + + return charset + + def get_payload(self, part, charset): + """ + get utf-8 encoded part content + """ + return unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') + + def get_attachment(self, part, charset): + """ + Extracts an attachment + """ + self.attachments.append({ + 'content-type': part.get_content_type(), + 'filename': part.get_filename(), + 'content': self.get_payload(part, charset) + }) + + def parse(self): + """ + Extracts text, html and attachments from the mail + """ + for part in self.mail.walk(): + self.process_part(part) + + def get_thread_id(self): + """ + Extracts thread id of the message between first [] + from the subject + """ + subject = self.mail.get('Subject', '') + if '[' in subject and ']' in subject: + return subject.split('[')[1].split(']')[0] + + def process_part(self, part): + """ + Process a single part of an email + """ + charset = self.get_charset(part) + content_type = part.get_content_type() + + if content_type == 'text/plain': + self.text_content += self.get_payload(part, charset) + + if content_type == 'text/html': + self.html_content += self.get_payload(part, charset) + + if part.get_filename(): + self.get_attachment(part, charset) + +class POP3Mailbox: + """ + A simple pop3 mailbox, abstracts connection and mail extraction + To use, subclass it and override method process_message(from, subject, text, thread_id) + """ + + def __init__(self, settings_doc): + """ + settings_doc must contain + is_ssl, host, username, password + """ + from webnotes.model.doc import Document + self.settings = Document(settings_doc, settings_doc) + + def connect(self): + """ + Connects to the mailbox + """ + import poplib + + if self.settings.use_ssl: + self.pop = poplib.POP3_SSL(self.settings.host) + else: + self.pop = poplib.POP3(self.settings.host) + self.pop.user(self.settings.username) + self.pop.pass_(self.settings.password) + + + def get_messages(self): + """ + Loads messages from the mailbox and calls + process_message for each message + """ + + if not self.check_mails(): + return # nothing to do + + self.connect() + num = len(self.pop.list()[1]) + for m in range(num): + msg = self.pop.retr(m+1) + self.process_message(IncomingMail('\n'.join(msg[1]))) + self.pop.dele(m+1) + self.pop.quit() + + def check_mails(self): + """ + To be overridden + If mailbox is to be scanned, returns true + """ + return true + + def process_message(self, mail): + """ + To be overriden + """ + pass diff --git a/cgi-bin/webnotes/utils/email_lib/send.py b/cgi-bin/webnotes/utils/email_lib/send.py new file mode 100644 index 0000000000..2eff8ed9bc --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/send.py @@ -0,0 +1,293 @@ +""" +Sends email via outgoing server specified in "Control Panel" +Allows easy adding of Attachments of "File" objects +""" + +import webnotes +import webnotes.defs +from webnotes import msgprint +import email + +class EMail: + """ + Wrapper on the email module. Email object represents emails to be sent to the client. + Also provides a clean way to add binary `FileData` attachments + Also sets all messages as multipart/alternative for cleaner reading in text-only clients + """ + def __init__(self, sender='', recipients=[], subject='', from_defs=0, alternative=0, reply_to=None): + from email.mime.multipart import MIMEMultipart + if type(recipients)==str: + recipients = recipients.replace(';', ',') + recipients = recipients.split(',') + + self.from_defs = from_defs + self.sender = sender + self.reply_to = reply_to or sender + self.recipients = recipients + self.subject = subject + + self.msg_root = MIMEMultipart('mixed') + self.msg_multipart = MIMEMultipart('alternative') + self.msg_root.attach(self.msg_multipart) + self.cc = [] + + def set_text(self, message): + """ + Attach message in the text portion of multipart/alternative + """ + from email.mime.text import MIMEText + part = MIMEText(message, 'plain') + self.msg_multipart.attach(part) + + def set_html(self, message): + """ + Attach message in the html portion of multipart/alternative + """ + from email.mime.text import MIMEText + part = MIMEText(message, 'html') + self.msg_multipart.attach(part) + + def set_message(self, message, mime_type='text/html', as_attachment=0, filename='attachment.html'): + """ + Append the message with MIME content to the root node (as attachment) + """ + from email.mime.text import MIMEText + + maintype, subtype = mime_type.split('/') + part = MIMEText(message, _subtype = subtype) + + if as_attachment: + part.add_header('Content-Disposition', 'attachment', filename=filename) + + self.msg_root.attach(part) + + def attach_file(self, n): + """ + attach a file from the `FileData` table + """ + from webnotes.utils.file_manager import get_file + res = get_file(n) + if not res: + return + + self.add_attachment(res[0], res[1]) + + def add_attachment(self, fname, fcontent, content_type=None): + + from email.mime.audio import MIMEAudio + from email.mime.base import MIMEBase + from email.mime.image import MIMEImage + from email.mime.text import MIMEText + + import mimetypes + + if not content_type: + content_type, encoding = mimetypes.guess_type(fname) + + if content_type is None: + # No guess could be made, or the file is encoded (compressed), so + # use a generic bag-of-bits type. + content_type = 'application/octet-stream' + + maintype, subtype = content_type.split('/', 1) + if maintype == 'text': + # Note: we should handle calculating the charset + part = MIMEText(fcontent, _subtype=subtype) + elif maintype == 'image': + part = MIMEImage(fcontent, _subtype=subtype) + elif maintype == 'audio': + part = MIMEAudio(fcontent, _subtype=subtype) + else: + part = MIMEBase(maintype, subtype) + part.set_payload(fcontent) + # Encode the payload using Base64 + from email import encoders + encoders.encode_base64(part) + + # Set the filename parameter + if fname: + part.add_header('Content-Disposition', 'attachment', filename=fname) + + self.msg_root.attach(part) + + def validate(self): + """ + validate the email ids + """ + if not self.sender: + self.sender = webnotes.conn.get_value('Control Panel',None,'auto_email_id') + + from webnotes.utils import validate_email_add + # validate ids + if self.sender and (not validate_email_add(self.sender)): + webnotes.msgprint("%s is not a valid email id" % self.sender, raise_exception = 1) + + if self.reply_to and (not validate_email_add(self.reply_to)): + webnotes.msgprint("%s is not a valid email id" % self.reply_to, raise_exception = 1) + + for e in self.recipients: + if not validate_email_add(e): + webnotes.msgprint("%s is not a valid email id" % e, raise_exception = 1) + + def setup(self): + """ + setup the SMTP (outgoing) server from `Control Panel` or defs.py + """ + if self.from_defs: + self.server = getattr(webnotes.defs,'mail_server','') + self.login = getattr(webnotes.defs,'mail_login','') + self.port = getattr(webnotes.defs,'mail_port',None) + self.password = getattr(webnotes.defs,'mail_password','') + self.use_ssl = getattr(webnotes.defs,'use_ssl',0) + + else: + import webnotes.model.doc + from webnotes.utils import cint + + # get defaults from control panel + cp = webnotes.model.doc.Document('Control Panel','Control Panel') + self.server = cp.outgoing_mail_server or getattr(webnotes.defs,'mail_server','') + self.login = cp.mail_login or getattr(webnotes.defs,'mail_login','') + self.port = cp.mail_port or getattr(webnotes.defs,'mail_port',None) + self.password = cp.mail_password or getattr(webnotes.defs,'mail_password','') + self.use_ssl = cint(cp.use_ssl) + + def make_msg(self): + self.msg_root['Subject'] = self.subject + self.msg_root['From'] = self.sender + self.msg_root['To'] = ', '.join([r.strip() for r in self.recipients]) + if self.reply_to and self.reply_to != self.sender: + self.msg_root['Reply-To'] = self.reply_to + if self.cc: + self.msg_root['CC'] = ', '.join([r.strip() for r in self.cc]) + + def add_to_queue(self): + # write to a file called "email_queue" or as specified in email + q = EmailQueue() + q.push({ + 'server': self.server, + 'port': self.port, + 'use_ssl': self.use_ssl, + 'login': self.login, + 'password': self.password, + 'sender': self.sender, + 'recipients': self.recipients, + 'msg': self.msg_root.as_string() + }) + q.close() + + def send(self, send_now = 0): + """ + send the message + """ + from webnotes.utils import cint + + self.setup() + self.validate() + self.make_msg() + + if (not send_now) and getattr(webnotes.defs, 'batch_emails', 0): + self.add_to_queue() + return + + import smtplib + sess = smtplib.SMTP(self.server, self.port or None) + + if self.use_ssl: + sess.ehlo() + sess.starttls() + sess.ehlo() + + ret = sess.login(self.login, self.password) + + # check if logged correctly + if ret[0]!=235: + msgprint(ret[1]) + raise Exception + + sess.sendmail(self.sender, self.recipients, self.msg_root.as_string()) + + try: + sess.quit() + except: + pass + + + + +# =========================================== +# Email Queue +# Maintains a list of emails in a file +# Flushes them when called from cron +# Defs settings: +# email_queue: (filename) [default: email_queue.py] +# +# From the scheduler, call: flush(qty) +# =========================================== + +class EmailQueue: + def __init__(self): + self.server = self.login = self.sess = None + self.filename = getattr(webnotes.defs, 'email_queue', 'email_queue.py') + + try: + f = open(self.filename, 'r') + self.queue = eval(f.read() or '[]') + f.close() + except IOError, e: + if e.args[0]==2: + self.queue = [] + else: + raise e + + def push(self, email): + self.queue.append(email) + + def close(self): + f = open(self.filename, 'w') + f.write(str(self.queue)) + f.close() + + def get_smtp_session(self, e): + if self.server==e['server'] and self.login==e['login'] and self.sess: + return self.sess + + webnotes.msgprint('getting server') + + import smtplib + + sess = smtplib.SMTP(e['server'], e['port'] or None) + + if self.use_ssl: + sess.ehlo() + sess.starttls() + sess.ehlo() + + ret = sess.login(e['login'], e['password']) + + # check if logged correctly + if ret[0]!=235: + webnotes.msgprint(ret[1]) + raise Exception + + self.sess = sess + self.server, self.login = e['server'], e['login'] + + return sess + + def flush(self, qty = 100): + f = open(self.filename, 'r') + + self.queue = eval(f.read() or '[]') + + if len(self.queue) < 100: + qty = len(self.queue) + + for i in range(qty): + e = self.queue[i] + sess = self.get_smtp_session(e) + sess.sendmail(e['sender'], e['recipients'], e['msg']) + + self.queue = self.queue[:(len(self.queue) - qty)] + self.close() + diff --git a/cgi-bin/webnotes/utils/encrypt.py b/cgi-bin/webnotes/utils/encrypt.py new file mode 100644 index 0000000000..80de8bf983 --- /dev/null +++ b/cgi-bin/webnotes/utils/encrypt.py @@ -0,0 +1,54 @@ +""" +XTEA Block Encryption Algorithm +Author: Paul Chakravarti (paul_dot_chakravarti_at_gmail_dot_com) +License: Public Domain +""" + +def get_key(): + # Encryption key is datetime of creation of DocType, DocType" + import webnotes + return webnotes.conn.sql("select creation from tabDocType where name='DocType'")[0][0].strftime('%Y%m%d%H%M%s')[:16] + +def encrypt(data, encryption_key = None): + if not encryption_key: + encryption_key = get_key() + return crypt(encryption_key, data).encode('hex') + +def decrypt(data, encryption_key = None): + if not encryption_key: + encryption_key = get_key() + return crypt(encryption_key, data.decode('hex')) + +def crypt(key,data,iv='\00\00\00\00\00\00\00\00',n=32): + def keygen(key,iv,n): + while True: + iv = xtea_encrypt(key,iv,n) + for k in iv: + yield ord(k) + xor = [ chr(x^y) for (x,y) in zip(map(ord,data),keygen(key,iv,n)) ] + return "".join(xor) + +def xtea_encrypt(key,block,n=32,endian="!"): + import struct + v0,v1 = struct.unpack(endian+"2L",block) + k = struct.unpack(endian+"4L",key) + sum,delta,mask = 0L,0x9e3779b9L,0xffffffffL + for round in range(n): + v0 = (v0 + (((v1<<4 ^ v1>>5) + v1) ^ (sum + k[sum & 3]))) & mask + sum = (sum + delta) & mask + v1 = (v1 + (((v0<<4 ^ v0>>5) + v0) ^ (sum + k[sum>>11 & 3]))) & mask + return struct.pack(endian+"2L",v0,v1) + +def xtea_decrypt(key,block,n=32,endian="!"): + import struct + + v0,v1 = struct.unpack(endian+"2L",block) + k = struct.unpack(endian+"4L",key) + delta,mask = 0x9e3779b9L,0xffffffffL + sum = (delta * n) & mask + for round in range(n): + v1 = (v1 - (((v0<<4 ^ v0>>5) + v0) ^ (sum + k[sum>>11 & 3]))) & mask + sum = (sum - delta) & mask + v0 = (v0 - (((v1<<4 ^ v1>>5) + v1) ^ (sum + k[sum & 3]))) & mask + return struct.pack(endian+"2L",v0,v1) + diff --git a/cgi-bin/webnotes/utils/file_manager.py b/cgi-bin/webnotes/utils/file_manager.py new file mode 100644 index 0000000000..26575ffd5f --- /dev/null +++ b/cgi-bin/webnotes/utils/file_manager.py @@ -0,0 +1,202 @@ +def upload(): + import webnotes + form = webnotes.form + + # get record details + dt = form.getvalue('doctype') + dn = form.getvalue('docname') + at_id = form.getvalue('at_id') + + # save + fid, fname = save_uploaded() + + if fid: + # refesh the form! + webnotes.response['result'] = """ + + """ % (dt, dn, fid, fname.replace("'", "\\'"), at_id, dt, dn) + +# ------------------------------------------------------- + +def make_thumbnail(blob, size): + from PIL import Image + import cStringIO + + fobj = cStringIO.StringIO(blob) + image = Image.open(fobj) + image.thumbnail((tn,tn*2), Image.ANTIALIAS) + outfile = cStringIO.StringIO() + image.save(outfile, 'JPEG') + outfile.seek(0) + fcontent = outfile.read() + + return fcontent + + +def save_uploaded(js_okay='window.parent.msgprint("File Upload Successful")', js_fail=''): + import webnotes + import webnotes.utils + + webnotes.response['type'] = 'iframe' + + form, fid, fname = webnotes.form, None, None + + try: + # has attachment? + if 'filedata' in form: + i = form['filedata'] + + fname, content = i.filename, i.file.read() + + # thumbnail + if webnotes.form_dict.get('thumbnail'): + try: + content = make_thumbnail(content, int(form.get('thumbnail'))) + # change extension to jpg + fname = '.'.join(fname.split('.')[:-1])+'.jpg' + except Exception, e: + pass + + # 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 + +# ------------------------------------------------------- + +def save_file(fname, content, module=None): + import webnotes + from webnotes.model.doc import Document + + # some browsers return the full path + if '\\' in fname: + fname = fname.split('\\')[-1] + if '/' in fname: + fname = fname.split('/')[-1] + + # generate the ID (?) + f = Document('File Data') + f.file_name = fname + if module: + f.module = module + f.save(1) + + write_file(f.name, content) + + return f.name + +# ------------------------------------------------------- + +def write_file(fid, content): + import webnotes, os, webnotes.defs + + # test size + max_file_size = 1000000 + if hasattr(webnotes.defs, 'max_file_size'): + max_file_size = webnotes.defs.max_file_size + + if len(content) > max_file_size: + raise Exception, 'Maximum File Limit (%s MB) Crossed' % (int(max_file_size / 1000000)) + + # no slashes + fid = fid.replace('/','-') + + # save to a folder (not accessible to public) + folder = webnotes.get_files_path() + + # create account folder (if not exists) + webnotes.create_folder(folder) + + # write the file + file = open(os.path.join(folder, fid),'w+') + file.write(content) + file.close() + + +# ------------------------------------------------------- +def get_file_system_name(fname): + # get system name from File Data table + import webnotes + return webnotes.conn.sql("select name, file_name from `tabFile Data` where name=%s or file_name=%s", (fname, fname)) + +# ------------------------------------------------------- +def delete_file(fname, verbose=0): + import webnotes, os + + for f in get_file_system_name(fname): + webnotes.conn.sql("delete from `tabFile Data` where name=%s", f[0]) + + # delete file + file_id = f[0].replace('/','-') + try: + os.remove(os.path.join(webnotes.get_files_path(), file_id)) + except OSError, e: + if e.args[0]!=2: + raise e + + if verbose: webnotes.msgprint('File Deleted') + +# Get File +# ------------------------------------------------------- + +def get_file(fname): + import webnotes + in_fname = fname + + # from the "File" table + if webnotes.conn.exists('File',fname): + fname = webnotes.conn.sql("select file_list from tabFile where name=%s", fname) + fname = fname and fname[0][0] + fname = fname.split('\n')[0].split(',')[1] + + + if get_file_system_name(fname): + f = get_file_system_name(fname)[0] + else: + f = None + + + # read the file + import os + + file_id = f[0].replace('/','-') + file = open(os.path.join(webnotes.get_files_path(), file_id), 'r') + content = file.read() + file.close() + return [f[1], content] + +# Conversion Patch +# ------------------------------------------------------- + +def convert_to_files(verbose=0): + import webnotes + + # nfiles + fl = webnotes.conn.sql("select name from `tabFile Data`") + for f in fl: + # get the blob + blob = webnotes.conn.sql("select blob_content from `tabFile Data` where name=%s", f[0])[0][0] + + if blob: + + if hasattr(blob, 'tostring'): + blob = blob.tostring() + + # write the file + write_file(f[0], blob) + + if verbose: + webnotes.msgprint('%s updated' % f[0]) + +# ------------------------------------------------------- diff --git a/cgi-bin/webnotes/utils/jsmin.py b/cgi-bin/webnotes/utils/jsmin.py new file mode 100644 index 0000000000..f0d45b7b44 --- /dev/null +++ b/cgi-bin/webnotes/utils/jsmin.py @@ -0,0 +1,213 @@ +import os, os.path, shutil + +# This code is original from jsmin by Douglas Crockford, it was translated to +# Python by Baruch Even. The original code had the following copyright and +# license. +# +# /* jsmin.c +# 2007-05-22 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# The Software shall be used for Good, not Evil. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# */ + +from StringIO import StringIO + +def jsmin(js): + ins = StringIO(js) + outs = StringIO() + JavascriptMinify().minify(ins, outs) + str = outs.getvalue() + if len(str) > 0 and str[0] == '\n': + str = str[1:] + return str + +def isAlphanum(c): + """return true if the character is a letter, digit, underscore, + dollar sign, or non-ASCII character. + """ + return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or + (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126)); + +class UnterminatedComment(Exception): + pass + +class UnterminatedStringLiteral(Exception): + pass + +class UnterminatedRegularExpression(Exception): + pass + +class JavascriptMinify(object): + + def _outA(self): + self.outstream.write(self.theA) + def _outB(self): + self.outstream.write(self.theB) + + def _get(self): + """return the next character from stdin. Watch out for lookahead. If + the character is a control character, translate it to a space or + linefeed. + """ + c = self.theLookahead + self.theLookahead = None + if c == None: + c = self.instream.read(1) + if c >= ' ' or c == '\n': + return c + if c == '': # EOF + return '\000' + if c == '\r': + return '\n' + return ' ' + + def _peek(self): + self.theLookahead = self._get() + return self.theLookahead + + def _next(self): + """get the next character, excluding comments. peek() is used to see + if an unescaped '/' is followed by a '/' or '*'. + """ + c = self._get() + if c == '/' and self.theA != '\\': + p = self._peek() + if p == '/': + c = self._get() + while c > '\n': + c = self._get() + return c + if p == '*': + c = self._get() + while 1: + c = self._get() + if c == '*': + if self._peek() == '/': + self._get() + return ' ' + if c == '\000': + raise UnterminatedComment() + + return c + + def _action(self, action): + """do something! What you do is determined by the argument: + 1 Output A. Copy B to A. Get the next B. + 2 Copy B to A. Get the next B. (Delete A). + 3 Get the next B. (Delete B). + action treats a string as a single character. Wow! + action recognizes a regular expression if it is preceded by ( or , or =. + """ + if action <= 1: + self._outA() + + if action <= 2: + self.theA = self.theB + if self.theA == "'" or self.theA == '"': + while 1: + self._outA() + self.theA = self._get() + if self.theA == self.theB: + break + if self.theA <= '\n': + raise UnterminatedStringLiteral() + if self.theA == '\\': + self._outA() + self.theA = self._get() + + + if action <= 3: + self.theB = self._next() + if self.theB == '/' and (self.theA == '(' or self.theA == ',' or + self.theA == '=' or self.theA == ':' or + self.theA == '[' or self.theA == '?' or + self.theA == '!' or self.theA == '&' or + self.theA == '|' or self.theA == ';' or + self.theA == '{' or self.theA == '}' or + self.theA == '\n'): + self._outA() + self._outB() + while 1: + self.theA = self._get() + if self.theA == '/': + break + elif self.theA == '\\': + self._outA() + self.theA = self._get() + elif self.theA <= '\n': + raise UnterminatedRegularExpression() + self._outA() + self.theB = self._next() + + + def _jsmin(self): + """Copy the input to the output, deleting the characters which are + insignificant to JavaScript. Comments will be removed. Tabs will be + replaced with spaces. Carriage returns will be replaced with linefeeds. + Most spaces and linefeeds will be removed. + """ + self.theA = '\n' + self._action(3) + + while self.theA != '\000': + if self.theA == ' ': + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + elif self.theA == '\n': + if self.theB in ['{', '[', '(', '+', '-']: + self._action(1) + elif self.theB == ' ': + self._action(3) + else: + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + else: + if self.theB == ' ': + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + elif self.theB == '\n': + if self.theA in ['}', ']', ')', '+', '-', '"', '\'']: + self._action(1) + else: + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + else: + self._action(1) + + def minify(self, instream, outstream): + self.instream = instream + self.outstream = outstream + self.theA = '\n' + self.theB = None + self.theLookahead = None + + self._jsmin() + self.instream.close() \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/nestedset.py b/cgi-bin/webnotes/utils/nestedset.py new file mode 100644 index 0000000000..13af8ec4de --- /dev/null +++ b/cgi-bin/webnotes/utils/nestedset.py @@ -0,0 +1,80 @@ +# Tree (Hierarchical) Nested Set Model (nsm) +# +# To use the nested set model, +# use the following pattern +# 1. name your parent field as "parent_node" if not have a property nsm_parent_field as your field name in the document class +# 2. have a field called "old_parent" in your fields list - this identifies whether the parent has been changed +# 3. call update_nsm(doc_obj) in the on_upate method + +# ------------------------------------------ + +import webnotes + +# called in the on_update method +def update_nsm(doc_obj): + # get fields, data from the DocType + d = doc_obj.doc + pf, opf = 'parent_node', 'old_parent' + if hasattr(doc_obj,'nsm_parent_field'): + pf = doc_obj.nsm_parent_field + if hasattr(doc_obj,'nsm_oldparent_field'): + opf = doc_obj.nsm_oldparent_field + p, op = d.fields[pf], d.fields.get(opf, '') + + # has parent changed (?) or parent is None (root) + if not doc_obj.doc.lft and not doc_obj.doc.rgt: + update_add_node(doc_obj.doc.doctype, doc_obj.doc.name, p or '', pf) + elif op != p: + update_remove_node(doc_obj.doc.doctype, doc_obj.doc.name) + update_add_node(doc_obj.doc.doctype, doc_obj.doc.name, p or '', pf) + # set old parent + webnotes.conn.set(d, opf, p or '') + +def rebuild_tree(doctype, parent_field): + # get all roots + right = 1 + result = webnotes.conn.sql("SELECT name FROM `tab%s` WHERE `%s`='' or `%s` IS NULL" % (doctype, parent_field, parent_field)) + for r in result: + right = rebuild_node(doctype, r[0], right, parent_field) + +def rebuild_node(doctype, parent, left, parent_field): + # the right value of this node is the left value + 1 + right = left+1 + + # get all children of this node + result = webnotes.conn.sql("SELECT name FROM `tab%s` WHERE `%s`='%s'" % (doctype, parent_field, parent)) + for r in result: + right = rebuild_node(doctype, r[0], right, parent_field) + + # we've got the left value, and now that we've processed + # the children of this node we also know the right value + webnotes.conn.sql('UPDATE `tab%s` SET lft=%s, rgt=%s WHERE name="%s"' % (doctype,left,right,parent)) + + #return the right value of this node + 1 + return right+1 + +def update_add_node(doctype, name, parent, parent_field): + # get the last sibling of the parent + if parent: + right = webnotes.conn.sql("select rgt from `tab%s` where name='%s'" % (doctype, parent))[0][0] + else: # root + right = webnotes.conn.sql("select ifnull(max(rgt),0)+1 from `tab%s` where ifnull(`%s`,'') =''" % (doctype, parent_field))[0][0] + right = right or 1 + + # update all on the right + webnotes.conn.sql("update `tab%s` set rgt = rgt+2 where rgt >= %s" %(doctype,right)) + webnotes.conn.sql("update `tab%s` set lft = lft+2 where lft >= %s" %(doctype,right)) + + #$ update index of new node + webnotes.conn.sql("update `tab%s` set lft=%s, rgt=%s where name='%s'" % (doctype,right,right+1,name)) + return right + +def update_remove_node(doctype, name): + left = webnotes.conn.sql("select lft from `tab%s` where name='%s'" % (doctype,name)) + if left[0][0]: + # reset this node + webnotes.conn.sql("update `tab%s` set lft=0, rgt=0 where name='%s'" % (doctype,name)) + + # update all on the right + webnotes.conn.sql("update `tab%s` set rgt = rgt-2 where rgt > %s" %(doctype,left[0][0])) + webnotes.conn.sql("update `tab%s` set lft = lft-2 where lft > %s" %(doctype,left[0][0])) diff --git a/cgi-bin/webnotes/utils/scheduler.py b/cgi-bin/webnotes/utils/scheduler.py new file mode 100644 index 0000000000..9520caf865 --- /dev/null +++ b/cgi-bin/webnotes/utils/scheduler.py @@ -0,0 +1,166 @@ +""" +Simple Scheduler + +This scheduler is used to fire events across multiple databases. A database +master_scheduler is maintained with one event and one log table + +Events are added by different databases in the master scheduler using the +`set_event` method and they are executed by the cron. + +__main__ will call run + +To install: +----------- + +python install_lib.py [root] [password] master_scheduler + +In cron: +-------- + +python [path]webnotes/utils/scheduler.py + +""" + + +class Scheduler: + def connect(self): + if hasattr(self,'conn'): return + + import webnotes.defs, webnotes.db + try: + self.conn = webnotes.db.Database(user='master_scheduler', password=webnotes.defs.db_password) + except Exception, e: + self.setup() + self.connect() + + def set(self, event, interval, recurring, db_name=None): + """ + Add an event to the Event table in the master scheduler + """ + self.connect() + + if not db_name: + import webnotes + db_name = webnotes.conn.cur_db_name + + self.clear(db_name, event) + self.conn.sql("""insert into + Event (`db_name`, `event`, `interval`, next_execution, recurring) + values (%s, %s, %s, ADDTIME(NOW(), SEC_TO_TIME(%s)), %s) + """, (webnotes.conn.cur_db_name, event, interval, interval, recurring)) + + def get_events(self, db_name=None): + """ + Returns list of upcoming events + """ + self.connect() + if not db_name: + import webnotes + db_name = webnotes.conn.cur_db_name + + return self.conn.sql("select * from Event where db_name=%s", db_name, as_dict=1) + + + def get_log(self, db_name=None): + """ + Returns log of events + """ + self.connect() + if not db_name: + import webnotes + db_name = webnotes.conn.cur_db_name + + return self.conn.sql("select * from EventLog where db_name=%s limit 50", db_name, as_dict=1) + + def clear(self, db_name, event): + """ + Clears the event + """ + self.connect() + self.conn.sql("delete from Event where `event`=%s and db_name=%s", (event, db_name)) + + def execute(self, db_name, event): + """ + Executes event in the specifed db + """ + import webnotes, webnotes.defs, webnotes.db + + try: + webnotes.conn = webnotes.db.Database(user=db_name, password=webnotes.defs.db_password) + webnotes.session = {'user':'Administrator'} + + module = '.'.join(event.split('.')[:-1]) + method = event.split('.')[-1] + + exec 'from %s import %s' % (module, method) + + webnotes.conn.begin() + ret = locals()[method]() + webnotes.conn.commit() + webnotes.conn.close() + + self.log(db_name, event, ret or 'Ok') + + except Exception, e: + self.log(db_name, event, webnotes.getTraceback()) + + def log(self, db_name, event, traceback): + """ + Log an event error + """ + self.conn.sql("insert into `EventLog`(db_name, event, log, executed_on) values (%s, %s, %s, now())", \ + (db_name, event, traceback)) + + # delete old logs + self.conn.sql("delete from EventLog where executed_on < subdate(curdate(), interval 30 day)") + + def run(self): + """ + Run scheduled (due) events and reset time for recurring events + """ + el = self.conn.sql("""select `db_name`, `event`, `recurring`, `interval` + from `Event` + where next_execution < NOW()""", as_dict=1) + + for e in el: + # execute the event + self.execute(e['db_name'], e['event']) + + # if recurring, update next_execution + if e['recurring']: + self.conn.sql("update Event set next_execution = addtime(now(), sec_to_time(%s))", e['interval']) + + # else clear + else: + self.clear(e['db_name'], e['event']) + +def set_event(event, interval=60*60*24, recurring=1): + """ + Adds an event to the master scheduler + """ + return Scheduler().set(event, interval, recurring) + + +def cancel_event(event): + """ + Cancels an event + """ + import webnotes + return Scheduler().clear(webnotes.conn.cur_db_name, event) + +# to be called from cron +if __name__=='__main__': + import os,sys + + cgi_bin_path = os.path.sep.join(__file__.split(os.path.sep)[:-3]) + + sys.path.append(cgi_bin_path) + + import webnotes + import webnotes.defs + sys.path.append(getattr(webnotes.defs,'modules_path',None)) + + sch = Scheduler() + sch.connect() + sch.run() + \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/sitemap.py b/cgi-bin/webnotes/utils/sitemap.py new file mode 100644 index 0000000000..ffa0471b81 --- /dev/null +++ b/cgi-bin/webnotes/utils/sitemap.py @@ -0,0 +1,34 @@ +# to generate sitemaps + +frame_xml = """ +%s +""" + +link_xml = """\n%s%s""" + +# generate the sitemap XML +def generate_xml(conn, site_prefix): + global frame_xml, link_xml + import urllib + + # settings + max_doctypes = 10 + max_items = 1000 + + site_map = '' + + if site_prefix: + # list of all Guest pages (static content) + for r in conn.sql("SELECT name, modified FROM tabPage WHERE ifnull(publish,0)=1 ORDER BY modified DESC"): + page_url = site_prefix + '#!' + urllib.quote(r[0]) + site_map += link_xml % (page_url, r[1].strftime('%Y-%m-%d')) + + # list of all Records that are viewable by guests (Blogs, Articles etc) + try: + from event_handlers import get_sitemap_items + for i in get_sitemap_items(site_prefix): + site_map += link_xml % (i[0], i[1]) + except ImportError, e: + pass + + return frame_xml % site_map \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/transfer.py b/cgi-bin/webnotes/utils/transfer.py new file mode 100644 index 0000000000..3a389b02f4 --- /dev/null +++ b/cgi-bin/webnotes/utils/transfer.py @@ -0,0 +1,300 @@ +import webnotes +from webnotes.model.doc import Document + +def set_doc(doclist, ovr=0, ignore=1, onupdate=1): + dt = doclist[0]['doctype'] + + if webnotes.conn.exists(doclist[0]['doctype'], doclist[0]['name']): + # exists, merge if possible + + if dt=='DocType': + ud = UpdateDocType(doclist) + elif dt == 'Module Def': + ud = UpdateModuleDef(doclist) + elif dt == 'DocType Mapper': + ud = UpdateDocTypeMapper(doclist) + else: + ud = UpdateDocument(doclist) + else: + ud = UpdateDocument(doclist) + + ud.sync() + return '\n'.join(ud.log) + + + + +# +# Class to sync incoming document +# +class UpdateDocument: + def __init__(self, in_doclist=[]): + self.in_doclist = in_doclist + self.doc = Document(fielddata = in_doclist[0]) + self.modified = self.doc.modified # make a copy + self.doclist = [] + + self.log = [] + self.exists = 0 + + # sync + def sync(self): + is_mod = self.is_modified() + + if (not self.exists) or (is_mod): + webnotes.conn.begin() + if self.exists: + self.delete_existing() + self.save() + self.update_modified() + self.run_on_update() + webnotes.conn.commit() + + # check modified + def is_modified(self): + try: + timestamp = webnotes.conn.sql("select modified from `tab%s` where name=%s" % (self.doc.doctype, '%s'), self.doc.name) + except Exception ,e: + if(e.args[0]==1146): + return + else: + raise e + + if timestamp: + self.exists = 1 + if str(timestamp[0][0]) == self.doc.modified: + self.log.append('%s %s, No change' % (self.doc.doctype, self.doc.name)) + else: return 1 + + # delete existing + def delete_existing(self): + from webnotes.model import delete_doc + webnotes.conn.sql("set foreign_key_checks=0") + delete_doc(self.doc.doctype, self.doc.name) + webnotes.conn.sql("set foreign_key_checks=1") + + # update modified timestamp + def update_modified(self): + webnotes.conn.set(self.doc, 'modified', self.modified) + + def save(self): + # parent + self.doc.save(new = 1, ignore_fields = 1, check_links=0) + self.doclist = [self.doc] + self.save_children() + + def save_children(self): + for df in self.in_doclist[1:]: + self.save_one_doc(df) + + def save_one_doc(self, df, as_new=1): + d = Document(fielddata = df) + d.save(new = as_new, ignore_fields = 1, check_links=0) + self.doclist.append(d) + + def run_on_update(self): + from webnotes.model.code import get_server_obj + so = get_server_obj(self.doc, self.doclist) + if hasattr(so, 'on_update'): + so.on_update() + + + +# +# "Merge incoming doctype" +# +class UpdateDocumentMerge(UpdateDocument): + def __init__(self, in_doclist): + self.to_update_doctype = [] + UpdateDocument.__init__(self, in_doclist) + + def delete_existing(self): + pass + + def get_id(self, d): + pass + + def to_update(self, d): + return 1 + + def child_exists(self, d): + return self.get_id(d) + + def on_save(self): + pass + + def save(self): + if self.exists: + # save main doc + self.keep_values(self.doc) + self.doc.save(ignore_fields = 1, check_links=0) + self.doclist.append(self.doc) + self.save_children() + self.on_save() + self.log.append('Updated %s' % self.doc.name) + else: + UpdateDocument.save(self) + + def save_children(self): + for df in self.in_doclist[1:]: + d = Document(fielddata = df) + + # update doctype? + if d.doctype in self.to_update_doctype: + + # update this record? + if self.to_update(d): + + # is it new? + if self.child_exists(d): + self.keep_values(d) + d.save(ignore_fields = 1, check_links=0) + self.log.append('updated %s, %s' % (d.doctype, d.name)) + else: + d.save(1, ignore_fields = 1, check_links=0) + self.log.append('new %s' % d.doctype) + self.doclist.append(d) + + def keep_values(self, d): + if hasattr(self, 'get_orignal_values'): + ov = self.get_orignal_values(d) + if ov: + d.fields.update(ov) + + + +# +# Class to sync incoming doctype +# +class UpdateDocType(UpdateDocumentMerge): + def __init__(self, in_doclist): + UpdateDocumentMerge.__init__(self, in_doclist) + self.to_update_doctype = ['DocType', 'DocField'] + + def to_udpate(self, d): + if (d.fieldtype not in ['Section Break', 'Column Break', 'HTML']) and (d.fieldname or d.label): + return 1 + + def get_id(self, d): + key = d.fieldname and 'fieldname' or 'label' + return webnotes.conn.sql("""select name, options, permlevel, reqd, print_hide, hidden + from tabDocField where %s=%s and parent=%s""" % (key, '%s', '%s'), (d.fields[key], d.parent)) + + def on_save(self): + self.renum() + + def child_exists(self, d): + if d.doctype=='DocField': + return self.get_id(d) + + def get_orignal_values(self, d): + if d.doctype=='DocField': + t = self.get_id(d)[0] + return {'name': t[0], 'options': t[1], 'reqd':t[3], 'print_hide':t[4], 'hidden':t[5]} + + if d.doctype=='DocType': + return webnotes.conn.sql("select server_code, client_script from `tabDocType` where name=%s", d.name, as_dict = 1)[0] + + # renumber the indexes + def renum(self): + extra = self.get_extra_fields() + self.clear_section_breaks() + self.add_section_breaks_and_renum() + self.fix_extra_fields(extra) + + # get fields not in the incoming list (to preserve order) + def get_extra_fields(self): + prev_field, prev_field_key, extra = '', '', [] + + # get new fields and labels + fieldnames = [d.get('fieldname') for d in self.in_doclist] + labels = [d.get('label') for d in self.in_doclist] + + # check if all existing are present + for f in webnotes.conn.sql("select fieldname, label, idx from tabDocField where parent=%s and fieldtype not in ('Section Break', 'Column Break', 'HTML') order by idx asc", self.doc.name): + if f[0] and not f[0] in fieldnames: + extra.append([f[0], f[1], prev_field, prev_field_key]) + elif f[1] and not f[1] in labels: + extra.append([f[0], f[1], prev_field, prev_field_key]) + + prev_field, prev_field_key = f[0] or f[1], f[0] and 'fieldname' or 'label' + + return extra + + # clear section breaks + def clear_section_breaks(self): + webnotes.conn.sql("delete from tabDocField where fieldtype in ('Section Break', 'Column Break', 'HTML') and parent=%s and ifnull(options,'')!='Custom'", self.doc.name) + + # add section breaks + def add_section_breaks_and_renum(self): + for d in self.in_doclist: + if d.get('parentfield')=='fields': + if d.get('fieldtype') in ('Section Break', 'Column Break', 'HTML'): + tmp = Document(fielddata = d) + tmp.fieldname = '' + tmp.name = None + tmp.save(1, ignore_fields = 1, check_links=0) + else: + webnotes.conn.sql("update tabDocField set idx=%s where %s=%s and parent=%s" % \ + ('%s', d.get('fieldname') and 'fieldname' or 'label', '%s', '%s'), (d.get('idx'), d.get('fieldname') or d.get('label'), self.doc.name)) + + + # adjust the extra fields + def fix_extra_fields(self, extra): + # push fields down at new idx + for e in extra: + # get idx of the prev to extra field + idx = 0 + if e[2]: + idx = webnotes.conn.sql("select idx from tabDocField where %s=%s and parent=%s" % (e[3], '%s', '%s'), (e[2], self.doc.name)) + idx = idx and idx[0][0] or 0 + + if idx: + webnotes.conn.sql("update tabDocField set idx=idx+1 where idx>%s and parent=%s", (idx, self.doc.name)) + webnotes.conn.sql("update tabDocField set idx=%s where %s=%s and parent=%s" % \ + ('%s', e[0] and 'fieldname' or 'label', '%s', '%s'), (idx+1, e[0] or e[1], self.doc.name)) + + + + +# +# update module def +# +class UpdateModuleDef(UpdateDocumentMerge): + def __init__(self, in_doclist): + UpdateDocumentMerge.__init__(self, in_doclist) + self.to_update_doctype = ['Module Def', 'Module Def Item'] + + def get_id(self, d): + return webnotes.conn.sql("select name from `tabModule Def Item` where doc_type=%s and doc_name=%s and display_name=%s and parent=%s", (d.doc_type, d.doc_name, d.display_name, d.parent)) + + def to_update(self, d): + if d.doctype=='Module Def Item': return 1 + + def get_orignal_values(self, d): + if d.doctype=='Module Def Item': + return {'name': self.get_id(d)[0][0]} + if d.doctype=='Module Def': + return webnotes.conn.sql("select module_seq, disabled, is_hidden from `tabModule Def` where name=%s", d.name, as_dict = 1)[0] + + + +# +# update module def +# +class UpdateDocTypeMapper(UpdateDocumentMerge): + def __init__(self, in_doclist): + UpdateDocumentMerge.__init__(self, in_doclist) + self.to_update_doctype = ['Field Mapper Detail', 'Table Mapper Detail'] + + def get_id(self, d): + if d.doctype=='Field Mapper Detail': + return webnotes.conn.sql("select name from `tabField Mapper Detail` where from_field=%s and to_field=%s and match_id=%s and parent=%s", (d.from_field, d.to_field, d.match_id, d.parent)) + elif d.doctype=='Table Mapper Detail': + return webnotes.conn.sql("select name from `tabTable Mapper Detail` where from_table=%s and to_table = %s and match_id=%s and parent=%s", (d.from_table, d.to_table, d.match_id, d.parent)) + + def get_orignal_values(self, d): + if d.doctype in ['Field Mapper Detail', 'Table Mapper Detail']: + return {'name': self.get_id(d)[0][0]} + + diff --git a/cgi-bin/webnotes/utils/webservice.py b/cgi-bin/webnotes/utils/webservice.py new file mode 100644 index 0000000000..c3bb8ceba9 --- /dev/null +++ b/cgi-bin/webnotes/utils/webservice.py @@ -0,0 +1,111 @@ +import webnotes +import webnotes.utils + +class FrameworkServer: + """ + Connect to a remote server via HTTP (webservice). + + * `remote_host` is the the address of the remote server + * `path` is the path of the Framework (excluding index.cgi) + """ + def __init__(self, remote_host, path, user='', password='', account='', cookies=None, opts=None, https = 0): + # validate + if not (remote_host and path): + raise Exception, "Server address and path necessary" + + if not ((user and password) or (cookies)): + raise Exception, "Either cookies or user/password necessary" + + self.remote_host = remote_host + self.path = path + self.cookies = cookies or {} + self.webservice_method='POST' + self.account = account + self.account_id = None + self.https = https + self.conn = None + + # login + if not cookies: + args = { 'usr': user, 'pwd': password, 'acx': account } + + if opts: + args.update(opts) + + res = self.http_get_response('login', args) + + ret = res.read() + try: + ret = eval(ret) + except Exception, e: + webnotes.msgprint(ret) + raise Exception, e + + if ret.get('message') and ret.get('message')!='Logged In': + raise Exception, ret.get('message') + + if ret.get('exc'): + raise Exception, ret.get('exc') + + self._extract_cookies(res) + + self.account_id = self.cookies.get('account_id') + self.sid = self.cookies.get('sid') + + self.login_response = res + self.login_return = ret + + # ----------------------------------------------------------------------------------------- + + def http_get_response(self, method, args): + """ + Run a method on the remote server, with the given arguments + """ + # get response from remote server + + import urllib, urllib2, os + + args['cmd'] = method + if self.path.startswith('/'): self.path = self.path[1:] + + protocol = self.https and 'https://' or 'http://' + req = urllib2.Request(protocol + os.path.join(self.remote_host, self.path, 'index.cgi'), urllib.urlencode(args)) + for key in self.cookies: + req.add_header('cookie', '; '.join(['%s=%s' % (key, self.cookies[key]) for key in self.cookies])) + return urllib2.urlopen(req) + + # ----------------------------------------------------------------------------------------- + + def _extract_cookies(self, res): + import Cookie + cookies = Cookie.SimpleCookie() + cookies.load(res.headers.get('set-cookie')) + for c in cookies.values(): + self.cookies[c.key] = c.value.rstrip(',') + + # ----------------------------------------------------------------------------------------- + + + def runserverobj(self, doctype, docname, method, arg=''): + """ + Returns the response of a remote method called on a system object specified by `doctype` and `docname` + """ + res = self.http_get_response('runserverobj', args = { + 'doctype':doctype + ,'docname':docname + ,'method':method + ,'arg':arg + }) + ret = eval(res.read()) + if ret.get('exc'): + raise Exception, ret.get('exc') + return ret + + # ----------------------------------------------------------------------------------------- + + def run_method(self, method, args): + res = self.http_get_response(method, args) + ret = eval(res.read()) + if ret.get('exc'): + raise Exception, ret.get('exc') + return ret diff --git a/cgi-bin/webnotes/widgets/__init__.py b/cgi-bin/webnotes/widgets/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/webnotes/widgets/auto_master.py b/cgi-bin/webnotes/widgets/auto_master.py new file mode 100644 index 0000000000..003b1153e9 --- /dev/null +++ b/cgi-bin/webnotes/widgets/auto_master.py @@ -0,0 +1,53 @@ +# auto masters +# _ + fieldname is the table +# 'value' is the column name, pkey + +import webnotes + +# create masters for a doctype +def create_auto_masters(dt): + fl = webnotes.conn.sql("select fieldname from tabDocField where fieldtype='Data' and options='Suggest' and parent=%s", dt) + for f in fl: + make_auto_master(f[0]) + +# create master table +def make_auto_master(fieldname): + try: + webnotes.conn.sql("select `value` from `__%s` limit 1" % fieldname) + except Exception, e: + if e.args[0]==1146: + webnotes.conn.commit() + webnotes.conn.sql("create table `__%s` (`value` varchar(220), primary key (`value`))" % fieldname) + webnotes.conn.begin() + +# get auto master fields +def get_master_fields(dt): + if not webnotes.session['data'].get('auto_masters'): + webnotes.session['data']['auto_masters'] = {} + + if webnotes.session['data']['auto_masters'].get(dt, None)==None: + fl = webnotes.conn.sql("select fieldname from tabDocField where fieldtype='Data' and options='Suggest' and parent=%s", dt) + webnotes.session['data']['auto_masters'][dt] = fl + + return webnotes.session['data']['auto_masters'][dt] + + +# update value +def update_auto_masters(doc): + if not doc.doctype: + return + + fl = get_master_fields(doc.doctype) + + # save masters in session cache + for f in fl: + if doc.fields.get(f[0]): + add_to_master(f[0], doc.fields.get(f[0])) + +# add to master +def add_to_master(fieldname, value): + try: + webnotes.conn.sql("insert into `__%s` (`value`) values (%s)" % (fieldname,'%s'), value) + except Exception, e: + # primary key + pass \ No newline at end of file diff --git a/cgi-bin/webnotes/widgets/event.py b/cgi-bin/webnotes/widgets/event.py new file mode 100644 index 0000000000..8bb999d04b --- /dev/null +++ b/cgi-bin/webnotes/widgets/event.py @@ -0,0 +1,48 @@ +# Event +# ------------- + +def get_cal_events(m_st, m_end): + import webnotes + import webnotes.model.doc + + sql = webnotes.conn.sql + + # load owned events + res1 = sql("select name from `tabEvent` WHERE ifnull(event_date,'2000-01-01') between '%s' and '%s' and owner = '%s' and event_type != 'Public' and event_type != 'Cancel'" % (m_st, m_end, webnotes.user.name)) + + # load individual events + res2 = sql("select t1.name from `tabEvent` t1, `tabEvent User` t2 where ifnull(t1.event_date,'2000-01-01') between '%s' and '%s' and t2.person = '%s' and t1.name = t2.parent and t1.event_type != 'Cancel'" % (m_st, m_end, webnotes.user.name)) + + # load role events + roles = webnotes.user.get_roles() + myroles = ['t2.role = "%s"' % r for r in roles] + myroles = '(' + (' OR '.join(myroles)) + ')' + res3 = sql("select t1.name from `tabEvent` t1, `tabEvent Role` t2 where ifnull(t1.event_date,'2000-01-01') between '%s' and '%s' and t1.name = t2.parent and t1.event_type != 'Cancel' and %s" % (m_st, m_end, myroles)) + + # load public events + res4 = sql("select name from `tabEvent` where ifnull(event_date,'2000-01-01') between '%s' and '%s' and event_type='Public'" % (m_st, m_end)) + + doclist, rl = [], [] + for r in res1 + res2 + res3 + res4: + if not r in rl: + doclist += webnotes.model.doc.get('Event', r[0]) + rl.append(r) + + return doclist + + +# Load Month Events +# ----------------- + +def load_month_events(): + import webnotes + from webnotes.utils import cint + + form = webnotes.form + + mm = form.getvalue('month') + yy = form.getvalue('year') + m_st = str(yy) + '-%.2i' % cint(mm) + '-01' + m_end = str(yy) + '-%.2i' % cint(mm) + '-31' + + webnotes.response['docs'] = get_cal_events(m_st, m_end) \ No newline at end of file diff --git a/cgi-bin/webnotes/widgets/follow.py b/cgi-bin/webnotes/widgets/follow.py new file mode 100644 index 0000000000..2766d742c6 --- /dev/null +++ b/cgi-bin/webnotes/widgets/follow.py @@ -0,0 +1,134 @@ +""" +Server side methods for the follower pattern (Follow button used in forms) +""" + +import webnotes +form = webnotes.form_dict + +# +# Follow +# +def follow(dt=None, dn=None, user=None, verbose=0): + "Add as follower to a particular record. If no parameteres, then take from the http request (form)" + + if not dt: + dt, dn, user = form.get('dt'), form.get('dn'), form.get('user') + verbose = 1 + + if not user: return + + if not is_follower(dt, dn, user): + make_follower(dt, dn, user, verbose) + else: + if verbose: webnotes.msgprint("%s is already a follower!" % user) + + return load_followers(dt, dn) + +def make_follower(dt, dn, user, verbose): + "Add the user as a follower" + if has_permission(dt, user): + from webnotes.model.doc import Document + d = Document('Follower') + d.doc_type = dt + d.doc_name = dn + d.owner = user + d.save(1) + else: + if verbose: webnotes.msgprint('%s does not have sufficient permission to follow' % user) + +def has_permission(dt, user): + "Check to see if the user has permission to follow" + + return webnotes.conn.sql("select name from tabDocPerm where parent=%s and ifnull(`read`,0)=1 and role in ('%s') limit 1" \ + % ('%s', ("', '".join(webnotes.user.get_roles()))), dt) + +def is_follower(dt, dn, user): + "returns true if given user is a follower" + + return webnotes.conn.sql(""" + select name from tabFollower + where ifnull(doc_type,'')=%s + and ifnull(doc_name,'')=%s + and owner=%s""", (dt, dn, user)) +# +# Unfollow +# +def unfollow(dt=None, dn=None, user=None): + "Unfollow a particular record. If no parameteres, then take from the http request (form)" + + if not dt: + dt, dn, user = form.get('dt'), form.get('dn'), form.get('user') + + webnotes.conn.sql("delete from tabFollower where doc_name=%s and doc_type=%s and owner=%s", (dn, dt, user)) + + return load_followers(dt, dn) + +# +# Load followers +# +def load_followers(dt=None, dn=None): + "returns list of followers (Full Names) for a particular object" + + if not dt: dt, dn = form.get('dt'), form.get('dn') + + try: + return [t[0] for t in webnotes.conn.sql(""" + SELECT IFNULL(CONCAT(t1.first_name, if(t1.first_name IS NULL, '', ' '), t1.last_name), t1.name) + FROM tabProfile t1, tabFollower t2 WHERE t2.doc_type=%s AND t2.doc_name=%s + AND t1.name = t2.owner""", (dt, dn))] + + except Exception, e: + if e.args[0] in (1146, 1054): + setup() + return [] + else: + raise e + +# +# Email followers +# +def email_followers(dt, dn, msg_html=None, msg_text=None): + "Send an email to all followers of this object" + pass + +# +# Update feed +# +def on_docsave(doc): + "Add the owner and all linked Profiles as followers" + follow(doc.doctype, doc.name, doc.owner) + for p in get_profile_fields(doc.doctype): + follow(doc.doctype, doc.name, doc.fields.get(p)) + + update_followers(doc = doc) + +# +# update the follower record timestamp and subject +# +def update_followers(dt=None, dn=None, subject=None, update_by=None, doc=None): + "Updates the timestamp and subject in follower table (for feed generation)" + from webnotes.utils import now + webnotes.conn.sql("update tabFollower set modified=%s, subject=%s, modified_by=%s where doc_type=%s and doc_name=%s", \ + (now(), + subject or doc.fields.get('subject'), \ + update_by or webnotes.session['user'],\ + dt or doc.doctype, + dn or doc.name)) + +# +# get type of "Profile" fields +# +def get_profile_fields(dt): + "returns a list of all profile link fields from the doctype" + return [f[0] for f in \ + webnotes.conn.sql("select fieldname from tabDocField where parent=%s and fieldtype='Link' and options='Profile'", dt)] + +# +# setup - make followers table +# +def setup(): + "Make table for followers - if missing" + webnotes.conn.commit() + from webnotes.modules.module_manager import reload_doc + reload_doc('core', 'doctype', 'follower') + webnotes.conn.begin() diff --git a/cgi-bin/webnotes/widgets/form.py b/cgi-bin/webnotes/widgets/form.py new file mode 100644 index 0000000000..9a25608608 --- /dev/null +++ b/cgi-bin/webnotes/widgets/form.py @@ -0,0 +1,490 @@ +""" +Server side handler for "Form" events +""" + +import webnotes +import webnotes.model.doc +import webnotes.model.meta +from webnotes.model.triggers import fire_event + +def getdoc(): + """ + Loads a doclist for a given document. This method is called directly from the client. + Requries "doctype", "docname" as form variables. If "from_archive" is set, it will get from archive. + Will also call the "onload" method on the document. + """ + + import webnotes + from webnotes.utils import cint + + form = webnotes.form_dict + doctype, docname = form.get('doctype'), form.get('name') + prefix = cint(form.get('from_archive')) and 'arc' or 'tab' + + if not (doctype and docname): + raise Exception, 'doctype and name required!' + + doclist = [] + # single + doclist = load_single_doc(doctype, docname, (form.get('user') or webnotes.session['user']), prefix) + + # load doctype along with the doc + if form.get('getdoctype'): + import webnotes.model.doctype + doclist += webnotes.model.doctype.get(doctype) + + # tag as archived + if prefix == 'arc': + doclist[0].__archived=1 + + webnotes.response['docs'] = doclist + +#=========================================================================================== + +def get_comments(doctype=None, docname=None, limit=5): + nc, cl = 0, [] + + if not doctype: + doctype, docname, limit = webnotes.form_dict.get('dt'), webnotes.form_dict.get('dn'), webnotes.form_dict.get('limit') + + try: + nc = int(webnotes.conn.sql("select count(*) from `tabComment Widget Record` where comment_doctype=%s and comment_docname=%s", (doctype, docname))[0][0]) + if nc: + cl = webnotes.conn.sql("select comment, ifnull(comment_by_fullname, comment_by) AS 'comment_by_fullname', creation from `tabComment Widget Record` where comment_doctype=%s and comment_docname=%s order by creation desc limit %s" % ('%s','%s',limit), (doctype, docname), as_dict=1) + + except Exception, e: + if e.args[0]==1146: + # no table + make_comment_table() + else: + raise e + + webnotes.response['n_comments'], webnotes.response['comment_list'] = nc, cl + +# +# make comment table +# +def make_comment_table(): + "Make table for comments - if missing via import module" + webnotes.conn.commit() + from webnotes.modules import reload_doc + reload_doc('core', 'doctype', 'comment_widget_record') + webnotes.conn.begin() + +#=========================================================================================== + +def add_comment(): + import time + args = webnotes.form_dict + + if args.get('comment'): + from webnotes.model.doc import Document + from webnotes.utils import nowdate + + cmt = Document('Comment Widget Record') + for arg in ['comment', 'comment_by', 'comment_by_fullname', 'comment_doctype', 'comment_docname']: + cmt.fields[arg] = args[arg] + cmt.comment_date = nowdate() + cmt.comment_time = time.strftime('%H:%M') + cmt.save(1) + +#=========================================================================================== + +def remove_comment(): + args = webnotes.form_dict + webnotes.conn.sql("delete from `tabComment Widget Record` where name=%s",args.get('id')) + + try: + get_obj('Feed Control').upate_comment_in_feed(args['dt'], args['dn']) + except: pass + +#=========================================================================================== + +def getdoctype(): + # load parent doctype too + import webnotes.model.doctype + + form, doclist = webnotes.form, [] + + dt = form.getvalue('doctype') + with_parent = form.getvalue('with_parent') + + # with parent (called from report builder) + if with_parent: + parent_dt = webnotes.model.meta.get_parent_dt(dt) + if parent_dt: + doclist = webnotes.model.doctype.get(parent_dt) + webnotes.response['parent_dt'] = parent_dt + + if not doclist: + doclist = webnotes.model.doctype.get(dt) + + # if single, send the record too + if doclist[0].issingle: + doclist += webnotes.model.doc.get(dt) + + # load search criteria for reports (all) + doclist += webnotes.model.meta.get_search_criteria(dt) + + + webnotes.response['docs'] = doclist + +#=========================================================================================== + +def load_single_doc(dt, dn, user, prefix): + import webnotes.model.code + + if not dn: dn = dt + dl = webnotes.model.doc.get(dt, dn, prefix=prefix) + + # archive, done + if prefix=='arc': + return dl + + try: + so, r = webnotes.model.code.get_server_obj(dl[0], dl), None + if hasattr(so, 'onload'): + r = webnotes.model.code.run_server_obj(so, 'onload') + if hasattr(so, 'custom_onload'): + r = webnotes.model.code.run_server_obj(so, 'custom_onload') + if r: + webnotes.msgprint(r) + except Exception, e: + webnotes.errprint(webnotes.utils.getTraceback()) + webnotes.msgprint('Error in script while loading') + raise e + + if dl and not dn.startswith('_'): + webnotes.user.update_recent(dt, dn) + + # load search criteria ---- if doctype + if dt=='DocType': + dl += webnotes.model.meta.get_search_criteria(dt) + + return dl + +# Check Guest Access +#=========================================================================================== +def check_guest_access(doc): + if webnotes.session['user']=='Guest' and not webnotes.conn.sql("select name from tabDocPerm where role='Guest' and parent=%s and ifnull(`read`,0)=1", doc.doctype): + webnotes.msgprint("Guest not allowed to call this object") + raise Exception + +# Runserverobj - run server calls from form +#=========================================================================================== + +def runserverobj(): + import webnotes.model.code + import webnotes.model.doclist + from webnotes.utils import cint + + form = webnotes.form + + + method = form.getvalue('method') + doclist, clientlist = [], [] + arg = form.getvalue('arg') + dt = form.getvalue('doctype') + dn = form.getvalue('docname') + + if dt: # not called from a doctype (from a page) + if not dn: dn = dt # single + so = webnotes.model.code.get_obj(dt, dn) + + else: + clientlist = webnotes.model.doclist.expand(form.getvalue('docs')) + + # find main doc + for d in clientlist: + if cint(d.get('docstatus')) != 2 and not d.get('parent'): + main_doc = webnotes.model.doc.Document(fielddata = d) + + # find child docs + for d in clientlist: + doc = webnotes.model.doc.Document(fielddata = d) + if doc.fields.get('parent'): + doclist.append(doc) + + so = webnotes.model.code.get_server_obj(main_doc, doclist) + + # check integrity + if not check_integrity(so.doc): + return + + check_guest_access(so.doc) + + if so: + r = webnotes.model.code.run_server_obj(so, method, arg) + doclist = so.doclist # reference back [in case of null] + if r: + try: + if r['doclist']: + clientlist += r['doclist'] + except: + pass + + #build output as csv + if cint(webnotes.form.getvalue('as_csv')): + make_csv_output(r, so.doc.doctype) + else: + webnotes.response['message'] = r + + if clientlist: + doclist.append(main_doc) + webnotes.response['docs'] = doclist + +def make_csv_output(res, dt): + import webnotes + from webnotes.utils import getCSVelement + + txt = [] + if type(res)==list: + for r in res: + txt.append(','.join([getCSVelement(i) for i in r])) + + txt = '\n'.join(txt) + + else: + txt = 'Output was not in list format\n' + r + + webnotes.response['result'] = txt + webnotes.response['type'] = 'csv' + webnotes.response['doctype'] = dt.replace(' ','') + + +# Document Save +#=========================================================================================== + +def _get_doclist(clientlist): + # converts doc dictionaries into Document objects + + from webnotes.model.doc import Document + form = webnotes.form + + midx = 0 + for i in range(len(clientlist)): + if clientlist[i]['name'] == form.getvalue('docname'): + main_doc = Document(fielddata = clientlist[i]) + midx = i + else: + clientlist[i] = Document(fielddata = clientlist[i]) + + del clientlist[midx] + return main_doc, clientlist + +def _do_action(doc, doclist, so, method_name, docstatus=0): + + from webnotes.model.code import run_server_obj + set = webnotes.conn.set + + if so and hasattr(so, method_name): + errmethod = method_name + run_server_obj(so, method_name) + if hasattr(so, 'custom_'+method_name): + run_server_obj(so, 'custom_'+method_name) + errmethod = '' + + # fire triggers observers (if any) + fire_event(doc, method_name) + + # set docstatus for all children records + if docstatus: + for d in [doc] + doclist: + if int(d.docstatus or 0) != 2: + set(d, 'docstatus', docstatus) + +def check_integrity(doc): + import webnotes + + if (not webnotes.model.meta.is_single(doc.doctype)) and (not doc.fields.get('__islocal')): + tmp = webnotes.conn.sql('SELECT modified FROM `tab%s` WHERE name="%s" for update' % (doc.doctype, doc.name)) + if tmp and str(tmp[0][0]) != str(doc.modified): + webnotes.msgprint('Document has been modified after you have opened it. To maintain the integrity of the data, you will not be able to save your changes. Please refresh this document. [%s/%s]' % (tmp[0][0], doc.modified)) + return 0 + + return 1 + +#=========================================================================================== + +def savedocs(): + import webnotes.model.doclist + + from webnotes.model.code import get_server_obj + from webnotes.model.code import run_server_obj + import webnotes.utils + from webnotes.widgets.auto_master import update_auto_masters + + from webnotes.utils import cint + + sql = webnotes.conn.sql + form = webnotes.form + + # action + action = form.getvalue('action') + + # get docs + doc, doclist = _get_doclist(webnotes.model.doclist.expand(form.getvalue('docs'))) + + # get server object + server_obj = get_server_obj(doc, doclist) + + # check integrity + if not check_integrity(doc): + return + + if not doc.check_perm(verbose=1): + webnotes.msgprint("Not enough permission to save %s" % doc.doctype) + return + + # validate links + ret = webnotes.model.doclist.validate_links_doclist([doc] + doclist) + if ret: + webnotes.msgprint("[Link Validation] Could not find the following values: %s. Please correct and resave. Document Not Saved." % ret) + return + + # saving & post-saving + try: + # validate befor saving and submitting + if action in ('Save', 'Submit') and server_obj: + if hasattr(server_obj, 'validate'): + t = run_server_obj(server_obj, 'validate') + if hasattr(server_obj, 'custom_validate'): + t = run_server_obj(server_obj, 'custom_validate') + + # set owner and modified times + is_new = cint(doc.fields.get('__islocal')) + if is_new and not doc.owner: + doc.owner = form.getvalue('user') + + doc.modified, doc.modified_by = webnotes.utils.now(), webnotes.session['user'] + + # save main doc + try: + t = doc.save(is_new) + update_auto_masters(doc) + except NameError, e: + webnotes.msgprint('%s "%s" already exists' % (doc.doctype, doc.name)) + if webnotes.conn.sql("select docstatus from `tab%s` where name=%s" % (doc.doctype, '%s'), doc.name)[0][0]==2: + webnotes.msgprint('[%s "%s" has been cancelled]' % (doc.doctype, doc.name)) + webnotes.errprint(webnotes.utils.getTraceback()) + raise e + + # save child docs + for d in doclist: + deleted, local = d.fields.get('__deleted',0), d.fields.get('__islocal',0) + + if cint(local) and cint(deleted): + pass + elif d.fields.has_key('parent'): + if d.parent and (not d.parent.startswith('old_parent:')): + d.parent = doc.name # rename if reqd + d.parenttype = doc.doctype + d.modified, d.modified_by = webnotes.utils.now(), webnotes.session['user'] + d.save(new = cint(local)) + update_auto_masters(d) + + # on_update + if action in ('Save','Submit') and server_obj: + if hasattr(server_obj, 'on_update'): + t = run_server_obj(server_obj, 'on_update') + if t: webnotes.msgprint(t) + + if hasattr(server_obj, 'custom_on_update'): + t = run_server_obj(server_obj, 'custom_on_update') + if t: webnotes.msgprint(t) + + fire_event(doc, 'on_update') + + # on_submit + if action == 'Submit': + _do_action(doc, doclist, server_obj, 'on_submit', 1) + + # for allow_on_submit type + if action == 'Update': + _do_action(doc, doclist, server_obj, 'on_update_after_submit', 0) + + # on_cancel + if action == 'Cancel': + _do_action(doc, doclist, server_obj, 'on_cancel', 2) + + # update recent documents + webnotes.user.update_recent(doc.doctype, doc.name) + + # send updated docs + webnotes.response['saved'] = '1' + webnotes.response['main_doc_name'] = doc.name + webnotes.response['docname'] = doc.name + webnotes.response['docs'] = [doc] + doclist + + except Exception, e: + webnotes.msgprint('Did not save') + webnotes.errprint(webnotes.utils.getTraceback()) + raise e + + +# Print Format +#=========================================================================================== +def _get_print_format(match): + name = match.group('name') + return webnotes.model.meta.get_print_format_html(name) + +def get_print_format(): + import re + import webnotes + + html = webnotes.model.meta.get_print_format_html(webnotes.form.getvalue('name')) + + p = re.compile('\$import\( (?P [^)]*) \)', re.VERBOSE) + out_html = '' + if html: + out_html = p.sub(_get_print_format, html) + + webnotes.response['message'] = out_html + +# remove attachment +#=========================================================================================== + +def remove_attach(): + import webnotes + import webnotes.utils.file_manager + + fid = webnotes.form.getvalue('fid') + webnotes.utils.file_manager.delete_file(fid, verbose=1) + +# Get Fields - Counterpart to $c_get_fields +#=========================================================================================== +def get_fields(): + import webnotes + r = {} + args = { + 'select':webnotes.form.getvalue('select') + ,'from':webnotes.form.getvalue('from') + ,'where':webnotes.form.getvalue('where') + } + ret = webnotes.conn.sql("select %(select)s from `%(from)s` where %(where)s limit 1" % args) + if ret: + fl, i = webnotes.form.getvalue('fields').split(','), 0 + for f in fl: + r[f], i = ret[0][i], i+1 + webnotes.response['message']=r + +# validate link +#=========================================================================================== +def validate_link(): + import webnotes + import webnotes.utils + + value, options, fetch = webnotes.form.getvalue('value'), webnotes.form.getvalue('options'), webnotes.form.getvalue('fetch') + + # no options, don't validate + if not options or options=='null' or options=='undefined': + webnotes.response['message'] = 'Ok' + return + + if webnotes.conn.sql("select name from `tab%s` where name=%s" % (options, '%s'), value): + + # get fetch values + if fetch: + webnotes.response['fetch_values'] = [webnotes.utils.parse_val(c) for c in webnotes.conn.sql("select %s from `tab%s` where name=%s" % (fetch, options, '%s'), value)[0]] + + webnotes.response['message'] = 'Ok' diff --git a/cgi-bin/webnotes/widgets/menus.py b/cgi-bin/webnotes/widgets/menus.py new file mode 100644 index 0000000000..1b414027ed --- /dev/null +++ b/cgi-bin/webnotes/widgets/menus.py @@ -0,0 +1,181 @@ +""" +Server side methods called from DocBrowser +""" + +import webnotes +from webnotes.utils import cint, cstr + +sql = webnotes.conn.sql + +def get_menu_items(): + """ + Returns a list of items to show in `Options` of the Web Notes Toolbar + List contains Pages and Single DocTypes + """ + import webnotes.utils + + rl = webnotes.user.get_roles() + [webnotes.session['user']] + role_options = ["role = '"+r+"'" for r in rl] + + sql = webnotes.conn.sql + menuitems = [] + + # pages + pages = sql("select distinct parent from `tabPage Role` where docstatus!=2 and (%s)" % (' OR '.join(role_options))) + + for p in pages: + tmp = sql("select icon, parent_node, menu_index, show_in_menu from tabPage where name = '%s'" % p[0]) + if tmp and tmp[0][3]: + menuitems.append(['Page', p[0] or '', tmp[0][1] or '', tmp[0][0] or '', webnotes.utils.cint(tmp[0][2])]) + + # singles + tmp = sql("select smallicon, parent_node, menu_index, name from tabDocType where (show_in_menu = 1 and show_in_menu is not null)") + singles = {} + for t in tmp: singles[t[3]] = t + + for p in webnotes.user.can_read: + tmp = singles.get(p, None) + if tmp: menuitems.append([p, p, tmp[1] or '', tmp[0] or '', int(tmp[2] or 0)]) + + return menuitems + +# -------------------------------------------------------------- +def has_result(): + return sql("select name from `tab%s` limit 1" % webnotes.form_dict.get('dt')) and 'Yes' or 'No' + +# -------------------------------------------------------------- + +def is_submittable(dt): + return sql("select name from tabDocPerm where parent=%s and ifnull(submit,0)=1 and docstatus<1 limit 1", dt) + +# -------------------------------------------------------------- + +def can_cancel(dt): + return sql('select name from tabDocPerm where parent="%s" and ifnull(cancel,0)=1 and docstatus<1 and role in ("%s") limit 1' % (dt, '", "'.join(webnotes.user.get_roles()))) + +# -------------------------------------------------------------- +def get_dt_trend(dt): + ret = {} + for r in sql("select datediff(now(),modified), count(*) from `tab%s` where datediff(now(),modified) between 0 and 30 group by date(modified)" % dt): + ret[cint(r[0])] = cint(r[1]) + return ret + +# -------------------------------------------------------------- + +def get_columns(out, sf, fl, dt, tag_fields): + if not fl: + fl = sf + + # subject + subject = webnotes.conn.get_value('DocType', dt, 'subject') + if subject: + out['subject'] = subject + + # get fields from subject + import re + fl = re.findall('\%\( (?P [^)]*) \)s', subject, re.VERBOSE) + + if tag_fields: + fl += [t.strip() for t in tag_fields.split(',')] + + res = [] + for f in tuple(set(fl)): + if f: + res += [[c or '' for c in r] for r in sql("select fieldname, label, fieldtype, options from tabDocField where parent='%s' and fieldname='%s'" % (dt, f))] + + + return res + + +# -------------------------------------------------------------- +# NOTE: THIS SHOULD BE CACHED IN DOCTYPE CACHE +# -------------------------------------------------------------- + +def get_dt_details(): + """ + Returns details called by DocBrowser this includes: + the filters, columns, subject and tag_fields + also if the doctype is of type "submittable" + """ + fl = eval(webnotes.form_dict.get('fl')) + dt = webnotes.form_dict.get('dt') + tag_fields, description = webnotes.conn.get_value('DocType', dt, ['tag_fields', 'description']) + + submittable = is_submittable(dt) and 1 or 0 + + out = { + 'submittable':(is_submittable(dt) and 1 or 0), + 'can_cancel':(can_cancel(dt) and 1 or 0) + } + + # filters + # ------- + + sf = sql("select search_fields from tabDocType where name=%s", dt)[0][0] or '' + + # get fields from in_filter (if not in search_fields) + if not sf.strip(): + res = sql("select fieldname, label, fieldtype, options from tabDocField where parent=%s and `in_filter` = 1 and ifnull(fieldname,'') != ''", dt) + sf = [s[0] for s in res] + else: + sf = [s.strip() for s in sf.split(',')] + res = sql("select fieldname, label, fieldtype, options from tabDocField where parent='%s' and fieldname in (%s)" % (dt, '"'+'","'.join(sf)+'"')) + + # select "link" options + res = [[c or '' for c in r] for r in res] + for r in res: + if r[2]=='Select' and r[3] and r[3].startswith('link:'): + tdt = r[3][5:] + ol = sql("select name from `tab%s` where docstatus!=2 order by name asc" % tdt) + r[3] = "\n".join([''] + [o[0] for o in ol]) + + if not res: + out['filters'] = [['name', 'ID', 'Data', '']] + else: + out['filters'] = [['name', 'ID', 'Data', '']] + res + + # columns + # ------- + res = get_columns(out, sf, fl, dt, tag_fields) + + from webnotes.widgets.tags import check_user_tags + check_user_tags(dt) + + out['columns'] = [['name', 'ID', 'Link', dt], ['modified', 'Modified', 'Data', ''], ['_user_tags', 'Tags', 'Data', '']] + res + out['tag_fields'] = tag_fields + out['description'] = description + + return out + + +# -------------------------------------------------------------- + +def get_trend(): + return {'trend': get_dt_trend(webnotes.form_dict.get('dt'))} + + + + + +# +# delete and archive in docbrowser +# +def delete_items(): + il = eval(webnotes.form_dict.get('items')) + from webnotes.model import delete_doc + from webnotes.model.code import get_obj + + for d in il: + dt_obj = get_obj(d[0], d[1]) + if hasattr(dt_obj, 'on_trash'): + dt_obj.on_trash() + delete_doc(d[0], d[1]) + +# -------------------------------------------------------------- + +def archive_items(): + il = eval(webnotes.form_dict.get('items')) + + from webnotes.utils.archive import archive_doc + for d in il: + archive_doc(d[0], d[1], webnotes.form_dict.get('action')=='Restore' and 1 or 0) diff --git a/cgi-bin/webnotes/widgets/page.py b/cgi-bin/webnotes/widgets/page.py new file mode 100644 index 0000000000..09fd79649f --- /dev/null +++ b/cgi-bin/webnotes/widgets/page.py @@ -0,0 +1,87 @@ +import webnotes +import webnotes.model.doc +import webnotes.model.code + +conn = webnotes.conn + +class Page: + """ + A page class helps in loading a Page in the system. On loading + + * Page will import Client Script from other pages where specified by `$import(page_name)` + * Execute dynamic HTML if the `content` starts with `#python` + """ + def __init__(self, name): + self.name = name + + def load(self): + """ + Returns :term:`doclist` of the `Page` + """ + from webnotes.modules import compress + from webnotes.model.code import get_code + + doclist = webnotes.model.doc.get('Page', self.name) + doc = doclist[0] + + doc.fields['__script'] = compress.get_page_js(doc) + doc.script = None + + template = '%(content)s' + # load code from template + if doc.template: + template = get_code(webnotes.conn.get_value('Page Template', doc.template, 'module'), 'Page Template', doc.template, 'html', fieldname='template') + + doc.content = get_code(doc.module, 'page', doc.name, 'html') or doc.content + + # execute content + if doc.content and doc.content.startswith('#!python'): + doc.__content = template % {'content': webnotes.model.code.execute(doc.content).get('content')} + else: + doc.__content = template % {'content': doc.content or ''} + + # local stylesheet + css = get_code(doc.module, 'page', doc.name, 'css') + if css: doc.style = css + + # add stylesheet + if doc.stylesheet: + doclist += self.load_stylesheet(doc.stylesheet) + + return doclist + + def load_stylesheet(self, stylesheet): + import webnotes + # load stylesheet + loaded = eval(webnotes.form_dict.get('stylesheets') or '[]') + if not stylesheet in loaded: + import webnotes.model.doc + from webnotes.model.code import get_code + + # doclist + sslist = webnotes.model.doc.get('Stylesheet', stylesheet) + + # stylesheet from file + css = get_code(sslist[0].module, 'Stylesheet', stylesheet, 'css') + + if css: sslist[0].stylesheet = css + + return sslist + else: + return [] + +def get(name): + """ + Return the :term:`doclist` of the `Page` specified by `name` + """ + return Page(name).load() + +def getpage(): + """ + Load the page from `webnotes.form` and send it via `webnotes.response` + """ + doclist = get(webnotes.form.getvalue('name')) + + # send + webnotes.response['docs'] = doclist + diff --git a/cgi-bin/webnotes/widgets/page_body.py b/cgi-bin/webnotes/widgets/page_body.py new file mode 100644 index 0000000000..f221511209 --- /dev/null +++ b/cgi-bin/webnotes/widgets/page_body.py @@ -0,0 +1,240 @@ +#: HTML Template of index.cgi +index_template = ''' + + + + + + + + + + + %(title)s + + + + + + + + + %(import_form)s + + + %(add_in_head)s + + + + + +
    + +
    + + +
    + + +
    + %(content)s +
    + +
    + +%(add_in_body)s + + +''' + +redirect_template = ''' + + +%s + + +Redirecting... + +''' + +page_properties = { + 'add_in_head':'', + 'add_in_body':'', + 'keywords':'', + 'site_description':'', + 'title':'', + 'content':'', + 'startup_data':'{}', + 'import_form':'' +} + + +import webnotes + +# remove 'id' attributes so they don't conflict +# --------------------------------------------- +def replace_id(match): + #webnotes.msgprint(match.group('name')) + return '' + +def scrub_ids(content): + import re + + p = re.compile('id=\"(?P [^\"]*)\"', re.VERBOSE) + content = p.sub(replace_id, content) + + p = re.compile('id=\'(?P [^\']*)\'', re.VERBOSE) + content = p.sub(replace_id, content) + + return content + +# +# load the page content and meta tags +# +def get_page_content(page): + """ + Gets the HTML content from `static_content` or `content` property of a `Page` + """ + from webnotes.model.code import get_code + from webnotes.model.doc import Document + global page_properties + + if not page: return + if '/' in page: page = page.split('/')[0] + if page=='Form': return + + try: + doc = Document('Page', page) + + load_page_metatags(doc) + + template = '%(content)s' + # content + if doc.template: + template = get_code(webnotes.conn.get_value('Page Template', doc.template, 'module'), 'Page Template', doc.template, 'html', fieldname='template') + + page_properties['content'] = get_code(doc.module, 'page', doc.name, 'html', fieldname='content') + + # dynamic (scripted) content + if page_properties['content'] and page_properties['content'].startswith('#!python'): + page_properties.update(webnotes.model.code.execute(page_properties['content'])) + + page_properties['content'] = scrub_ids(template % {'content':page_properties['content']}) + except: + pass + +# +# load metatags +# +def load_page_metatags(doc): + global page_properties + + try: + import startup + except: + startup = '' + + # page meta-tags + page_properties['title'] = doc.page_title or doc.name + page_properties['keywords'] = doc.keywords or webnotes.conn.get_value('Control Panel',None,'keywords') or '' + page_properties['site_description'] = doc.site_description or webnotes.conn.get_value('Control Panel',None,'site_description') or '' + page_properties['add_in_head'] = getattr(startup, 'add_in_head', '') + page_properties['add_in_body'] = getattr(startup, 'add_in_body', '') + +# +# load the form as page (deprecated) +# +def get_doc_content(dt, dn): + """ + Gets the HTML content of a document record by using the overridden or standard :method: `doclist.to_html` + """ + import webnotes.model.code + + if dt in webnotes.user.get_read_list(): + # generate HTML + do = webnotes.model.code.get_obj(dt, dn, with_children = 1) + if hasattr(do, 'to_html'): + return dn, do.to_html() + else: + import webnotes.model.doclist + return dn, webnotes.model.doclist.to_html(do.doclist) + else: + return 'Forbidden - 404', '

    Forbidden - 404

    ' + +# find the page to load as static +# ------------------------------- + +def load_properties(): + import webnotes.widgets.page + import urllib + + page_url = webnotes.form_dict.get('_escaped_fragment_', webnotes.form_dict.get('page', '')) + + if page_url: + if page_url.startswith('Page/'): + page_url = page_url[5:] + page_url = ['Page', urllib.unquote(page_url)] + else: + page_url = ['Page', webnotes.user.get_home_page()] + + # load content + # ----------------- + get_page_content(page_url[1]) + +# generate the page +# ----------------- +def load_default_properties(): + if not page_properites['keywords']: + page_properites['keywords'] = webnotes.conn.get_value('Control Panel',None,'keywords') or '' + if not page_properites['site_description']: + page_properites['site_description'] = webnotes.conn.get_value('Control Panel',None,'site_description') or '' + +# generate the page +# ----------------- +def get(): + """ + returns the full rendered index.cgi + Gets `keywords` and `site_description` from the `Control Panel` + """ + import webnotes + no_startup = webnotes.form.getvalue('no_startup') or None + + global index_template, redirect_template + import webnotes.session_cache + try: + import json + except: # python 2.4 + import simplejson as json + + page = webnotes.form_dict.get('page', '') + # sid in public display + # --------------------- + if webnotes.form_dict.get('sid'): + return redirect_template % ('Redirecting...', ('index.cgi' + (page and ('?page='+page) or ''))) + + if '%(content)s' in index_template: + load_properties() + + # load the session data + # --------------------- + try: + sd = webnotes.session_cache.get() + except: + import webnotes.utils + sd = {'exc':webnotes.utils.getTraceback()} + + # add debug messages + + sd['server_messages'] = '\n--------------\n'.join(webnotes.message_log) + + page_properties['startup_data'] = no_startup and '{}' or json.dumps(sd) + + # no form api required for guests + if webnotes.session['user']=='Guest': + page_properties['import_form'] = '' + + index_template = index_template % page_properties + + return index_template diff --git a/cgi-bin/webnotes/widgets/query_builder.py b/cgi-bin/webnotes/widgets/query_builder.py new file mode 100644 index 0000000000..cf272434e3 --- /dev/null +++ b/cgi-bin/webnotes/widgets/query_builder.py @@ -0,0 +1,333 @@ +import webnotes + +form = webnotes.form +session = webnotes.session +sql = webnotes.conn.sql +out = webnotes.response + +from webnotes.utils import cint + +def get_search_criteria_list(dt): + sc_list = sql("select criteria_name, doc_type from `tabSearch Criteria` where doc_type = '%s' or parent_doc_type = '%s'" % (dt, dt)) + return [list(s) for s in sc_list] + +def load_report_list(): + webnotes.response['rep_list'] = get_search_criteria_list(form.getvalue('dt')) + + +# Get, scrub metadata +# ==================================================================== + +def get_sql_tables(q): + if q.find('WHERE') != -1: + tl = q.split('FROM')[1].split('WHERE')[0].split(',') + elif q.find('GROUP BY') != -1: + tl = q.split('FROM')[1].split('GROUP BY')[0].split(',') + else: + tl = q.split('FROM')[1].split('ORDER BY')[0].split(',') + return [t.strip().strip('`')[3:] for t in tl] + + +def get_parent_dt(dt): + pdt = '' + if sql('select name from `tabDocType` where istable=1 and name="%s"' % dt): + res = sql('select parent from `tabDocField` where fieldtype="Table" and options="%s"' % dt) + if res: pdt = res[0][0] + return pdt + +def get_sql_meta(tl): + std_columns = { + 'owner':('Owner', '', '', '100'), + 'creation':('Created on', 'Date', '', '100'), + 'modified':('Last modified on', 'Date', '', '100'), + 'modified_by':('Modified By', '', '', '100') + } + + meta = {} + + for dt in tl: + meta[dt] = std_columns.copy() + + # for table doctype, the ID is the parent id + pdt = get_parent_dt(dt) + if pdt: + meta[dt]['parent'] = ('ID', 'Link', pdt, '200') + + # get the field properties from DocField + res = sql("select fieldname, label, fieldtype, options, width from tabDocField where parent='%s'" % dt) + for r in res: + if r[0]: + meta[dt][r[0]] = (r[1], r[2], r[3], r[4]); + + # name + meta[dt]['name'] = ('ID', 'Link', dt, '200') + + return meta + +# Additional conditions to fulfill match permission rules +# ==================================================================== + +def getmatchcondition(dt, ud, ur): + res = sql("SELECT `role`, `match` FROM tabDocPerm WHERE parent = '%s' AND (`read`=1) AND permlevel = 0" % dt) + cond = [] + for r in res: + if r[0] in ur: # role applicable to user + if r[1]: + defvalues = ud.get(r[1],['_NA']) + for d in defvalues: + cond.append('`tab%s`.`%s`="%s"' % (dt, r[1], d)) + else: # nomatch i.e. full read rights + return '' + + return ' OR '.join(cond) + +def add_match_conditions(q, tl, ur, ud): + sl = [] + for dt in tl: + s = getmatchcondition(dt, ud, ur) + if s: + sl.append(s) + + # insert the conditions + if sl: + condition_st = q.find('WHERE')!=-1 and ' AND ' or ' WHERE ' + + condition_end = q.find('ORDER BY')!=-1 and 'ORDER BY' or 'LIMIT' + condition_end = q.find('GROUP BY')!=-1 and 'GROUP BY' or condition_end + + if q.find('ORDER BY')!=-1 or q.find('LIMIT')!=-1 or q.find('GROUP BY')!=-1: # if query continues beyond conditions + q = q.split(condition_end) + q = q[0] + condition_st + '(' + ' OR '.join(sl) + ') ' + condition_end + q[1] + else: + q = q + condition_st + '(' + ' OR '.join(sl) + ')' + + return q + +# execute server-side script from Search Criteria +# ==================================================================== + +def exec_report(code, res, colnames=[], colwidths=[], coltypes=[], coloptions=[], filter_values={}, query='', from_export=0): + col_idx, i, out, style, header_html, footer_html, page_template = {}, 0, None, [], '', '', '' + for c in colnames: + col_idx[c] = i + i+=1 + + # load globals (api) + from webnotes import * + from webnotes.utils import * + from webnotes.model.doc import * + from webnotes.model.doclist import getlist + from webnotes.model.db_schema import updatedb + from webnotes.model.code import get_obj + + set = webnotes.conn.set + sql = webnotes.conn.sql + get_value = webnotes.conn.get_value + convert_to_lists = webnotes.conn.convert_to_lists + NEWLINE = '\n' + + exec str(code) + + if out!=None: + res = out + + return res, style, header_html, footer_html, page_template + +# ==================================================================== + +def guess_type(m): + """ + Returns fieldtype depending on the MySQLdb Description + """ + import MySQLdb + if m in MySQLdb.NUMBER: + return 'Currency' + elif m in MySQLdb.DATE: + return 'Date' + else: + return 'Data' + +def build_description_simple(): + colnames, coltypes, coloptions, colwidths = [], [], [], [] + + for m in webnotes.conn.get_description(): + colnames.append(m[0]) + coltypes.append(guess_type[m[0]]) + coloptions.append('') + colwidths.append('100') + + return colnames, coltypes, coloptions, colwidths + +# ==================================================================== + +def build_description_standard(meta, tl): + + desc = webnotes.conn.get_description() + + colnames, coltypes, coloptions, colwidths = [], [], [], [] + + # merged metadata - used if we are unable to + # get both the table name and field name from + # the description - in case of joins + merged_meta = {} + for d in meta: + merged_meta.update(meta[d]) + + for f in desc: + fn, dt = f[0], '' + if '.' in fn: + dt, fn = fn.split('.') + + if (not dt) and merged_meta.get(fn): + # no "AS" given, find type from merged description + + desc = merged_meta[fn] + colnames.append(desc[0] or fn) + coltypes.append(desc[1] or '') + coloptions.append(desc[2] or '') + colwidths.append(desc[3] or '100') + + elif meta.get(dt,{}).has_key(fn): + # type specified for a multi-table join + # usually from Report Builder + + desc = meta[dt][fn] + colnames.append(desc[0] or fn) + coltypes.append(desc[1] or '') + coloptions.append(desc[2] or '') + colwidths.append(desc[3] or '100') + + else: + # nothing found + # guess + + colnames.append(fn) + coltypes.append(guess_type(f[1])) + coloptions.append('') + colwidths.append('100') + + return colnames, coltypes, coloptions, colwidths + +# Entry Point - Run the query +# ==================================================================== + +def runquery(q='', ret=0, from_export=0): + import webnotes.utils + + formatted = cint(form.getvalue('formatted')) + + # CASE A: Simple Query + # -------------------- + if form.getvalue('simple_query') or form.getvalue('is_simple'): + q = form.getvalue('simple_query') or form.getvalue('query') + if q.split()[0].lower() != 'select': + raise Exception, 'Query must be a SELECT' + + as_dict = cint(form.getvalue('as_dict')) + res = sql(q, as_dict = as_dict, as_list = not as_dict, formatted=formatted) + + # build colnames etc from metadata + colnames, coltypes, coloptions, colwidths = [], [], [], [] + + # CASE B: Standard Query + # ----------------------- + else: + if not q: q = form.getvalue('query') + + tl = get_sql_tables(q) + meta = get_sql_meta(tl) + + q = add_match_conditions(q, tl, webnotes.user.roles, webnotes.user.get_defaults()) + + # replace special variables + q = q.replace('__user', session['user']) + q = q.replace('__today', webnotes.utils.nowdate()) + + res = sql(q, as_list=1, formatted=formatted) + + colnames, coltypes, coloptions, colwidths = build_description_standard(meta, tl) + + # run server script + # ----------------- + style, header_html, footer_html, page_template = '', '', '', '' + if form.has_key('sc_id') and form.getvalue('sc_id'): + sc_id = form.getvalue('sc_id') + from webnotes.model.code import get_code + sc_details = webnotes.conn.sql("select module, standard, server_script from `tabSearch Criteria` where name=%s", sc_id)[0] + if sc_details[1]!='No': + code = get_code(sc_details[0], 'Search Criteria', sc_id, 'py') + else: + code = sc_details[2] + + if code: + filter_values = form.has_key('filter_values') and eval(form.getvalue('filter_values','')) or {} + res, style, header_html, footer_html, page_template = exec_report(code, res, colnames, colwidths, coltypes, coloptions, filter_values, q, from_export) + + out['colnames'] = colnames + out['coltypes'] = coltypes + out['coloptions'] = coloptions + out['colwidths'] = colwidths + out['header_html'] = header_html + out['footer_html'] = footer_html + out['page_template'] = page_template + + if style: + out['style'] = style + + # just the data - return + if ret==1: + return res + + out['values'] = res + + # return num of entries + qm = form.has_key('query_max') and form.getvalue('query_max') or '' + if qm and qm.strip(): + if qm.split()[0].lower() != 'select': + raise Exception, 'Query (Max) must be a SELECT' + if not form.has_key('simple_query'): + qm = add_match_conditions(qm, tl, webnotes.user.roles, webnotes.user.defaults) + + out['n_values'] = webnotes.utils.cint(sql(qm)[0][0]) + +# Export to CSV +# ==================================================================== + +def runquery_csv(): + from webnotes.utils import getCSVelement + + # run query + res = runquery(from_export = 1) + + q = form.getvalue('query') + + rep_name = form.getvalue('report_name') + if not form.has_key('simple_query'): + + # Report Name + if not rep_name: + rep_name = get_sql_tables(q)[0] + + if not rep_name: rep_name = 'DataExport' + + # Headings + heads = [] + for h in out['colnames']: + heads.append(getCSVelement(h)) + if form.has_key('colnames'): + for h in form.getvalue('colnames').split(','): + heads.append(getCSVelement(h)) + + # Output dataset + dset = [rep_name, ''] + if heads: + dset.append(','.join(heads)) + + # Data + for r in out['values']: + dset.append(','.join([getCSVelement(i) for i in r])) + + txt = '\n'.join(dset) + out['result'] = txt + out['type'] = 'csv' + out['doctype'] = rep_name diff --git a/cgi-bin/webnotes/widgets/search.py b/cgi-bin/webnotes/widgets/search.py new file mode 100644 index 0000000000..9d8da2b790 --- /dev/null +++ b/cgi-bin/webnotes/widgets/search.py @@ -0,0 +1,101 @@ +# Search +import webnotes + +# this is called when a new doctype is setup for search - to set the filters +def getsearchfields(): + + sf = webnotes.conn.sql("select search_fields from tabDocType where name=%s", webnotes.form.getvalue("doctype")) + sf = sf and sf[0][0] or '' + sf = [s.strip() for s in sf.split(',')] + if sf and sf[0]: + res = webnotes.conn.sql("select fieldname, label, fieldtype, options from tabDocField where parent='%s' and fieldname in (%s)" % (webnotes.form.getvalue("doctype","_NA"), '"'+'","'.join(sf)+'"')) + else: + res = [] + + res = [[c or '' for c in r] for r in res] + for r in res: + if r[2]=='Select' and r[3] and r[3].startswith('link:'): + dt = r[3][5:] + ol = webnotes.conn.sql("select name from `tab%s` where docstatus!=2 order by name asc" % dt) + r[3] = '\n'.join([''] + [o[0] for o in ol]) + + webnotes.response['searchfields'] = [['name', 'ID', 'Data', '']] + res + +def make_query(fields, dt, key, txt, start, length): + return """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` + DESC LIMIT %(start)s, %(len)s """ % { + 'fields': fields, + 'dt': dt, + 'key': key, + 'txt': txt + '%', + 'start': start, + 'len': length + } + +def get_std_fields_list(dt, key): + # get additional search fields + sflist = webnotes.conn.sql("select search_fields from tabDocType where name = '%s'" % dt) + sflist = sflist and sflist[0][0] and sflist[0][0].split(',') or [] + + sflist = ['name'] + sflist + if not key in sflist: + sflist = sflist + [key] + + return ['`tab%s`.`%s`' % (dt, f.strip()) for f in sflist] + +def build_for_autosuggest(res): + from webnotes.utils import cstr + + results = [] + for r in res: + info = '' + if len(r) > 1: + info = ','.join([cstr(t) for t in r[1:]]) + if len(info) > 30: + info = info[:30] + '...' + + results.append({'id':r[0], 'value':r[0], 'info':info}) + return results + +def scrub_custom_query(query, key, txt): + if '%(key)s' in query: + query = query.replace('%(key)s', key) + if '%s' in query: + query = query.replace('%s', ((txt or '') + '%')) + return query + +# this is called by the Link Field +def search_link(): + import webnotes.widgets.query_builder + + txt = webnotes.form.getvalue('txt') + dt = webnotes.form.getvalue('dt') + query = webnotes.form.getvalue('query') + + if query: + res = webnotes.conn.sql(scrub_custom_query(query, 'name', txt)) + else: + q = make_query(', '.join(get_std_fields_list(dt, 'name')), dt, 'name', txt, '0', '10') + res = webnotes.widgets.query_builder.runquery(q, ret=1) + + # make output + webnotes.response['results'] = build_for_autosuggest(res) + +# this is called by the search box +def search_widget(): + import webnotes.widgets.query_builder + + dt = webnotes.form.getvalue('doctype') + txt = webnotes.form.getvalue('txt') or '' + key = webnotes.form.getvalue('searchfield') or 'name' # key field + user_query = webnotes.form.getvalue('query') or '' + + if user_query: + query = scrub_custom_query(user_query, key, txt) + else: + query = make_query(', '.join(get_std_fields_list(dt, key)), dt, key, txt, webnotes.form.getvalue('start') or 0, webnotes.form.getvalue('page_len') or 50) + + webnotes.widgets.query_builder.runquery(query) diff --git a/cgi-bin/webnotes/widgets/tags.py b/cgi-bin/webnotes/widgets/tags.py new file mode 100644 index 0000000000..b08429e8e8 --- /dev/null +++ b/cgi-bin/webnotes/widgets/tags.py @@ -0,0 +1,256 @@ +""" +Server side functions for tagging. + +- Tags can be added to any record (doctype, name) in the system. +- Items are filtered by tags +- Top tags are shown in the sidebar (?) +- Tags are also identified by the tag_fields property of the DocType + +Discussion: + +Tags are shown in the docbrowser and ideally where-ever items are searched. +There should also be statistics available for tags (like top tags etc) + + +Design: + +- free tags (user_tags) are stored in __user_tags +- doctype tags are set in tag_fields property of the doctype +- top tags merges the tags from both the lists (only refreshes once an hour (max)) + +""" + + +def check_user_tags(dt): + "if the user does not have a tags column, then it creates one" + try: + webnotes.conn.sql("select `_user_tags` from `tab%s` limit 1" % dt) + except Exception, e: + if e.args[0] == 1054: + DocTags(dt).setup() + + +# +# Add a new tag +# +def add_tag(): + "adds a new tag to a record, and creates the Tag master" + + f = webnotes.form_dict + tag, color = f.get('tag'), f.get('color') + dt, dn = f.get('dt'), f.get('dn') + + DocTags(dt).add(dn, tag) + + return tag + +# +# remove tag +# +def remove_tag(): + "removes tag from the record" + f = webnotes.form_dict + tag, dt, dn = f.get('tag'), f.get('dt'), f.get('dn') + + DocTags(dt).remove(dn, tag) + + + +import webnotes +from webnotes.utils import cint, cstr, load_json + +class DocTags: + """Tags for a particular doctype""" + def __init__(self, dt): + self.dt = dt + + def get_tag_fields(self): + """returns tag_fields property""" + return webnotes.conn.get_value('DocType', self.dt, 'tag_fields') + + def get_tags(self, dn): + """returns tag for a particular item""" + return webnotes.conn.get_value(self.dt, dn, '_user_tags') or '' + + def create(self, tag): + try: + webnotes.conn.sql("insert into tabTag(name) values (%s) on duplicate key ignore", tag) + except Exception, e: + if e.args[0]==1147: + self.setup_tag_master() + self.create(tag) + + def add(self, dn, tag): + """add a new user tag""" + self.create(tag) + tl = self.get_tags(dn).split(',') + if not tag in tl: + tl.append(tag) + self.update(dn, tl) + TagCounter(self.dt).update(tag, 1) + + def remove(self, dn, tag): + """remove a user tag""" + tl = self.get_tags(dn).split(',') + self.update(dn, filter(lambda x:x!=tag, tl)) + TagCounter(self.dt).update(tag, -1) + + def update(self, dn, tl): + """updates the _user_tag column in the table""" + + tl = list(set(filter(lambda x: x, tl))) + + try: + webnotes.conn.sql("update `tab%s` set _user_tags=%s where name=%s" % \ + (self.dt,'%s','%s'), (',' + ','.join(tl), dn)) + except Exception, e: + if e.args[0]==1054: + self.setup() + self.update(dn, tl) + else: raise e + + def setup_tags(self): + """creates the tabTag table if not exists""" + webnotes.conn.commit() + from webnotes.modules.module_manager import reload_doc + reload_doc('core','doctype','tag') + webnotes.conn.begin() + + def setup(self): + """adds the _user_tags column if not exists""" + webnotes.conn.commit() + webnotes.conn.sql("alter table `tab%s` add column `_user_tags` varchar(180)" % self.dt) + webnotes.conn.begin() + + + + + + + + +class TagCounter: + """ + Tag Counter stores tag count per doctype in table _tag_cnt + """ + def __init__(self, doctype): + self.doctype = doctype + + # setup / update tag cnt + # keeps tags in _tag_cnt (doctype, tag, cnt) + # if doctype cnt does not exist + # creates it for the first time + def update(self, tag, diff): + "updates tag cnt for a doctype and tag" + cnt = webnotes.conn.sql("select cnt from `_tag_cnt` where doctype=%s and tag=%s", (self.doctype, tag)) + + if not cnt: + # first time? build a cnt and add + self.new_tag(tag, 1) + else: + webnotes.conn.sql("update `_tag_cnt` set cnt = ifnull(cnt,0) + (%s) where doctype=%s and tag=%s",\ + (diff, self.doctype, tag)) + + + def new_tag(self, tag, cnt=0, dt=None): + "Creates a new row for the tag and doctype" + webnotes.conn.sql("insert into `_tag_cnt`(doctype, tag, cnt) values (%s, %s, %s)", \ + (dt or self.doctype, tag, cnt)) + + def build(self, dt): + "Builds / rebuilds the counting" + webnotes.conn.sql("delete from _tag_cnt where doctype=%s", dt) + + # count + tags = {} + for ut in webnotes.conn.sql("select _user_tags from `tab%s`" % dt): + if ut[0]: + tag_list = ut[0].split(',') + for t in tag_list: + if t: + tags[t] = tags.get(t, 0) + 1 + + # insert + for t in tags: + self.new_tag(t, tags[t], dt) + + def load_top(self): + try: + return webnotes.conn.sql("select tag, cnt from `_tag_cnt` where doctype=%s and cnt>0 order by cnt desc limit 10", self.doctype, as_list = 1) + except Exception, e: + if e.args[0]==1146: + self.setup() + return self.load_top() + else: raise e + + def setup(self): + "creates the tag cnt table from the DocType" + webnotes.conn.commit() + webnotes.conn.sql(""" + create table `_tag_cnt` ( + doctype varchar(180), tag varchar(22), cnt int(10), + primary key (doctype, tag), index cnt(cnt)) ENGINE=InnoDB + """) + webnotes.conn.begin() + + # build all + for dt in webnotes.conn.sql("select name from tabDocType where ifnull(issingle,0)=0 and docstatus<2"): + try: + self.build(dt[0]) + except Exception, e: + if e.args[0]==1054: pass + else: raise e + + + + +def get_top_field_tags(dt): + tf = webnotes.conn.get_value('DocType', dt, 'tag_fields') + if not tf: return [] + + # restrict to only 2 fields + tf = tuple(set(tf.split(',')))[:2] + tl = [] + + for t in tf: + t = t.strip() + # disastrous query but lets try it! + tl += webnotes.conn.sql("""select `%s`, count(*), '%s' from `tab%s` + where docstatus!=2 + and ifnull(`%s`, '')!='' + group by `%s` + order by count(*) desc + limit 10""" % (t, t, dt, t, t), as_list=1) + + if tl: + tl.sort(lambda x, y: y[1]-x[1]) + + return tl[:10] + +# returns the top ranked 10 tags for the +# doctype. +# merges the top tags from fields and user tags +def get_top_tags(args=''): + "returns the top 10 tags for the doctype from fields (7) and users (3)" + tl = None + dt = webnotes.form_dict['doctype'] + + from webnotes.utils.cache import get_item + + # if not reload, try and load from cache + if not cint(webnotes.form_dict.get('refresh')): + tl = get_item('tags-' + dt).get() + + if tl: + return eval(tl) + else: + tl = TagCounter(dt).load_top() + get_top_field_tags(dt) + if tl: + tl.sort(lambda x, y: y[1]-x[1]) + tl = tl[:20] + + # set in cache and don't reload for an hour + get_item('tags-' + dt).set(tl, 60*60) + + return tl + diff --git a/cgi-bin/webnotes/widgets/todo.py b/cgi-bin/webnotes/widgets/todo.py new file mode 100644 index 0000000000..40a118cd97 --- /dev/null +++ b/cgi-bin/webnotes/widgets/todo.py @@ -0,0 +1,49 @@ +# ToDO and Reminder +# ----------------- + +def add_todo(user, date, priority, desc, ref_type, ref_name): + nlist = [] + if type(user)==list: + for i in user: + nlist.append(add_todo_item(i, date, priority, desc, ref_type, ref_name)) + return nlist + else: + return add_todo_item(user, date, priority, desc, ref_type, ref_name) + +def add_todo_item(user, date, priority, desc, ref_type, ref_name): + if not date: + date = nowdate() + + d = Document('ToDo Item') + d.owner = user + d.date = date + d.priority = priority + d.description = desc + d.reference_type = ref_type + d.reference_name = ref_name + d.save(1) + return d.name + +def remove_todo(name): + if type(name)==list: + for i in name: + sql("delete from `tabToDo Item` where name='%s'" % i) + else: + sql("delete from `tabToDo Item` where name='%s'" % name) + +def get_todo_list(): + c = getcursor() + try: + role_options = ["role = '"+r+"'" for r in roles] + role_options = role_options and ' OR ' + ' OR '.join(role_options) or '' + c.execute("select * from `tabToDo Item` where owner='%s' %s" % (session['user'], role_options)) + except: # deprecated + c.execute("select * from `tabToDo Item` where owner='%s'" % session['user']) + dataset = c.fetchall() + l = [] + for i in range(len(dataset)): + d = Document('ToDo Item') + d.loadfields(dataset, i, c.description) + l.append(d) + + return l \ No newline at end of file diff --git a/change_log.txt b/change_log.txt new file mode 100644 index 0000000000..45b039f665 --- /dev/null +++ b/change_log.txt @@ -0,0 +1,143 @@ +# Framework change log + +# TODO +# ------- + +- renaming on first save - change to observer style +- table border issue in FF +- defaults in single? + +# LOG +# -------- + +15-Feb-08: + +- Rechanged structure to make it cleaner / CMS Friendly +- to make cgi run from anywhere + +23-Feb-08 + +- to start a new server + + - Concept: every server must have a base account called 'accounts' + - All different accounts on the server are logged in 'accounts' + + - make accounts database + - set accounts details in defs.py + - execute setup.cgi + - make "Account" doctype in the first database + - ac_name, db_name, db_login + - Autoname- field:ac_name + + - make account "accounts" with related db_name + +5-March-08 + +- added __account in each server call to avoid multiple login account + - exceptions : login and initdata (refresh) +- added __modified in savedocs to match if document has not been saved in between + and is the current copy in the database +- added hide for tablefield +- updated get_status in field +- added remove child function +- added print functionality to datatable +- added msgprint and errprint +- added freeze and unfreezing + +11-March-08 + +- added ip address blocking + - add ip_address in Profile to block +- client side triggers using "cscript" property +- activate / deactivate field in table (no triggers) + +14-March-08 + +- app2: onload function passed to copy_doc +- app2: allow_on_submit now works in Cancel +- app2: IE7 main heading bug fixed - was happening due to click->hide calendar??? + - change: create calendar first time on show. +- changed messaging logic + - all msgprints will be printed + - r.message is now r.server_messages + +15-16-March-08 + +- created Report API + - see test report + + +17-March-08 + +- activation logic changed for new rows in grids, + - make_newrow is called from add_template if there is no docname +- changes in report for page breaks + +21-March-08 + +- added trigger on section break +- multiple columns on link +- no print until submitted +- docstatus of submitted and cancelled documents changed for child elements + +26-March-08 + +- complete drill down + - added feature to have function executed + - added feature to have custom result + + +10-Apr-08 + +- Amendment added to Frm / Permissions + +14-Apr-08 + +- Finder 2.0 + +6-May-08 + +- Included AutoSuggest + +19-Dec-08 + +PIL --- Installation + +1. Donwload + unzip +2. python setup.py -build_ext -i +3. python selftest.py +4. python setup.py install + +To install jpeg library.. Download jpeg-6b + +1. ./configure --enable-shared --enable-static +2. make +3. make install + +09-July-09 + +- to start a new server + + - set server_prefix in defs.py + - open python shell, + - import server + - server.import_db('Framework') + + - set appropriate details in defs.py + + +31-July-09 + +mysqldump('s2u019','../data/') +create_account('xx','s2u019.sql') + +18-Sep-09 + +matplotlib - numpy, + + +------- Updates in httpd.conf + +RewriteEngine On +RewriteRule ^/uploads/(.*)$ /cgi-bin/getfile.cgi?name=$1 +RewriteRule \.py - [F] \ No newline at end of file diff --git a/compress.py b/compress.py new file mode 100644 index 0000000000..0ea1b6c79e --- /dev/null +++ b/compress.py @@ -0,0 +1,424 @@ +in_files_main = [ + 'utils/rsh.compressed.js' + ,'globals.js' + ,'utils/datatype.js' + ,'utils/browser_detect.js' + ,'utils/datetime.js' + ,'utils/dom.js' + ,'utils/handler.js' + ,'utils/msgprint.js' + ,'utils/json.js' + ,'utils/printElement.js' + ,'wn/widgets/dialog.js' + ,'widgets/dialog.js' + ,'widgets/listing.js' + ,'wn/widgets/listing.js' + ,'widgets/tree.js' + ,'widgets/menu.js' + ,'widgets/layout.js' + ,'widgets/tabbedpage.js' + ,'webpage/page_header.js' + ,'widgets/autosuggest.js' + ,'widgets/select.js' + ,'widgets/tags.js' + ,'widgets/export_query.js' + ,'widgets/list_selector.js' + ,'widgets/form/fields.js' + ,'webpage/wntoolbar.js' + ,'webpage/history.js' + ,'webpage/search.js' + ,'webpage/spinner.js' + ,'webpage/freeze_page.js' + ,'webpage/error_console.js' + ,'webpage/about.js' + ,'webpage/loaders.js' + ,'webpage/uploader.js' + ,'webpage/page.js' + ,'webpage/docbrowser.js' + ,'wn/page_layout.js' + #,'wn/widgets/doc_column_view.js' + ,'wn/widgets/page_sidebar.js' + ,'wn/widgets/footer.js' + #,'wn/widgets/follow.js' + ,'model/local_data.js' + ,'model/doclist.js' + ,'webpage/body.js' + ,'app.js' + ,'widgets/calendar.js' + ] + +out_file_main = 'js/wnf.compressed.js' + +#------------------------------------------------- + +in_files_lite = [ + 'utils/rsh.compressed.js' + ,'globals.js' + ,'utils/datatype.js' + ,'utils/browser_detect.js' + ,'utils/datetime.js' + ,'utils/dom.js' + ,'utils/handler.js' + ,'utils/msgprint.js' + ,'utils/json.js' + ,'wn/widgets/dialog.js' + ,'widgets/dialog.js' + ,'widgets/listing.js' + ,'widgets/layout.js' + ,'widgets/tabbedpage.js' + ,'webpage/page_header.js' + ,'widgets/autosuggest.js' + ,'widgets/tags.js' + ,'widgets/form/fields.js' + ,'webpage/history.js' + ,'webpage/search.js' + ,'webpage/spinner.js' + ,'webpage/freeze_page.js' + ,'webpage/error_console.js' + ,'webpage/about.js' + ,'webpage/loaders.js' + ,'webpage/uploader.js' + ,'webpage/page.js' + ,'wn/widgets/page_sidebar.js' + ,'wn/widgets/follow.js' + ,'model/local_data.js' + ,'model/doclist.js' + ,'webpage/body.js' + ,'app.js' + ] + +out_file_lite = 'js/wnf-lite.compressed.js' + +#------------------------------------------------- + +in_files_form = [ + 'widgets/form/form_container.js' + ,'widgets/form/form_header.js' + ,'widgets/form/form.js' + ,'widgets/form/form_fields.js' + ,'widgets/form/grid.js' + ,'widgets/form/form_grid.js' + ,'widgets/form/print_format.js' + ,'widgets/form/email.js' + ,'widgets/form/clientscriptAPI.js' + ,'widgets/form/form_comments.js' + ,'wn/widgets/form/sidebar.js' + ,'wn/widgets/form/comments.js' + ,'wn/widgets/form/attachments.js' +] + +out_file_form = 'js/form.compressed.js'; + +in_files_report = [ + 'widgets/report_builder/bargraph.js' + ,'widgets/report_builder/report_builder.js' + ,'widgets/report_builder/datatable.js' + ,'widgets/report_builder/calculator.js' +] + +out_file_report = 'js/report.compressed.js' + +in_files_css = [ + 'css/body.css', + 'css/menus.css', + 'css/messages.css', + 'css/forms.css', + 'css/grid.css', + 'css/listing.css', + 'css/report.css', + 'css/calendar.css', + 'css/autosuggest.css', + 'css/dialog.css', + 'css/wntoolbar.css', + 'css/tabs.css', + 'css/jqplot.css', + 'css/bw-icons.css', + 'css/sidebar.css', + 'css/doc_column_view.css', +] + +out_file_css = 'css/default.css' + + + +#in_files_main += in_files_form + +import os, os.path, shutil + +# This code is original from jsmin by Douglas Crockford, it was translated to +# Python by Baruch Even. The original code had the following copyright and +# license. +# +# /* jsmin.c +# 2007-05-22 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# The Software shall be used for Good, not Evil. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# */ + +from StringIO import StringIO + +def jsmin(js): + ins = StringIO(js) + outs = StringIO() + JavascriptMinify().minify(ins, outs) + str = outs.getvalue() + if len(str) > 0 and str[0] == '\n': + str = str[1:] + return str + +def isAlphanum(c): + """return true if the character is a letter, digit, underscore, + dollar sign, or non-ASCII character. + """ + return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or + (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126)); + +class UnterminatedComment(Exception): + pass + +class UnterminatedStringLiteral(Exception): + pass + +class UnterminatedRegularExpression(Exception): + pass + +class JavascriptMinify(object): + + def _outA(self): + self.outstream.write(self.theA) + def _outB(self): + self.outstream.write(self.theB) + + def _get(self): + """return the next character from stdin. Watch out for lookahead. If + the character is a control character, translate it to a space or + linefeed. + """ + c = self.theLookahead + self.theLookahead = None + if c == None: + c = self.instream.read(1) + if c >= ' ' or c == '\n': + return c + if c == '': # EOF + return '\000' + if c == '\r': + return '\n' + return ' ' + + def _peek(self): + self.theLookahead = self._get() + return self.theLookahead + + def _next(self): + """get the next character, excluding comments. peek() is used to see + if an unescaped '/' is followed by a '/' or '*'. + """ + c = self._get() + if c == '/' and self.theA != '\\': + p = self._peek() + if p == '/': + c = self._get() + while c > '\n': + c = self._get() + return c + if p == '*': + c = self._get() + while 1: + c = self._get() + if c == '*': + if self._peek() == '/': + self._get() + return ' ' + if c == '\000': + raise UnterminatedComment() + + return c + + def _action(self, action): + """do something! What you do is determined by the argument: + 1 Output A. Copy B to A. Get the next B. + 2 Copy B to A. Get the next B. (Delete A). + 3 Get the next B. (Delete B). + action treats a string as a single character. Wow! + action recognizes a regular expression if it is preceded by ( or , or =. + """ + if action <= 1: + self._outA() + + if action <= 2: + self.theA = self.theB + if self.theA == "'" or self.theA == '"': + while 1: + self._outA() + self.theA = self._get() + if self.theA == self.theB: + break + if self.theA <= '\n': + raise UnterminatedStringLiteral() + if self.theA == '\\': + self._outA() + self.theA = self._get() + + + if action <= 3: + self.theB = self._next() + if self.theB == '/' and (self.theA == '(' or self.theA == ',' or + self.theA == '=' or self.theA == ':' or + self.theA == '[' or self.theA == '?' or + self.theA == '!' or self.theA == '&' or + self.theA == '|' or self.theA == ';' or + self.theA == '{' or self.theA == '}' or + self.theA == '\n'): + self._outA() + self._outB() + while 1: + self.theA = self._get() + if self.theA == '/': + break + elif self.theA == '\\': + self._outA() + self.theA = self._get() + elif self.theA <= '\n': + raise UnterminatedRegularExpression() + self._outA() + self.theB = self._next() + + + def _jsmin(self): + """Copy the input to the output, deleting the characters which are + insignificant to JavaScript. Comments will be removed. Tabs will be + replaced with spaces. Carriage returns will be replaced with linefeeds. + Most spaces and linefeeds will be removed. + """ + self.theA = '\n' + self._action(3) + + while self.theA != '\000': + if self.theA == ' ': + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + elif self.theA == '\n': + if self.theB in ['{', '[', '(', '+', '-']: + self._action(1) + elif self.theB == ' ': + self._action(3) + else: + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + else: + if self.theB == ' ': + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + elif self.theB == '\n': + if self.theA in ['}', ']', ')', '+', '-', '"', '\'']: + self._action(1) + else: + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + else: + self._action(1) + + def minify(self, instream, outstream): + self.instream = instream + self.outstream = outstream + self.theA = '\n' + self.theB = None + self.theLookahead = None + + self._jsmin() + self.instream.close() + +def combine_css(): + global out_file_css, in_files_css + + data = '' + for f in in_files_css: + fh = open(f, 'read') + data += fh.read() + '\n' + fh.close() + + out_file = open(out_file_css, 'w') + out_file.write(data) + out_file.close() + +def _compress(in_files, out_file, in_type='js', verbose=False, + temp_file='.temp'): + + import os + + temp = open(temp_file, 'w') + for f in in_files: + print f + ' | ' + str(int(os.path.getsize('js/'+f)/1024)) + 'k' + + fh = open('js/' + f) + data = fh.read() + '\n' + fh.close() + + temp.write(data) + + #print ' + %s' % f + temp.close() + + out = open(out_file, 'w') + + jsm = JavascriptMinify() + jsm.minify(open(temp_file,'r'), out) + + out.close() + + org_size = os.path.getsize(temp_file) + new_size = os.path.getsize(out_file) + + print '=> %s' % out_file + print 'Original: %.2f kB' % (org_size / 1024.0) + print 'Compressed: %.2f kB' % (new_size / 1024.0) + print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100) + print '' + + os.remove(temp_file) + + +if __name__=='__main__': + import sys + if sys.argv[1]=='main': + _compress(in_files_main, out_file_main) + elif sys.argv[1]=='lite': + _compress(in_files_lite, out_file_lite) + elif sys.argv[1]=='form': + _compress(in_files_form, out_file_form) + elif sys.argv[1]=='report': + _compress(in_files_report, out_file_report) + elif sys.argv[1]=='css': + combine_css() + else: + print 'parameter must be one of main, lite, css, form or report' + diff --git a/css/autosuggest.css b/css/autosuggest.css new file mode 100644 index 0000000000..991221b084 --- /dev/null +++ b/css/autosuggest.css @@ -0,0 +1,91 @@ +/* +================================================ +autosuggest, inquisitor style +================================================ +*/ + +div.autosuggest +{ + position: absolute; + margin-top: 3px; + border: 1px solid #222; +} + +div.autosuggest ul +{ + list-style: none; + margin: 0px; + padding: 2px; + overflow: hidden; + background-color: #FFF; +} + +div.autosuggest ul li +{ + color: #444; + padding: 0; + margin: 0; + text-align: left; +} + +div.autosuggest ul li a +{ + color: #444; + display: block; + text-decoration: none; + position: relative; + padding: 0; + width: 100%; +} +div.autosuggest ul li a:hover +{ + +} +div.autosuggest ul li.as_highlight a:hover +{ + background-color: #45A; + color: #FFF; +} + +div.autosuggest ul li a span +{ + display: block; + padding: 3px 6px; + color: #444; + border-bottom:1px solid #DDD; +} + +div.autosuggest ul li a span small +{ + display: block; + font-weight: normal; + color: #444; +} + +div.autosuggest ul li.as_highlight a span small +{ + color: #FFF; +} + +div.autosuggest ul li.as_highlight a span { + color: #FFF; +} + +div.autosuggest ul li.as_highlight a +{ + color: #FFF; + background-color: #45A; + cursor: pointer; +} + +div.autosuggest ul li.as_warning +{ + font-weight: bold; + text-align: center; +} + +div.autosuggest ul em +{ + font-style: normal; + font-weight: bold; +} diff --git a/css/body.css b/css/body.css new file mode 100644 index 0000000000..3fa852c5b6 --- /dev/null +++ b/css/body.css @@ -0,0 +1,108 @@ +html { + margin: 0px; + padding: 0px; +} + +body { + margin: 0px; + padding: 0px; + font-family: Arial, Helvetica, Sans; + font-size: 12px; + color: #000; +} + +input, select, button { font-size: 12px; font-family: Arial, Helvetica, Sans; } + +li { margin: 4px; } + +h1, h2, h3, h4, h5 { + font-family: Tahoma, Sans; + font-weight: normal; +} + +h1 { margin: 8px 0px; padding: 0px; font-size: 27px; } +h2 { margin: 8px 0px; padding: 0px; font-size: 23px; } +h3 { margin: 4px 0px; padding: 0px; font-size: 17px; } +h4 { margin: 2px 0px; padding: 0px; font-size: 13px; } +h5 { margin: 2px 0px; padding: 0px; font-size: 13px; } + +pre { margin: 0px; padding: 0px; } + +button { margin: 2px; margin-left: 0px; } + +select, input, textarea { + border: 1px solid #AAA; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + font-size: 13px + padding: 2px; +} + +textarea { font-family: arial, helvetica, sans serif; height: 120px; width: 90%; overflow-x: auto; font-size: 12px; } + +table { padding: 0px; border-collapse: 'collapse'} + +td { padding:0px; margin: 0px; vertical-align: top; } + +a:active { outline:none; } + +:focus { -moz-outline-style:none; } + +table.simpletable { border-collapse: collapse; margin-bottom: 10px;} +table.simpletable td {border: 1pt solid #000; vertical-align: top; padding: 2px; } + +div.fix_ff_cursor { overflow: auto; } + +/* --- Layout --- */ + +div.comment { color: #444; } + +div#body_div { + position: relative; + display: none; +} + +div.no_script { + display: none; +} + +div.loading_div { + position: absolute; + background-color: #FFFFCC; + z-index: 1999; + right: 5px; + width: 90px; + display: none; + text-align: center; + padding: 2px; + font-size: 12px; + border: 1px solid #FF4; +} + + +div#head_div { background-color: #FFF; } + +#head_banner { background-color: #FFF; } + +.link_type { + padding:2px; + color: #00b; + text-decoration: underline; + cursor: pointer; +} + +.link_type:hover { + color: #fff !important; + background-color: #07b; + text-decoration: none; +} + +div.std-footer { + margin: 13px 0px; + border-top: 1px solid #AAA; + padding: 13px; +} + +div.std-footer-item { + margin: 0px 13px 13px 0px; +} \ No newline at end of file diff --git a/css/bw-icons.css b/css/bw-icons.css new file mode 100644 index 0000000000..4f42de4488 --- /dev/null +++ b/css/bw-icons.css @@ -0,0 +1,250 @@ + +/** general icons **/ + +.wn-icon { background: url('../images/icons/icons.png'); width: 16px; height: 16px; cursor: pointer; } +.ic-2x2_grid { background-position: 0 0; } +.ic-3x3_grid { background-position: 0 -36px; } +.ic-3x3_grid_2 { background-position: 0 -72px; } +.ic-air_signal { background-position: 0 -108px; } +.ic-align_center { background-position: 0 -144px; } +.ic-align_just { background-position: 0 -180px; } +.ic-align_left { background-position: 0 -216px; } +.ic-align_right { background-position: 0 -252px; } +.ic-app_window { background-position: 0 -288px; } +.ic-arrow_bottom { background-position: 0 -324px; } +.ic-arrow_bottom_left { background-position: 0 -360px; } +.ic-arrow_bottom_right { background-position: 0 -396px; } +.ic-arrow_l { background-position: 0 -432px; } +.ic-arrow_left { background-position: 0 -468px; } +.ic-arrow_r { background-position: 0 -504px; } +.ic-arrow_right { background-position: 0 -540px; } +.ic-arrow_top { background-position: 0 -576px; } +.ic-arrow_top_left { background-position: 0 -612px; } +.ic-arrow_top_right { background-position: 0 -648px; } +.ic-arrow_two_head { background-position: 0 -684px; } +.ic-arrow_two_head_2 { background-position: 0 -720px; } +.ic-attention { background-position: 0 -756px; } +.ic-battery { background-position: 0 -792px; } +.ic-bell { background-position: 0 -828px; } +.ic-book { background-position: 0 -864px; } +.ic-bookmark_1 { background-position: 0 -900px; } +.ic-bookmark_2 { background-position: 0 -936px; } +.ic-box { background-position: 0 -972px; } +.ic-br_down { background-position: 0 -1008px; } +.ic-br_next { background-position: 0 -1044px; } +.ic-br_prev { background-position: 0 -1080px; } +.ic-br_up { background-position: 0 -1116px; } +.ic-brackets { background-position: 0 -1152px; } +.ic-browser { background-position: 0 -1188px; } +.ic-brush { background-position: 0 -1224px; } +.ic-bug { background-position: 0 -1260px; } +.ic-burst { background-position: 0 -1296px; } +.ic-calc { background-position: 0 -1332px; } +.ic-calendar_1 { background-position: 0 -1368px; } +.ic-calendar_2 { background-position: 0 -1404px; } +.ic-cancel { background-position: 0 -1440px; } +.ic-case { background-position: 0 -1476px; } +.ic-cc { background-position: 0 -1512px; } +.ic-cert { background-position: 0 -1548px; } +.ic-chart_bar { background-position: 0 -1584px; } +.ic-chart_line { background-position: 0 -1620px; } +.ic-chart_line_2 { background-position: 0 -1656px; } +.ic-chart_pie { background-position: 0 -1692px; } +.ic-checkbox_checked { background-position: 0 -1728px; } +.ic-checkbox_unchecked { background-position: 0 -1764px; } +.ic-checkmark { background-position: 0 -1800px; } +.ic-clip { background-position: 0 -1836px; } +.ic-clipboard_copy { background-position: 0 -1872px; } +.ic-clipboard_cut { background-position: 0 -1908px; } +.ic-clipboard_past { background-position: 0 -1944px; } +.ic-clock { background-position: -36px 0; } +.ic-cloud { background-position: -36px -36px; } +.ic-cloud_rain { background-position: -36px -72px; } +.ic-cog { background-position: -36px -108px; } +.ic-comp { background-position: -36px -144px; } +.ic-compass { background-position: -36px -180px; } +.ic-contact_card { background-position: -36px -216px; } +.ic-cube { background-position: -36px -252px; } +.ic-cur_bp { background-position: -36px -288px; } +.ic-cur_dollar { background-position: -36px -324px; } +.ic-cur_euro { background-position: -36px -360px; } +.ic-cur_yen { background-position: -36px -396px; } +.ic-cursor_H_split { background-position: -36px -432px; } +.ic-cursor_V_split { background-position: -36px -468px; } +.ic-cursor_arrow { background-position: -36px -504px; } +.ic-cursor_drag_arrow { background-position: -36px -540px; } +.ic-cursor_drag_arrow_2 { background-position: -36px -576px; } +.ic-cursor_drag_hand { background-position: -36px -612px; } +.ic-cursor_hand { background-position: -36px -648px; } +.ic-db { background-position: -36px -684px; } +.ic-delete { background-position: -36px -720px; } +.ic-doc_delete { background-position: -36px -756px; } +.ic-doc_edit { background-position: -36px -792px; } +.ic-doc_empty { background-position: -36px -828px; } +.ic-doc_export { background-position: -36px -864px; } +.ic-doc_import { background-position: -36px -900px; } +.ic-doc_lines { background-position: -36px -936px; } +.ic-doc_lines_stright { background-position: -36px -972px; } +.ic-doc_minus { background-position: -36px -1008px; } +.ic-doc_new { background-position: -36px -1044px; } +.ic-doc_plus { background-position: -36px -1080px; } +.ic-document { background-position: -36px -1116px; } +.ic-download { background-position: -36px -1152px; } +.ic-emotion_sad { background-position: -36px -1188px; } +.ic-emotion_smile { background-position: -36px -1224px; } +.ic-expand { background-position: -36px -1260px; } +.ic-eye { background-position: -36px -1296px; } +.ic-eye_inv { background-position: -36px -1332px; } +.ic-facebook { background-position: -36px -1368px; } +.ic-filter { background-position: -36px -1404px; } +.ic-fire { background-position: -36px -1440px; } +.ic-flag { background-position: -36px -1476px; } +.ic-folder { background-position: -36px -1512px; } +.ic-folder_arrow { background-position: -36px -1548px; } +.ic-folder_delete { background-position: -36px -1584px; } +.ic-folder_minus { background-position: -36px -1620px; } +.ic-folder_open { background-position: -36px -1656px; } +.ic-folder_plus { background-position: -36px -1692px; } +.ic-font_bold { background-position: -36px -1728px; } +.ic-font_italic { background-position: -36px -1764px; } +.ic-font_size { background-position: -36px -1800px; } +.ic-font_strokethrough { background-position: -36px -1836px; } +.ic-font_underline { background-position: -36px -1872px; } +.ic-game_pad { background-position: -36px -1908px; } +.ic-globe_1 { background-position: -36px -1944px; } +.ic-globe_2 { background-position: -72px 0; } +.ic-globe_3 { background-position: -72px -36px; } +.ic-google { background-position: -72px -72px; } +.ic-hand_1 { background-position: -72px -108px; } +.ic-hand_2 { background-position: -72px -144px; } +.ic-hand_contra { background-position: -72px -180px; } +.ic-hand_pro { background-position: -72px -216px; } +.ic-headphones { background-position: -72px -252px; } +.ic-heart { background-position: -72px -288px; } +.ic-heart_empty { background-position: -72px -324px; } +.ic-home { background-position: -72px -360px; } +.ic-image_text { background-position: -72px -396px; } +.ic-inbox { background-position: -72px -432px; } +.ic-indent_decrease { background-position: -72px -468px; } +.ic-indent_increase { background-position: -72px -504px; } +.ic-info { background-position: -72px -540px; } +.ic-iphone { background-position: -72px -576px; } +.ic-key { background-position: -72px -612px; } +.ic-layers_1 { background-position: -72px -648px; } +.ic-layers_2 { background-position: -72px -684px; } +.ic-lightbulb { background-position: -72px -720px; } +.ic-lighting { background-position: -72px -756px; } +.ic-link { background-position: -72px -792px; } +.ic-list_bullets { background-position: -72px -828px; } +.ic-list_num { background-position: -72px -864px; } +.ic-magic_wand { background-position: -72px -900px; } +.ic-mail { background-position: -72px -936px; } +.ic-mail_2 { background-position: -72px -972px; } +.ic-mic { background-position: -72px -1008px; } +.ic-monitor { background-position: -72px -1044px; } +.ic-movie { background-position: -72px -1080px; } +.ic-music { background-position: -72px -1116px; } +.ic-net_comp { background-position: -72px -1152px; } +.ic-network { background-position: -72px -1188px; } +.ic-notepad { background-position: -72px -1224px; } +.ic-notepad_2 { background-position: -72px -1260px; } +.ic-on-off { background-position: -72px -1296px; } +.ic-openid { background-position: -72px -1332px; } +.ic-padlock_closed { background-position: -72px -1368px; } +.ic-padlock_open { background-position: -72px -1404px; } +.ic-page_layout { background-position: -72px -1440px; } +.ic-paragraph { background-position: -72px -1476px; } +.ic-pencil { background-position: -72px -1512px; } +.ic-phone { background-position: -72px -1548px; } +.ic-phone_1 { background-position: -72px -1584px; } +.ic-phone_2 { background-position: -72px -1620px; } +.ic-phone_touch { background-position: -72px -1656px; } +.ic-photo { background-position: -72px -1692px; } +.ic-picture { background-position: -72px -1728px; } +.ic-pin { background-position: -72px -1764px; } +.ic-pin_2 { background-position: -72px -1800px; } +.ic-pin_map { background-position: -72px -1836px; } +.ic-pin_map_down { background-position: -72px -1872px; } +.ic-pin_map_left { background-position: -72px -1908px; } +.ic-pin_map_right { background-position: -72px -1944px; } +.ic-pin_map_top { background-position: -108px 0; } +.ic-pin_sq_down { background-position: -108px -36px; } +.ic-pin_sq_left { background-position: -108px -72px; } +.ic-pin_sq_right { background-position: -108px -108px; } +.ic-pin_sq_top { background-position: -108px -144px; } +.ic-playback_ff { background-position: -108px -180px; } +.ic-playback_next { background-position: -108px -216px; } +.ic-playback_pause { background-position: -108px -252px; } +.ic-playback_play { background-position: -108px -288px; } +.ic-playback_prev { background-position: -108px -324px; } +.ic-playback_rec { background-position: -108px -360px; } +.ic-playback_reload { background-position: -108px -396px; } +.ic-playback_rew { background-position: -108px -432px; } +.ic-playback_stop { background-position: -108px -468px; } +.ic-preso { background-position: -108px -504px; } +.ic-print { background-position: -108px -540px; } +.ic-question { background-position: -108px -576px; } +.ic-redo { background-position: -108px -612px; } +.ic-rnd_br_down { background-position: -108px -648px; } +.ic-rnd_br_first { background-position: -108px -684px; } +.ic-rnd_br_last { background-position: -108px -720px; } +.ic-rnd_br_next { background-position: -108px -756px; } +.ic-rnd_br_prev { background-position: -108px -792px; } +.ic-rnd_br_up { background-position: -108px -828px; } +.ic-round { background-position: -108px -864px; } +.ic-round_and_up { background-position: -108px -900px; } +.ic-round_arrow_left { background-position: -108px -936px; } +.ic-round_arrow_right { background-position: -108px -972px; } +.ic-round_checkmark { background-position: -108px -1008px; } +.ic-round_delete { background-position: -108px -1044px; } +.ic-round_minus { background-position: -108px -1080px; } +.ic-round_plus { background-position: -108px -1116px; } +.ic-rss { background-position: -108px -1152px; } +.ic-rss_sq { background-position: -108px -1188px; } +.ic-sand { background-position: -108px -1224px; } +.ic-sat_dish { background-position: -108px -1260px; } +.ic-save { background-position: -108px -1296px; } +.ic-server { background-position: -108px -1332px; } +.ic-share { background-position: -108px -1368px; } +.ic-shop_cart { background-position: -108px -1404px; } +.ic-sound_high { background-position: -108px -1440px; } +.ic-sound_low { background-position: -108px -1476px; } +.ic-sound_mute { background-position: -108px -1512px; } +.ic-spechbubble { background-position: -108px -1548px; } +.ic-spechbubble_2 { background-position: -108px -1584px; } +.ic-spechbubble_sq { background-position: -108px -1620px; } +.ic-spechbubble_sq_line { background-position: -108px -1656px; } +.ic-sq_br_down { background-position: -108px -1692px; } +.ic-sq_br_first { background-position: -108px -1728px; } +.ic-sq_br_last { background-position: -108px -1764px; } +.ic-sq_br_next { background-position: -108px -1800px; } +.ic-sq_br_prev { background-position: -108px -1836px; } +.ic-sq_br_up { background-position: -108px -1872px; } +.ic-sq_down { background-position: -108px -1908px; } +.ic-sq_minus { background-position: -108px -1944px; } +.ic-sq_next { background-position: -144px 0; } +.ic-sq_plus { background-position: -144px -36px; } +.ic-sq_prev { background-position: -144px -72px; } +.ic-sq_up { background-position: -144px -108px; } +.ic-square_shape { background-position: -144px -144px; } +.ic-star { background-position: -144px -180px; } +.ic-star_fav { background-position: -144px -216px; } +.ic-star_fav_empty { background-position: -144px -252px; } +.ic-sun { background-position: -144px -288px; } +.ic-tag { background-position: -144px -324px; } +.ic-tape { background-position: -144px -360px; } +.ic-target { background-position: -144px -396px; } +.ic-text_curstor { background-position: -144px -432px; } +.ic-text_letter_t { background-position: -144px -468px; } +.ic-top_right_expand { background-position: -144px -504px; } +.ic-trash { background-position: -144px -540px; } +.ic-twitter { background-position: -144px -576px; } +.ic-twitter_2 { background-position: -144px -612px; } +.ic-undo { background-position: -144px -648px; } +.ic-user { background-position: -144px -684px; } +.ic-users { background-position: -144px -720px; } +.ic-wrench { background-position: -144px -756px; } +.ic-wrench_plus { background-position: -144px -792px; } +.ic-wrench_plus_2 { background-position: -144px -828px; } +.ic-zoom { background-position: -144px -864px; } + diff --git a/css/calendar.css b/css/calendar.css new file mode 100644 index 0000000000..1637889cfd --- /dev/null +++ b/css/calendar.css @@ -0,0 +1,171 @@ +/**** CALENDAR ****/ + +.caldiv { + position:absolute; + visibility:hidden; + background-color:white; + width: 144px; + z-index: 301; /* always on top(?) */ +} + + + +div.cal_wrapper { } +div.cal_body { + margin: 16px; + background-color: #DDD; + position: relative; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.cal_head { + margin: 16px; + margin-bottom: 0px; +} +div.cal_head div { + font-size: 18px; + color: #666; + padding-top: 8px; +} + +div.cal_view_body { + margin: 16px; +} + +div.cal_view_body_plain { + margin: 16px; +} + +div.cal_month_head { +} + +div.cal_month_body { + border-top: 1px solid #888; +} + +.cal_month_headtable { + /*table-layout:fixed;*/ + width: 100%; +} + +.cal_month_name { + width: 100%; + color: #888; + font-size: 14px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +.cal_month_headtable tr td{ + font-size: 12px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +table.cal_month_table { + border-collapse: collapse; + /*table-layout:fixed;*/ + height: 100%; + width: 100%; +} + +table.cal_month_table td { + width: 14.29%; + height: 20%; + /*overflow:hidden;*/ + padding:0px; +} + +div.cal_month_date { + width:100%; + height:25%; + font-size: 10px; + overflow:hidden; + /*background-color: #EEF;*/ +} + +div.cal_month_date_holiday { + /*background-color: #FFF;*/ +} + +div.cal_month_unit { + width:100%; + height:75%; + overflow:hidden; + cursor:pointer; + /*background-color:#FFF;*/ +} + +div.cal_vu_disabled { + background-color:#FFF; + cursor:default; +} + +table.cal_day_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_day_table td { +} + +div.cal_day_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #AAA; +} + +div.cal_day_unit{ + width:100%; + cursor:pointer; +} + +table.cal_week_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_week_table td { + width: 12.5%; +} + +div.cal_week_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #888; +} + +div.cal_week_unit{ + width: 100%; + cursor:pointer; +} + +div.cal_event { + width: 100%; + height: 12px; + overflow: hidden; + font-size: 11px; + color: #00B; + margin-bottom: 2px; + text-decoration: underline; +} + +div.cal_event_Public { + color: GREEN; +} + +div.cal_event_Private { + color: BLUE; +} + +div.cal_event_hover { + text-decoration: underline; +} diff --git a/css/default.css b/css/default.css new file mode 100644 index 0000000000..1206c8fe72 --- /dev/null +++ b/css/default.css @@ -0,0 +1,1773 @@ +html { + margin: 0px; + padding: 0px; +} + +body { + margin: 0px; + padding: 0px; + font-family: Arial, Helvetica, Sans; + font-size: 12px; + color: #000; +} + +input, select, button { font-size: 12px; font-family: Arial, Helvetica, Sans; } + +li { margin: 4px; } + +h1, h2, h3, h4, h5 { + font-family: Tahoma, Sans; + font-weight: normal; +} + +h1 { margin: 8px 0px; padding: 0px; font-size: 27px; } +h2 { margin: 8px 0px; padding: 0px; font-size: 23px; } +h3 { margin: 4px 0px; padding: 0px; font-size: 17px; } +h4 { margin: 2px 0px; padding: 0px; font-size: 13px; } +h5 { margin: 2px 0px; padding: 0px; font-size: 13px; } + +pre { margin: 0px; padding: 0px; } + +button { margin: 2px; margin-left: 0px; } + +select, input, textarea { + border: 1px solid #AAA; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + font-size: 13px + padding: 2px; +} + +textarea { font-family: arial, helvetica, sans serif; height: 120px; width: 90%; overflow-x: auto; font-size: 12px; } + +table { padding: 0px; border-collapse: 'collapse'} + +td { padding:0px; margin: 0px; vertical-align: top; } + +a:active { outline:none; } + +:focus { -moz-outline-style:none; } + +table.simpletable { border-collapse: collapse; margin-bottom: 10px;} +table.simpletable td {border: 1pt solid #000; vertical-align: top; padding: 2px; } + +div.fix_ff_cursor { overflow: auto; } + +/* --- Layout --- */ + +div.comment { color: #444; } + +div#body_div { + position: relative; + display: none; +} + +div.no_script { + display: none; +} + +div.loading_div { + position: absolute; + background-color: #FFFFCC; + z-index: 1999; + right: 5px; + width: 90px; + display: none; + text-align: center; + padding: 2px; + font-size: 12px; + border: 1px solid #FF4; +} + + +div#head_div { background-color: #FFF; } + +#head_banner { background-color: #FFF; } + +.link_type { + padding:2px; + color: #00b; + text-decoration: underline; + cursor: pointer; +} + +.link_type:hover { + color: #fff !important; + background-color: #07b; + text-decoration: none; +} + +div.std-footer { + margin: 13px 0px; + border-top: 1px solid #AAA; + padding: 13px; +} + +div.std-footer-item { + margin: 0px 13px 13px 0px; +} + +/******** Menus - menu.js ************/ + +ul.menu_toolbar { + z-index: 30; + padding: 0px; + margin: 0px; + margin-top: 1px; +} + +ul.menu_toolbar li { + list-style: none; + margin: 0px; + float: left; +} + +.top_menu { + margin: 0px; + padding: 4px; + cursor: pointer; + color: #FFF; + margin-right: 8px; +} + +.top_menu_mo { + background-color: #000; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.menu_toolbar_dropdown { + position: absolute; + margin-top: 4px; + margin-left: 8px; + width: 140px; + background-color: #FFF; + color: #000; + display: none; + border: 2px solid #333; + z-index: 31; + overflow-y: auto; + overflow-x: hidden; +} + +div.dd_item { + cursor: pointer; + padding: 4px; + background-color: #FFF; +} +div.dd_item_mo { background-color: #FE8; } + +/* FLOATING MESSAGE */ + +.btn-img { cursor: pointer; } + +div.fetching { color: #888; text-align:right; } + +div.notice { + postion: absolute; + background-color: #000; + -moz-border-radius: 5px; -webkit-border-radius: 5px; + opacity: 0.6; + right: 0; + top: 0; + margin-top: 8px; + z-index: -1; + padding: 8px; +} + +/** help **/ + +.info-box { + background-color:#eeeef2; + font-size: 12px; + line-height: 1.6em; + color: #335; + padding: 7px; + margin: 11px 0px; + border: 1px solid #c2c2cc; +} + +.help_box, .help-box { + background-color:#FFC; + font-size: 13px; + line-height: 1.6em; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box { + background-color:#FFC; + font-size: 13px; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box_big { + background-color:#FFC; + color: #864; + padding: 7px; + margin: 7px 0px; + border: 1px solid #EEB; + text-align: center; + font-size: 14px; +} +/* FORMS */ + + +div.frm_print_wrapper { + background-color:#FFF; + border:1px solid #444; + padding: 40px; + + box-shadow:1px 1px 8px #229; + -moz-box-shadow: 1px 1px 8px #229; + -webkit-box-shadow: 1px 1px 8px #229; +} + +div.page_break { + margin: 24px 0px; + border-top: 1px dashed #888; +} + +div.grid_tbarlinks { + border-bottom: 0px; + background-color: #CCC; + padding: 4px 4px 2px 4px; + width: 180px; + float: right; + + -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; + -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; +} + + +div.frm_tip_box { + margin: 0px; + padding: 8px; + background-color: #FFC; + display: none; + font-size: 11px; + border: 1px solid #FFB; +} + +div.frm_tip_box table { + border-collapse: collapse; + vertical-align: top; +} + +td.frm_tray_area { + width: 122px; +} + +div.dialog_frm { + position: relative; + margin: 10px; +} + + + +/*------------------*/ + +.top_cell { + height: 50px; +} + +div.attach_area { + padding: 8px; + margin: 8px; + background-color: #EEE; +} + +div.attach_area table { + width: 100%; +} + +.tablabel_normal { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + display: inline; + cursor: pointer; +} + +.tablabel_selected { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + font-weight: bold; + display: inline; + cursor: pointer; + color: #000; +} + +.scrollhead_wrapper { + position: absolute; + z-index: 1; + height: 30px; +} + +.treeimg { + cursor: pointer; + margin-right: 3px; +} + + +.sectionCell { + padding: 5px; + vertical-align: top; +} + +.code_area { + width: 80%; + margin: 8px; + padding: 4px; + background-color: #F8F8F8; + border: 1px solid #CCC; + overflow-x: auto; +} + +.code_text { + width: 100%; + height: 360px; + margin-top: 3px; + font-family: Courier, Fixed; + font-size: 12px; +} + +div.time_field select{ + display: inline; + margin: 2px; + width: 45px; +} + +/* Documents */ + +.frm_field_table { + width: 100%; + border-collapse: collapse; +} + +.datalabelcell { + padding: 2px 0px; + width: 160px; + vertical-align: top; +} +.datainputcell { padding: 2px 0px; } + + +.field_description { + margin: 3px 0px 11px 0px; + color: #888; + font-size: 12px; + font-style: italic; +} + +.field_description_top { + margin-bottom: 3px; +} + +.field_label { + font-size:11px; +} +.input_area input, select, textarea { + font-size: 14px; + padding: 2px; +} + +.input_area input { + width: 80%; + margin: 0px; +} +.input_area select { + width: 80%; +} +.input_area textarea { + width: 90%; +} + +.disp_area { + width: 80%; + padding: 2px 0px; + font-size: 12px; +} +.disp_area_no_val { + height: 14px; +} + +.no_img { + padding: 40px; + width: 100px; + height: 20px; + color: #888; + text-align: center; + border: 1px solid #AAA; +} + +.input-mandatory { + font-size: 14px !important; + font-weight: bold; +} + +.field-to-update { + background-color:#FEE; +} + +/* sidebar */ + +div.sidebar-comment-wrapper input { + width: 50%; +} +div.sidebar-comment-message { + margin-top: 8px; + font-size: 11px; + color: #777; +} + +div.sidebar-comment-text { + font-size: 12px; + font-weight: bold; + margin-top: 8px; + color: #444; +} +div.sidebar-comment-info { + font-size: 10px; + color: #777; +} + + +/* Grid */ + + +/* --- Simple --- */ +.grid_wrapper_simple { + width: 100%; + margin-bottom: 8px; + border: 1px solid #AA9; +} + +.grid_head_wrapper_simple { + padding: 0px; + border-bottom: 2px solid #AAA; +} + +.grid_head_wrapper_simple td { + border-right: 1px solid #AA9; +} + +.grid_head_wrapper_simple td div { + padding: 2px; +} + +.grid_tab_wrapper_simple { +} + +.grid_cell_simple { + padding: 2px; + background-color: #fff; + border-right: 1px solid #AA9; +} + + +/* --- Normal --- */ +.grid_wrapper { + position: relative; + overflow: auto; + border: 1px solid #AAA; + width: 100%; + margin-bottom: 8px; + background-color: #fff; +} + +.grid_tab_wrapper { + position: absolute; + top: 30px; + border-bottom: 1px solid #DDD; +} + +.grid_table, .grid_head_table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +.grid_cell { + border-right: 1px solid #ddd; + padding: 0px; + background-color: #fff; +} + +.grid_head_wrapper { + position: absolute; + z-index: 1; + height: 30px; + padding: 0px; + overflow: hidden; + /*background-color: #fff;*/ +} + +.grid_head_table td { + background-color: #EEE; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + height: 30px; + padding: 0px; +} + +.grid_head_table td div { + color: #222; + font-weight: bold; + overflow: hidden; + padding: 2px 0px; + text-align: center; +} + +.grid_selector { + padding: 1px; + border-right: 1px solid #DDD; + width: 20px; + background-color: #fff; +} + +.grid_cell_div { + padding: 2px; + cursor: pointer; + overflow: hidden; + border: 2px solid #FFF; +} + +.grid_cell_div_selected { + border: 2px solid #88f; +} + +.grid_cell_div input, .grid_cell_div select, .grid_cell_div div input { + margin: 0px; + border: 0px; + width: 100%; + margin: 0px; + } + +.grid_cell_div textarea { + border: 3px solid #abf; + height:200px; + width: 300px; + z-index: 10; + position:absolute; +} + +.gridDivSelected option { border: 0px; } +/* listing 2.0 */ + +div.listing-more { + margin: 7px 0px 17px 0px; + textAlign: center; + display: none; +} + +div.listing-toolbar { + margin: 7px 0px; +} + +/* SRS */ + +table.srs_result_tab { + border: 2px solid #AAA; + border-collapse: collapse; +} + +/* firefox bug fix for disappering borders */ +table.srs_result_tab td, table.srs_result_tab tr, table.srs_result_tab tbody, table.srs_result_tab div { + position: static; +} + +table.srs_result_tab td { + padding: 3px 2px; + position: static; +} + +div.srs_body_area { +} + +div.srs_results_area { +} + +div.srs_filter_wrapper { + border: 1px solid #CCF; + + background-color: #EEF; + margin:0px 0px 8px 0px; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +div.srs_filter_area { + padding: 8px; +} + +div.srs_filter_area td { + vertical-align: middle; +} + + + + + +/* Reports */ + +div.report_grid_area { + position: relative; + padding: 8px; +} + + +div.report_tab { + border: 1px solid #AAA; + position: relative; + overflow: auto; +} + +div.report_no_data { + padding: 8px; + background-color: #EEE; + border: 1px solid #DDD; + position: absolute; + margin-left: 40%; + margin-top: 50px; + display: none; +} + +div.report_htitle { + float: left; + padding: 2px; + font-size: 14px; + font-weight: bold; + margin-left: 4px; + color: #665; + /*font-weight: bold;*/ +} + +div.report_tbar { + /*background: url('../images/ui/blue-back.gif') repeat-x; */ + background-color: #EEF; + border: 1px solid #CCF; + border-bottom: 0px; + height: 28px; +} + +div.report_tbar table{ + width: 100%; +} +div.report_tbar table td { + +} +div.report_tbar table td div { + position: relative; +} +div.report_tbar button, div.report_tbar select, div.report_tbar img { + font-size: 11px; + margin: 0px; +} + +div.report_head_wrapper { + position: absolute; + height: 24px; + top: 0px; + z-index: 1; +} + +div.report_tab_wrapper { + position: absolute; + border-bottom: 1px solid #AAA; + border-top: 1px solid #AAA; +} + +div.report_tab_wrapper table, div.report_head_wrapper table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +div.report_tab_wrapper table td, div.report_head_wrapper table td { + border-left: 1px solid #AAA; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + overflow: hidden; + padding: 0px; +} + +div.report_tab_wrapper table td div, div.report_head_wrapper table td div { + padding: 3px; + overflow: hidden; +} + +.report_head_cell { + background-color: #EEE; + border-bottom: 1px solid #AA9; + text-align: center; + font-weight: bold; +} +.report_head_cell div { + color:#222; + height: 18px; +} + + +/* FINDER */ + +div.finder_wrapper { +} + +div.finder_body_area { + margin: 16px; +} + +div.finder_body { + display: none; +} + +div.finder_advanced_area table { + width: 80%; +} + +div.finder_advanced_area textarea { + width: 80%; +} + +div.finder_filter_area { + position: relative; +} + +div.filter_head { + font-size: 14px; + margin-bottom: 2px; +} +div.filter_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} +table.filter_tab { + width: 96%; + border-collapse: collapse; +} + +table.filter_tab td { + width: 50%; +} + +div.finder_picker_area { + +} +div.builder_field { + margin: 0px; +} +div.builder_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} + +div.builder_field table { + width: 90%; + border-collapse: collapse; +} + +div.builder_label { + height: 20px; +} + +div.builder_head { + font-size: 16px; + font-weight: bold; + color: #AB6; +} + +table.builder_tab { + width: 96%; + border-collapse: collapse; +} + +table.builder_tab td { + width: 33%; + padding: 2px; +} +/**** CALENDAR ****/ + +.caldiv { + position:absolute; + visibility:hidden; + background-color:white; + width: 144px; + z-index: 301; /* always on top(?) */ +} + + + +div.cal_wrapper { } +div.cal_body { + margin: 16px; + background-color: #DDD; + position: relative; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.cal_head { + margin: 16px; + margin-bottom: 0px; +} +div.cal_head div { + font-size: 18px; + color: #666; + padding-top: 8px; +} + +div.cal_view_body { + margin: 16px; +} + +div.cal_view_body_plain { + margin: 16px; +} + +div.cal_month_head { +} + +div.cal_month_body { + border-top: 1px solid #888; +} + +.cal_month_headtable { + /*table-layout:fixed;*/ + width: 100%; +} + +.cal_month_name { + width: 100%; + color: #888; + font-size: 14px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +.cal_month_headtable tr td{ + font-size: 12px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +table.cal_month_table { + border-collapse: collapse; + /*table-layout:fixed;*/ + height: 100%; + width: 100%; +} + +table.cal_month_table td { + width: 14.29%; + height: 20%; + /*overflow:hidden;*/ + padding:0px; +} + +div.cal_month_date { + width:100%; + height:25%; + font-size: 10px; + overflow:hidden; + /*background-color: #EEF;*/ +} + +div.cal_month_date_holiday { + /*background-color: #FFF;*/ +} + +div.cal_month_unit { + width:100%; + height:75%; + overflow:hidden; + cursor:pointer; + /*background-color:#FFF;*/ +} + +div.cal_vu_disabled { + background-color:#FFF; + cursor:default; +} + +table.cal_day_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_day_table td { +} + +div.cal_day_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #AAA; +} + +div.cal_day_unit{ + width:100%; + cursor:pointer; +} + +table.cal_week_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_week_table td { + width: 12.5%; +} + +div.cal_week_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #888; +} + +div.cal_week_unit{ + width: 100%; + cursor:pointer; +} + +div.cal_event { + width: 100%; + height: 12px; + overflow: hidden; + font-size: 11px; + color: #00B; + margin-bottom: 2px; + text-decoration: underline; +} + +div.cal_event_Public { + color: GREEN; +} + +div.cal_event_Private { + color: BLUE; +} + +div.cal_event_hover { + text-decoration: underline; +} + +/* +================================================ +autosuggest, inquisitor style +================================================ +*/ + +div.autosuggest +{ + position: absolute; + margin-top: 3px; + border: 1px solid #222; +} + +div.autosuggest ul +{ + list-style: none; + margin: 0px; + padding: 2px; + overflow: hidden; + background-color: #FFF; +} + +div.autosuggest ul li +{ + color: #444; + padding: 0; + margin: 0; + text-align: left; +} + +div.autosuggest ul li a +{ + color: #444; + display: block; + text-decoration: none; + position: relative; + padding: 0; + width: 100%; +} +div.autosuggest ul li a:hover +{ + +} +div.autosuggest ul li.as_highlight a:hover +{ + background-color: #45A; + color: #FFF; +} + +div.autosuggest ul li a span +{ + display: block; + padding: 3px 6px; + color: #444; + border-bottom:1px solid #DDD; +} + +div.autosuggest ul li a span small +{ + display: block; + font-weight: normal; + color: #444; +} + +div.autosuggest ul li.as_highlight a span small +{ + color: #FFF; +} + +div.autosuggest ul li.as_highlight a span { + color: #FFF; +} + +div.autosuggest ul li.as_highlight a +{ + color: #FFF; + background-color: #45A; + cursor: pointer; +} + +div.autosuggest ul li.as_warning +{ + font-weight: bold; + text-align: center; +} + +div.autosuggest ul em +{ + font-style: normal; + font-weight: bold; +} + +/***** Dialogs *******/ + +div.dialog_wrapper { + position: absolute; + width: 440px; + display: none; + z-index: 90; + background-color: #FFF; + border: 3px solid #222; + box-shadow:1px 1px 5px #777; + -moz-box-shadow: 1px 1px 5px #777; + -webkit-box-shadow: 1px 1px 5px #777; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_head { + height: 22px; + padding: 4px; + background-color: #222; + color: #FFF; +} + +div.dialog_body { + padding: 8px 4px 16px 4px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_back { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 100%; + background-color: #EEE; + opacity: 0.6; + z-index: 50; + text-align: center; +} + +div.dialog_message { + display: none; + position: absolute; + width: 250px; + font-size: 12px; + z-index: 91; + background-color:#FFF; + padding: 12px; + border: 1px solid #444; +} + +div.dialog_row { + padding: 8px 8px 0px 8px; +} + +div.dialog_row table { + width: 100%; +} + +div.dialog_row table td { +} + +div.dialog_row input[type="text"], div.dialog_row input[type="password"], div.dialog_row textarea, div.dialog_row select { + width: 80%; + font-size: 14px; +} + +div.dialog_row table td textarea { + width: 80%; + height: 200px; + font-size: 12px; +} + + +/* Recent */ + +div.recent_starred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star.gif'); +} + +div.recent_unstarred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star_plain.gif'); +} + +div.status_flag { + width: 8px; + height: 8px; + margin: 4px; + font-size: 0px; + background-color: #EEE; +} + + + + + +/* Search */ + +.search_table td { + padding: 2px; +} + + + + +/*** for wn toolbar ***/ +.wntoolbar-icon { background: url('../images/icons/wntoolbar-icons.png'); width: 16px; height: 16px; } +.sprite-home { background-position: 0 0; } +.sprite-new { background-position: 0 -66px; } +.sprite-pages { background-position: 0 -132px; } +.sprite-recent { background-position: 0 -198px; } +.sprite-report { background-position: 0 -264px; } +.sprite-search { background-position: 0 -330px; } +.sprite-tools { background-position: 0 -396px; } + +/******* TABS ********/ + +div.box_label_wrapper { + border-bottom: 6px solid #777; +} + +div.box_label_body { + height: 22px; +} + +ul.box_tabs { + margin: 0px; + padding: 0px; + list-style: none; +} + +ul.box_tabs li { + height: 22px; + float:left; + font-size: 12px; + text-decoration: underline; + + background-color: #DDD; + + margin:0; + margin-left: 4px; + padding:0 0 0 9px; + cursor: pointer; +} + +ul.box_tabs a { + display:block; + padding:3px 15px 3px 6px; + text-decoration:none; +} + +ul.box_tabs li.box_tab_mouseover { + background-color: #BBB; +} + + +ul.box_tabs li.box_tab_selected { +/* background:url("../images/ui/rc/tab-left-CCC.gif") no-repeat left top; + background-color: #ABABAB; */ + + background-color: #777; + + background: -webkit-gradient(linear, left top, left bottom, from(#999), to(#777)); + background: -moz-linear-gradient(top, #999, #777); + + color: #FFF; + font-weight:bold; + +} +ul.box_tabs li.box_tab_selected a { +/* background:url("../images/ui/rc/tab-right-CCC.gif") no-repeat right top; */ +} + +/******* jqPlot ***********/ + +/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ +.jqplot-target { + position: relative; + color: #666666; + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; +/* height: 300px; + width: 400px;*/ +} + +/*rules applied to all axes*/ +.jqplot-axis { + font-size: 0.75em; +} + +.jqplot-xaxis { + margin-top: 10px; +} + +.jqplot-x2axis { + margin-bottom: 10px; +} + +.jqplot-yaxis { + margin-right: 10px; +} + +.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis { + margin-left: 10px; + margin-right: 10px; +} + +/*rules applied to all axis tick divs*/ +.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + position: absolute; +} + + +.jqplot-xaxis-tick { + top: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-top: 10px;*/ + vertical-align: top; +} + +.jqplot-x2axis-tick { + bottom: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-bottom: 10px;*/ + vertical-align: bottom; +} + +.jqplot-yaxis-tick { + right: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-right: 10px;*/ + text-align: right; +} + +.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + left: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-left: 10px;*/ +/* padding-right: 15px;*/ + text-align: left; +} + +.jqplot-xaxis-label { + margin-top: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-x2axis-label { + margin-bottom: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-yaxis-label { + margin-right: 10px; +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label { +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +table.jqplot-table-legend, table.jqplot-cursor-legend { + background-color: rgba(255,255,255,0.6); + border: 1px solid #cccccc; + position: absolute; + font-size: 0.75em; +} + +td.jqplot-table-legend { + vertical-align:middle; +} + +td.jqplot-table-legend > div { + border:1px solid #cccccc; + padding:0.2em; +} + +div.jqplot-table-legend-swatch { + width:0px; + height:0px; + border-top-width: 0.35em; + border-bottom-width: 0.35em; + border-left-width: 0.6em; + border-right-width: 0.6em; + border-top-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; +} + +.jqplot-title { + top: 0px; + left: 0px; + padding-bottom: 0.5em; + font-size: 1.2em; +} + +table.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; +} + + +.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-highlighter-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-point-label { + font-size: 0.75em; +} + +td.jqplot-cursor-legend-swatch { +vertical-align:middle; +text-align:center; +} + +div.jqplot-cursor-legend-swatch { +width:1.2em; +height:0.7em; +} + + +/** general icons **/ + +.wn-icon { background: url('../images/icons/icons.png'); width: 16px; height: 16px; cursor: pointer; } +.ic-2x2_grid { background-position: 0 0; } +.ic-3x3_grid { background-position: 0 -36px; } +.ic-3x3_grid_2 { background-position: 0 -72px; } +.ic-air_signal { background-position: 0 -108px; } +.ic-align_center { background-position: 0 -144px; } +.ic-align_just { background-position: 0 -180px; } +.ic-align_left { background-position: 0 -216px; } +.ic-align_right { background-position: 0 -252px; } +.ic-app_window { background-position: 0 -288px; } +.ic-arrow_bottom { background-position: 0 -324px; } +.ic-arrow_bottom_left { background-position: 0 -360px; } +.ic-arrow_bottom_right { background-position: 0 -396px; } +.ic-arrow_l { background-position: 0 -432px; } +.ic-arrow_left { background-position: 0 -468px; } +.ic-arrow_r { background-position: 0 -504px; } +.ic-arrow_right { background-position: 0 -540px; } +.ic-arrow_top { background-position: 0 -576px; } +.ic-arrow_top_left { background-position: 0 -612px; } +.ic-arrow_top_right { background-position: 0 -648px; } +.ic-arrow_two_head { background-position: 0 -684px; } +.ic-arrow_two_head_2 { background-position: 0 -720px; } +.ic-attention { background-position: 0 -756px; } +.ic-battery { background-position: 0 -792px; } +.ic-bell { background-position: 0 -828px; } +.ic-book { background-position: 0 -864px; } +.ic-bookmark_1 { background-position: 0 -900px; } +.ic-bookmark_2 { background-position: 0 -936px; } +.ic-box { background-position: 0 -972px; } +.ic-br_down { background-position: 0 -1008px; } +.ic-br_next { background-position: 0 -1044px; } +.ic-br_prev { background-position: 0 -1080px; } +.ic-br_up { background-position: 0 -1116px; } +.ic-brackets { background-position: 0 -1152px; } +.ic-browser { background-position: 0 -1188px; } +.ic-brush { background-position: 0 -1224px; } +.ic-bug { background-position: 0 -1260px; } +.ic-burst { background-position: 0 -1296px; } +.ic-calc { background-position: 0 -1332px; } +.ic-calendar_1 { background-position: 0 -1368px; } +.ic-calendar_2 { background-position: 0 -1404px; } +.ic-cancel { background-position: 0 -1440px; } +.ic-case { background-position: 0 -1476px; } +.ic-cc { background-position: 0 -1512px; } +.ic-cert { background-position: 0 -1548px; } +.ic-chart_bar { background-position: 0 -1584px; } +.ic-chart_line { background-position: 0 -1620px; } +.ic-chart_line_2 { background-position: 0 -1656px; } +.ic-chart_pie { background-position: 0 -1692px; } +.ic-checkbox_checked { background-position: 0 -1728px; } +.ic-checkbox_unchecked { background-position: 0 -1764px; } +.ic-checkmark { background-position: 0 -1800px; } +.ic-clip { background-position: 0 -1836px; } +.ic-clipboard_copy { background-position: 0 -1872px; } +.ic-clipboard_cut { background-position: 0 -1908px; } +.ic-clipboard_past { background-position: 0 -1944px; } +.ic-clock { background-position: -36px 0; } +.ic-cloud { background-position: -36px -36px; } +.ic-cloud_rain { background-position: -36px -72px; } +.ic-cog { background-position: -36px -108px; } +.ic-comp { background-position: -36px -144px; } +.ic-compass { background-position: -36px -180px; } +.ic-contact_card { background-position: -36px -216px; } +.ic-cube { background-position: -36px -252px; } +.ic-cur_bp { background-position: -36px -288px; } +.ic-cur_dollar { background-position: -36px -324px; } +.ic-cur_euro { background-position: -36px -360px; } +.ic-cur_yen { background-position: -36px -396px; } +.ic-cursor_H_split { background-position: -36px -432px; } +.ic-cursor_V_split { background-position: -36px -468px; } +.ic-cursor_arrow { background-position: -36px -504px; } +.ic-cursor_drag_arrow { background-position: -36px -540px; } +.ic-cursor_drag_arrow_2 { background-position: -36px -576px; } +.ic-cursor_drag_hand { background-position: -36px -612px; } +.ic-cursor_hand { background-position: -36px -648px; } +.ic-db { background-position: -36px -684px; } +.ic-delete { background-position: -36px -720px; } +.ic-doc_delete { background-position: -36px -756px; } +.ic-doc_edit { background-position: -36px -792px; } +.ic-doc_empty { background-position: -36px -828px; } +.ic-doc_export { background-position: -36px -864px; } +.ic-doc_import { background-position: -36px -900px; } +.ic-doc_lines { background-position: -36px -936px; } +.ic-doc_lines_stright { background-position: -36px -972px; } +.ic-doc_minus { background-position: -36px -1008px; } +.ic-doc_new { background-position: -36px -1044px; } +.ic-doc_plus { background-position: -36px -1080px; } +.ic-document { background-position: -36px -1116px; } +.ic-download { background-position: -36px -1152px; } +.ic-emotion_sad { background-position: -36px -1188px; } +.ic-emotion_smile { background-position: -36px -1224px; } +.ic-expand { background-position: -36px -1260px; } +.ic-eye { background-position: -36px -1296px; } +.ic-eye_inv { background-position: -36px -1332px; } +.ic-facebook { background-position: -36px -1368px; } +.ic-filter { background-position: -36px -1404px; } +.ic-fire { background-position: -36px -1440px; } +.ic-flag { background-position: -36px -1476px; } +.ic-folder { background-position: -36px -1512px; } +.ic-folder_arrow { background-position: -36px -1548px; } +.ic-folder_delete { background-position: -36px -1584px; } +.ic-folder_minus { background-position: -36px -1620px; } +.ic-folder_open { background-position: -36px -1656px; } +.ic-folder_plus { background-position: -36px -1692px; } +.ic-font_bold { background-position: -36px -1728px; } +.ic-font_italic { background-position: -36px -1764px; } +.ic-font_size { background-position: -36px -1800px; } +.ic-font_strokethrough { background-position: -36px -1836px; } +.ic-font_underline { background-position: -36px -1872px; } +.ic-game_pad { background-position: -36px -1908px; } +.ic-globe_1 { background-position: -36px -1944px; } +.ic-globe_2 { background-position: -72px 0; } +.ic-globe_3 { background-position: -72px -36px; } +.ic-google { background-position: -72px -72px; } +.ic-hand_1 { background-position: -72px -108px; } +.ic-hand_2 { background-position: -72px -144px; } +.ic-hand_contra { background-position: -72px -180px; } +.ic-hand_pro { background-position: -72px -216px; } +.ic-headphones { background-position: -72px -252px; } +.ic-heart { background-position: -72px -288px; } +.ic-heart_empty { background-position: -72px -324px; } +.ic-home { background-position: -72px -360px; } +.ic-image_text { background-position: -72px -396px; } +.ic-inbox { background-position: -72px -432px; } +.ic-indent_decrease { background-position: -72px -468px; } +.ic-indent_increase { background-position: -72px -504px; } +.ic-info { background-position: -72px -540px; } +.ic-iphone { background-position: -72px -576px; } +.ic-key { background-position: -72px -612px; } +.ic-layers_1 { background-position: -72px -648px; } +.ic-layers_2 { background-position: -72px -684px; } +.ic-lightbulb { background-position: -72px -720px; } +.ic-lighting { background-position: -72px -756px; } +.ic-link { background-position: -72px -792px; } +.ic-list_bullets { background-position: -72px -828px; } +.ic-list_num { background-position: -72px -864px; } +.ic-magic_wand { background-position: -72px -900px; } +.ic-mail { background-position: -72px -936px; } +.ic-mail_2 { background-position: -72px -972px; } +.ic-mic { background-position: -72px -1008px; } +.ic-monitor { background-position: -72px -1044px; } +.ic-movie { background-position: -72px -1080px; } +.ic-music { background-position: -72px -1116px; } +.ic-net_comp { background-position: -72px -1152px; } +.ic-network { background-position: -72px -1188px; } +.ic-notepad { background-position: -72px -1224px; } +.ic-notepad_2 { background-position: -72px -1260px; } +.ic-on-off { background-position: -72px -1296px; } +.ic-openid { background-position: -72px -1332px; } +.ic-padlock_closed { background-position: -72px -1368px; } +.ic-padlock_open { background-position: -72px -1404px; } +.ic-page_layout { background-position: -72px -1440px; } +.ic-paragraph { background-position: -72px -1476px; } +.ic-pencil { background-position: -72px -1512px; } +.ic-phone { background-position: -72px -1548px; } +.ic-phone_1 { background-position: -72px -1584px; } +.ic-phone_2 { background-position: -72px -1620px; } +.ic-phone_touch { background-position: -72px -1656px; } +.ic-photo { background-position: -72px -1692px; } +.ic-picture { background-position: -72px -1728px; } +.ic-pin { background-position: -72px -1764px; } +.ic-pin_2 { background-position: -72px -1800px; } +.ic-pin_map { background-position: -72px -1836px; } +.ic-pin_map_down { background-position: -72px -1872px; } +.ic-pin_map_left { background-position: -72px -1908px; } +.ic-pin_map_right { background-position: -72px -1944px; } +.ic-pin_map_top { background-position: -108px 0; } +.ic-pin_sq_down { background-position: -108px -36px; } +.ic-pin_sq_left { background-position: -108px -72px; } +.ic-pin_sq_right { background-position: -108px -108px; } +.ic-pin_sq_top { background-position: -108px -144px; } +.ic-playback_ff { background-position: -108px -180px; } +.ic-playback_next { background-position: -108px -216px; } +.ic-playback_pause { background-position: -108px -252px; } +.ic-playback_play { background-position: -108px -288px; } +.ic-playback_prev { background-position: -108px -324px; } +.ic-playback_rec { background-position: -108px -360px; } +.ic-playback_reload { background-position: -108px -396px; } +.ic-playback_rew { background-position: -108px -432px; } +.ic-playback_stop { background-position: -108px -468px; } +.ic-preso { background-position: -108px -504px; } +.ic-print { background-position: -108px -540px; } +.ic-question { background-position: -108px -576px; } +.ic-redo { background-position: -108px -612px; } +.ic-rnd_br_down { background-position: -108px -648px; } +.ic-rnd_br_first { background-position: -108px -684px; } +.ic-rnd_br_last { background-position: -108px -720px; } +.ic-rnd_br_next { background-position: -108px -756px; } +.ic-rnd_br_prev { background-position: -108px -792px; } +.ic-rnd_br_up { background-position: -108px -828px; } +.ic-round { background-position: -108px -864px; } +.ic-round_and_up { background-position: -108px -900px; } +.ic-round_arrow_left { background-position: -108px -936px; } +.ic-round_arrow_right { background-position: -108px -972px; } +.ic-round_checkmark { background-position: -108px -1008px; } +.ic-round_delete { background-position: -108px -1044px; } +.ic-round_minus { background-position: -108px -1080px; } +.ic-round_plus { background-position: -108px -1116px; } +.ic-rss { background-position: -108px -1152px; } +.ic-rss_sq { background-position: -108px -1188px; } +.ic-sand { background-position: -108px -1224px; } +.ic-sat_dish { background-position: -108px -1260px; } +.ic-save { background-position: -108px -1296px; } +.ic-server { background-position: -108px -1332px; } +.ic-share { background-position: -108px -1368px; } +.ic-shop_cart { background-position: -108px -1404px; } +.ic-sound_high { background-position: -108px -1440px; } +.ic-sound_low { background-position: -108px -1476px; } +.ic-sound_mute { background-position: -108px -1512px; } +.ic-spechbubble { background-position: -108px -1548px; } +.ic-spechbubble_2 { background-position: -108px -1584px; } +.ic-spechbubble_sq { background-position: -108px -1620px; } +.ic-spechbubble_sq_line { background-position: -108px -1656px; } +.ic-sq_br_down { background-position: -108px -1692px; } +.ic-sq_br_first { background-position: -108px -1728px; } +.ic-sq_br_last { background-position: -108px -1764px; } +.ic-sq_br_next { background-position: -108px -1800px; } +.ic-sq_br_prev { background-position: -108px -1836px; } +.ic-sq_br_up { background-position: -108px -1872px; } +.ic-sq_down { background-position: -108px -1908px; } +.ic-sq_minus { background-position: -108px -1944px; } +.ic-sq_next { background-position: -144px 0; } +.ic-sq_plus { background-position: -144px -36px; } +.ic-sq_prev { background-position: -144px -72px; } +.ic-sq_up { background-position: -144px -108px; } +.ic-square_shape { background-position: -144px -144px; } +.ic-star { background-position: -144px -180px; } +.ic-star_fav { background-position: -144px -216px; } +.ic-star_fav_empty { background-position: -144px -252px; } +.ic-sun { background-position: -144px -288px; } +.ic-tag { background-position: -144px -324px; } +.ic-tape { background-position: -144px -360px; } +.ic-target { background-position: -144px -396px; } +.ic-text_curstor { background-position: -144px -432px; } +.ic-text_letter_t { background-position: -144px -468px; } +.ic-top_right_expand { background-position: -144px -504px; } +.ic-trash { background-position: -144px -540px; } +.ic-twitter { background-position: -144px -576px; } +.ic-twitter_2 { background-position: -144px -612px; } +.ic-undo { background-position: -144px -648px; } +.ic-user { background-position: -144px -684px; } +.ic-users { background-position: -144px -720px; } +.ic-wrench { background-position: -144px -756px; } +.ic-wrench_plus { background-position: -144px -792px; } +.ic-wrench_plus_2 { background-position: -144px -828px; } +.ic-zoom { background-position: -144px -864px; } + + +div.psidebar-wrapper { + margin: 0px 8px; +} + +div.psidebar-head { + font-size: 14px; + font-weight: bold; + color: #555; + margin-bottom: 12px; +} + +div.psidebar-section { + background-color: #f7f7f5; + border: 2px solid #b2b2b7; + margin-bottom: 11px; +} + +div.psidebar-section-head { + font-weight: bold; + font-size: 13px; + color: #222; + background-color: #d8d8d4; + margin-bottom: 7px; + padding: 3px 11px; +} + +div.psidebar-section-body { + margin: 7px 11px 11px 11px; +} + +div.psidebar-section-item { + margin-bottom: 7px; +} + +.psidebar-section-link { + font-size: 11px; + color: #666; +} + +div.follower-list { + color: #666; + margin-top: 7px; + font-size: 11px; +} +/******** Listing2 ***********/ +table.dcv-tab { + table-layout: fixed; + border-collapse: collapse; +} + +table.dcv-tab td { + border: 1px solid #DDD; +} + +table.dcv-tab td td { + border: 0px solid #BBB; +} + +div.list2-head { + padding: 3px 6px; + font-size: 14px; + color: #555; +} + +div.list2-new { + padding: 4px; +} + +div.list2-message { + padding: 8px; + color: #888; + background-color: #FFD; +} + +div.list2-search { + padding: 4px; +} + +div.list2-list-area { + padding: 4px; +} + +div.list2-item-div { + border-bottom: 1px solid #AAA; + padding: 4px; + cursor: pointer; +} + +span.list2-edit-link { + font-weight: normal; + font-size: 11px; + margin-left: 7px; +} + +div.list2-item-title { + font-weight: bold; +} + +div.list2-item-selected { + background-color: #CCF; +} + +div.list2-item-more-info { + color: #888; + margin-top: 4px; +} diff --git a/css/dialog.css b/css/dialog.css new file mode 100644 index 0000000000..f417994bb4 --- /dev/null +++ b/css/dialog.css @@ -0,0 +1,76 @@ +/***** Dialogs *******/ + +div.dialog_wrapper { + position: absolute; + width: 440px; + display: none; + z-index: 90; + background-color: #FFF; + border: 3px solid #222; + box-shadow:1px 1px 5px #777; + -moz-box-shadow: 1px 1px 5px #777; + -webkit-box-shadow: 1px 1px 5px #777; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_head { + height: 22px; + padding: 4px; + background-color: #222; + color: #FFF; +} + +div.dialog_body { + padding: 8px 4px 16px 4px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_back { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 100%; + background-color: #EEE; + opacity: 0.6; + z-index: 50; + text-align: center; +} + +div.dialog_message { + display: none; + position: absolute; + width: 250px; + font-size: 12px; + z-index: 91; + background-color:#FFF; + padding: 12px; + border: 1px solid #444; +} + +div.dialog_row { + padding: 8px 8px 0px 8px; +} + +div.dialog_row table { + width: 100%; +} + +div.dialog_row table td { +} + +div.dialog_row input[type="text"], div.dialog_row input[type="password"], div.dialog_row textarea, div.dialog_row select { + width: 80%; + font-size: 14px; +} + +div.dialog_row table td textarea { + width: 80%; + height: 200px; + font-size: 12px; +} diff --git a/css/doc_column_view.css b/css/doc_column_view.css new file mode 100644 index 0000000000..30660dcbed --- /dev/null +++ b/css/doc_column_view.css @@ -0,0 +1,62 @@ +/******** Listing2 ***********/ +table.dcv-tab { + table-layout: fixed; + border-collapse: collapse; +} + +table.dcv-tab td { + border: 1px solid #DDD; +} + +table.dcv-tab td td { + border: 0px solid #BBB; +} + +div.list2-head { + padding: 3px 6px; + font-size: 14px; + color: #555; +} + +div.list2-new { + padding: 4px; +} + +div.list2-message { + padding: 8px; + color: #888; + background-color: #FFD; +} + +div.list2-search { + padding: 4px; +} + +div.list2-list-area { + padding: 4px; +} + +div.list2-item-div { + border-bottom: 1px solid #AAA; + padding: 4px; + cursor: pointer; +} + +span.list2-edit-link { + font-weight: normal; + font-size: 11px; + margin-left: 7px; +} + +div.list2-item-title { + font-weight: bold; +} + +div.list2-item-selected { + background-color: #CCF; +} + +div.list2-item-more-info { + color: #888; + margin-top: 4px; +} \ No newline at end of file diff --git a/css/forms.css b/css/forms.css new file mode 100644 index 0000000000..b99410aee6 --- /dev/null +++ b/css/forms.css @@ -0,0 +1,222 @@ +/* FORMS */ + + +div.frm_print_wrapper { + background-color:#FFF; + border:1px solid #444; + padding: 40px; + + box-shadow:1px 1px 8px #229; + -moz-box-shadow: 1px 1px 8px #229; + -webkit-box-shadow: 1px 1px 8px #229; +} + +div.page_break { + margin: 24px 0px; + border-top: 1px dashed #888; +} + +div.grid_tbarlinks { + border-bottom: 0px; + background-color: #CCC; + padding: 4px 4px 2px 4px; + width: 180px; + float: right; + + -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; + -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; +} + + +div.frm_tip_box { + margin: 0px; + padding: 8px; + background-color: #FFC; + display: none; + font-size: 11px; + border: 1px solid #FFB; +} + +div.frm_tip_box table { + border-collapse: collapse; + vertical-align: top; +} + +td.frm_tray_area { + width: 122px; +} + +div.dialog_frm { + position: relative; + margin: 10px; +} + + + +/*------------------*/ + +.top_cell { + height: 50px; +} + +div.attach_area { + padding: 8px; + margin: 8px; + background-color: #EEE; +} + +div.attach_area table { + width: 100%; +} + +.tablabel_normal { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + display: inline; + cursor: pointer; +} + +.tablabel_selected { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + font-weight: bold; + display: inline; + cursor: pointer; + color: #000; +} + +.scrollhead_wrapper { + position: absolute; + z-index: 1; + height: 30px; +} + +.treeimg { + cursor: pointer; + margin-right: 3px; +} + + +.sectionCell { + padding: 5px; + vertical-align: top; +} + +.code_area { + width: 80%; + margin: 8px; + padding: 4px; + background-color: #F8F8F8; + border: 1px solid #CCC; + overflow-x: auto; +} + +.code_text { + width: 100%; + height: 360px; + margin-top: 3px; + font-family: Courier, Fixed; + font-size: 12px; +} + +div.time_field select{ + display: inline; + margin: 2px; + width: 45px; +} + +/* Documents */ + +.frm_field_table { + width: 100%; + border-collapse: collapse; +} + +.datalabelcell { + padding: 2px 0px; + width: 160px; + vertical-align: top; +} +.datainputcell { padding: 2px 0px; } + + +.field_description { + margin: 3px 0px 11px 0px; + color: #888; + font-size: 12px; + font-style: italic; +} + +.field_description_top { + margin-bottom: 3px; +} + +.field_label { + font-size:11px; +} +.input_area input, select, textarea { + font-size: 14px; + padding: 2px; +} + +.input_area input { + width: 80%; + margin: 0px; +} +.input_area select { + width: 80%; +} +.input_area textarea { + width: 90%; +} + +.disp_area { + width: 80%; + padding: 2px 0px; + font-size: 12px; +} +.disp_area_no_val { + height: 14px; +} + +.no_img { + padding: 40px; + width: 100px; + height: 20px; + color: #888; + text-align: center; + border: 1px solid #AAA; +} + +.input-mandatory { + font-size: 14px !important; + font-weight: bold; +} + +.field-to-update { + background-color:#FEE; +} + +/* sidebar */ + +div.sidebar-comment-wrapper input { + width: 50%; +} +div.sidebar-comment-message { + margin-top: 8px; + font-size: 11px; + color: #777; +} + +div.sidebar-comment-text { + font-size: 12px; + font-weight: bold; + margin-top: 8px; + color: #444; +} +div.sidebar-comment-info { + font-size: 10px; + color: #777; +} \ No newline at end of file diff --git a/css/grid.css b/css/grid.css new file mode 100644 index 0000000000..a9c5e877c1 --- /dev/null +++ b/css/grid.css @@ -0,0 +1,122 @@ + + +/* Grid */ + + +/* --- Simple --- */ +.grid_wrapper_simple { + width: 100%; + margin-bottom: 8px; + border: 1px solid #AA9; +} + +.grid_head_wrapper_simple { + padding: 0px; + border-bottom: 2px solid #AAA; +} + +.grid_head_wrapper_simple td { + border-right: 1px solid #AA9; +} + +.grid_head_wrapper_simple td div { + padding: 2px; +} + +.grid_tab_wrapper_simple { +} + +.grid_cell_simple { + padding: 2px; + background-color: #fff; + border-right: 1px solid #AA9; +} + + +/* --- Normal --- */ +.grid_wrapper { + position: relative; + overflow: auto; + border: 1px solid #AAA; + width: 100%; + margin-bottom: 8px; + background-color: #fff; +} + +.grid_tab_wrapper { + position: absolute; + top: 30px; + border-bottom: 1px solid #DDD; +} + +.grid_table, .grid_head_table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +.grid_cell { + border-right: 1px solid #ddd; + padding: 0px; + background-color: #fff; +} + +.grid_head_wrapper { + position: absolute; + z-index: 1; + height: 30px; + padding: 0px; + overflow: hidden; + /*background-color: #fff;*/ +} + +.grid_head_table td { + background-color: #EEE; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + height: 30px; + padding: 0px; +} + +.grid_head_table td div { + color: #222; + font-weight: bold; + overflow: hidden; + padding: 2px 0px; + text-align: center; +} + +.grid_selector { + padding: 1px; + border-right: 1px solid #DDD; + width: 20px; + background-color: #fff; +} + +.grid_cell_div { + padding: 2px; + cursor: pointer; + overflow: hidden; + border: 2px solid #FFF; +} + +.grid_cell_div_selected { + border: 2px solid #88f; +} + +.grid_cell_div input, .grid_cell_div select, .grid_cell_div div input { + margin: 0px; + border: 0px; + width: 100%; + margin: 0px; + } + +.grid_cell_div textarea { + border: 3px solid #abf; + height:200px; + width: 300px; + z-index: 10; + position:absolute; +} + +.gridDivSelected option { border: 0px; } \ No newline at end of file diff --git a/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/css/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100755 index 0000000000..5b5dab2ab7 Binary files /dev/null and b/css/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/css/images/ui-bg_flat_75_ffffff_40x100.png b/css/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100755 index 0000000000..ac8b229af9 Binary files /dev/null and b/css/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/css/images/ui-bg_glass_55_fbf9ee_1x400.png b/css/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100755 index 0000000000..ad3d6346e0 Binary files /dev/null and b/css/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/css/images/ui-bg_glass_95_fef1ec_1x400.png b/css/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100755 index 0000000000..4443fdc1a1 Binary files /dev/null and b/css/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/css/images/ui-bg_highlight-hard_65_ffffff_1x100.png b/css/images/ui-bg_highlight-hard_65_ffffff_1x100.png new file mode 100755 index 0000000000..eaa8cfa3ca Binary files /dev/null and b/css/images/ui-bg_highlight-hard_65_ffffff_1x100.png differ diff --git a/css/images/ui-bg_highlight-hard_75_dadada_1x100.png b/css/images/ui-bg_highlight-hard_75_dadada_1x100.png new file mode 100755 index 0000000000..eef96a3ef2 Binary files /dev/null and b/css/images/ui-bg_highlight-hard_75_dadada_1x100.png differ diff --git a/css/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png b/css/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png new file mode 100755 index 0000000000..31503e6215 Binary files /dev/null and b/css/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png differ diff --git a/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100755 index 0000000000..7c9fa6c6ed Binary files /dev/null and b/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/css/images/ui-icons_222222_256x240.png b/css/images/ui-icons_222222_256x240.png new file mode 100755 index 0000000000..b273ff111d Binary files /dev/null and b/css/images/ui-icons_222222_256x240.png differ diff --git a/css/images/ui-icons_2e83ff_256x240.png b/css/images/ui-icons_2e83ff_256x240.png new file mode 100755 index 0000000000..09d1cdc856 Binary files /dev/null and b/css/images/ui-icons_2e83ff_256x240.png differ diff --git a/css/images/ui-icons_454545_256x240.png b/css/images/ui-icons_454545_256x240.png new file mode 100755 index 0000000000..59bd45b907 Binary files /dev/null and b/css/images/ui-icons_454545_256x240.png differ diff --git a/css/images/ui-icons_888888_256x240.png b/css/images/ui-icons_888888_256x240.png new file mode 100755 index 0000000000..6d02426c11 Binary files /dev/null and b/css/images/ui-icons_888888_256x240.png differ diff --git a/css/images/ui-icons_cd0a0a_256x240.png b/css/images/ui-icons_cd0a0a_256x240.png new file mode 100755 index 0000000000..2ab019b73e Binary files /dev/null and b/css/images/ui-icons_cd0a0a_256x240.png differ diff --git a/css/jqplot.css b/css/jqplot.css new file mode 100644 index 0000000000..c1882b5286 --- /dev/null +++ b/css/jqplot.css @@ -0,0 +1,169 @@ +/******* jqPlot ***********/ + +/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ +.jqplot-target { + position: relative; + color: #666666; + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; +/* height: 300px; + width: 400px;*/ +} + +/*rules applied to all axes*/ +.jqplot-axis { + font-size: 0.75em; +} + +.jqplot-xaxis { + margin-top: 10px; +} + +.jqplot-x2axis { + margin-bottom: 10px; +} + +.jqplot-yaxis { + margin-right: 10px; +} + +.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis { + margin-left: 10px; + margin-right: 10px; +} + +/*rules applied to all axis tick divs*/ +.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + position: absolute; +} + + +.jqplot-xaxis-tick { + top: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-top: 10px;*/ + vertical-align: top; +} + +.jqplot-x2axis-tick { + bottom: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-bottom: 10px;*/ + vertical-align: bottom; +} + +.jqplot-yaxis-tick { + right: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-right: 10px;*/ + text-align: right; +} + +.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + left: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-left: 10px;*/ +/* padding-right: 15px;*/ + text-align: left; +} + +.jqplot-xaxis-label { + margin-top: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-x2axis-label { + margin-bottom: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-yaxis-label { + margin-right: 10px; +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label { +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +table.jqplot-table-legend, table.jqplot-cursor-legend { + background-color: rgba(255,255,255,0.6); + border: 1px solid #cccccc; + position: absolute; + font-size: 0.75em; +} + +td.jqplot-table-legend { + vertical-align:middle; +} + +td.jqplot-table-legend > div { + border:1px solid #cccccc; + padding:0.2em; +} + +div.jqplot-table-legend-swatch { + width:0px; + height:0px; + border-top-width: 0.35em; + border-bottom-width: 0.35em; + border-left-width: 0.6em; + border-right-width: 0.6em; + border-top-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; +} + +.jqplot-title { + top: 0px; + left: 0px; + padding-bottom: 0.5em; + font-size: 1.2em; +} + +table.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; +} + + +.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-highlighter-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-point-label { + font-size: 0.75em; +} + +td.jqplot-cursor-legend-swatch { +vertical-align:middle; +text-align:center; +} + +div.jqplot-cursor-legend-swatch { +width:1.2em; +height:0.7em; +} diff --git a/css/jquery-ui.css b/css/jquery-ui.css new file mode 100755 index 0000000000..c7ab34740c --- /dev/null +++ b/css/jquery-ui.css @@ -0,0 +1,383 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial,sans-serif&fwDefault=normal&fsDefault=1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=04_highlight_hard.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=222&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=04_highlight_hard.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=000&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=04_highlight_hard.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=000&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +*/ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Arial,sans-serif; font-size: 1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_highlight-hard_75_e6e6e6_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #222; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #222; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_highlight-hard_75_dadada_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #000; } +.ui-state-hover a, .ui-state-hover a:hover { color: #000; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_highlight-hard_65_ffffff_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #000; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #000; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Button +----------------------------------*/ + +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3em; } +button.ui-button-icons-only { width: 3.2em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.2; } +.ui-button-text-only .ui-button-text { padding: .3em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .3em; text-indent: -9999999px; } +.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .3em 1em .3em 1.8em; } +.ui-button-text-icons .ui-button-text { padding-right: 1.8em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .3em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon .ui-icon-primary, .ui-button-text-icons .ui-icon-primary, .ui-button-icons-only .ui-icon-primary { left: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-button-set { margin-right: 7px; } +.ui-button-set .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ + + +/* Datepicker +----------------------------------*/ +.ui-datepicker { width: 17em; padding: .2em .2em 0; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +} + +/* There must be a better way to do this - Rushabh */ +#ui-datepicker-div { + z-index: 9999; +} \ No newline at end of file diff --git a/css/listing.css b/css/listing.css new file mode 100644 index 0000000000..9deb7942e9 --- /dev/null +++ b/css/listing.css @@ -0,0 +1,56 @@ +/* listing 2.0 */ + +div.listing-more { + margin: 7px 0px 17px 0px; + textAlign: center; + display: none; +} + +div.listing-toolbar { + margin: 7px 0px; +} + +/* SRS */ + +table.srs_result_tab { + border: 2px solid #AAA; + border-collapse: collapse; +} + +/* firefox bug fix for disappering borders */ +table.srs_result_tab td, table.srs_result_tab tr, table.srs_result_tab tbody, table.srs_result_tab div { + position: static; +} + +table.srs_result_tab td { + padding: 3px 2px; + position: static; +} + +div.srs_body_area { +} + +div.srs_results_area { +} + +div.srs_filter_wrapper { + border: 1px solid #CCF; + + background-color: #EEF; + margin:0px 0px 8px 0px; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +div.srs_filter_area { + padding: 8px; +} + +div.srs_filter_area td { + vertical-align: middle; +} + + + diff --git a/css/menus.css b/css/menus.css new file mode 100644 index 0000000000..646a7d61f3 --- /dev/null +++ b/css/menus.css @@ -0,0 +1,51 @@ + +/******** Menus - menu.js ************/ + +ul.menu_toolbar { + z-index: 30; + padding: 0px; + margin: 0px; + margin-top: 1px; +} + +ul.menu_toolbar li { + list-style: none; + margin: 0px; + float: left; +} + +.top_menu { + margin: 0px; + padding: 4px; + cursor: pointer; + color: #FFF; + margin-right: 8px; +} + +.top_menu_mo { + background-color: #000; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.menu_toolbar_dropdown { + position: absolute; + margin-top: 4px; + margin-left: 8px; + width: 140px; + background-color: #FFF; + color: #000; + display: none; + border: 2px solid #333; + z-index: 31; + overflow-y: auto; + overflow-x: hidden; +} + +div.dd_item { + cursor: pointer; + padding: 4px; + background-color: #FFF; +} +div.dd_item_mo { background-color: #FE8; } \ No newline at end of file diff --git a/css/messages.css b/css/messages.css new file mode 100644 index 0000000000..2e1fabe97a --- /dev/null +++ b/css/messages.css @@ -0,0 +1,59 @@ + +/* FLOATING MESSAGE */ + +.btn-img { cursor: pointer; } + +div.fetching { color: #888; text-align:right; } + +div.notice { + postion: absolute; + background-color: #000; + -moz-border-radius: 5px; -webkit-border-radius: 5px; + opacity: 0.6; + right: 0; + top: 0; + margin-top: 8px; + z-index: -1; + padding: 8px; +} + +/** help **/ + +.info-box { + background-color:#eeeef2; + font-size: 12px; + line-height: 1.6em; + color: #335; + padding: 7px; + margin: 11px 0px; + border: 1px solid #c2c2cc; +} + +.help_box, .help-box { + background-color:#FFC; + font-size: 13px; + line-height: 1.6em; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box { + background-color:#FFC; + font-size: 13px; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box_big { + background-color:#FFC; + color: #864; + padding: 7px; + margin: 7px 0px; + border: 1px solid #EEB; + text-align: center; + font-size: 14px; +} \ No newline at end of file diff --git a/css/report.css b/css/report.css new file mode 100644 index 0000000000..333dd3bf7c --- /dev/null +++ b/css/report.css @@ -0,0 +1,180 @@ + +/* Reports */ + +div.report_grid_area { + position: relative; + padding: 8px; +} + + +div.report_tab { + border: 1px solid #AAA; + position: relative; + overflow: auto; +} + +div.report_no_data { + padding: 8px; + background-color: #EEE; + border: 1px solid #DDD; + position: absolute; + margin-left: 40%; + margin-top: 50px; + display: none; +} + +div.report_htitle { + float: left; + padding: 2px; + font-size: 14px; + font-weight: bold; + margin-left: 4px; + color: #665; + /*font-weight: bold;*/ +} + +div.report_tbar { + /*background: url('../images/ui/blue-back.gif') repeat-x; */ + background-color: #EEF; + border: 1px solid #CCF; + border-bottom: 0px; + height: 28px; +} + +div.report_tbar table{ + width: 100%; +} +div.report_tbar table td { + +} +div.report_tbar table td div { + position: relative; +} +div.report_tbar button, div.report_tbar select, div.report_tbar img { + font-size: 11px; + margin: 0px; +} + +div.report_head_wrapper { + position: absolute; + height: 24px; + top: 0px; + z-index: 1; +} + +div.report_tab_wrapper { + position: absolute; + border-bottom: 1px solid #AAA; + border-top: 1px solid #AAA; +} + +div.report_tab_wrapper table, div.report_head_wrapper table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +div.report_tab_wrapper table td, div.report_head_wrapper table td { + border-left: 1px solid #AAA; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + overflow: hidden; + padding: 0px; +} + +div.report_tab_wrapper table td div, div.report_head_wrapper table td div { + padding: 3px; + overflow: hidden; +} + +.report_head_cell { + background-color: #EEE; + border-bottom: 1px solid #AA9; + text-align: center; + font-weight: bold; +} +.report_head_cell div { + color:#222; + height: 18px; +} + + +/* FINDER */ + +div.finder_wrapper { +} + +div.finder_body_area { + margin: 16px; +} + +div.finder_body { + display: none; +} + +div.finder_advanced_area table { + width: 80%; +} + +div.finder_advanced_area textarea { + width: 80%; +} + +div.finder_filter_area { + position: relative; +} + +div.filter_head { + font-size: 14px; + margin-bottom: 2px; +} +div.filter_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} +table.filter_tab { + width: 96%; + border-collapse: collapse; +} + +table.filter_tab td { + width: 50%; +} + +div.finder_picker_area { + +} +div.builder_field { + margin: 0px; +} +div.builder_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} + +div.builder_field table { + width: 90%; + border-collapse: collapse; +} + +div.builder_label { + height: 20px; +} + +div.builder_head { + font-size: 16px; + font-weight: bold; + color: #AB6; +} + +table.builder_tab { + width: 96%; + border-collapse: collapse; +} + +table.builder_tab td { + width: 33%; + padding: 2px; +} \ No newline at end of file diff --git a/css/sidebar.css b/css/sidebar.css new file mode 100644 index 0000000000..493935d8f0 --- /dev/null +++ b/css/sidebar.css @@ -0,0 +1,44 @@ +div.psidebar-wrapper { + margin: 0px 8px; +} + +div.psidebar-head { + font-size: 14px; + font-weight: bold; + color: #555; + margin-bottom: 12px; +} + +div.psidebar-section { + background-color: #f7f7f5; + border: 2px solid #b2b2b7; + margin-bottom: 11px; +} + +div.psidebar-section-head { + font-weight: bold; + font-size: 13px; + color: #222; + background-color: #d8d8d4; + margin-bottom: 7px; + padding: 3px 11px; +} + +div.psidebar-section-body { + margin: 7px 11px 11px 11px; +} + +div.psidebar-section-item { + margin-bottom: 7px; +} + +.psidebar-section-link { + font-size: 11px; + color: #666; +} + +div.follower-list { + color: #666; + margin-top: 7px; + font-size: 11px; +} \ No newline at end of file diff --git a/css/tabs.css b/css/tabs.css new file mode 100644 index 0000000000..9ae6da7850 --- /dev/null +++ b/css/tabs.css @@ -0,0 +1,58 @@ + +/******* TABS ********/ + +div.box_label_wrapper { + border-bottom: 6px solid #777; +} + +div.box_label_body { + height: 22px; +} + +ul.box_tabs { + margin: 0px; + padding: 0px; + list-style: none; +} + +ul.box_tabs li { + height: 22px; + float:left; + font-size: 12px; + text-decoration: underline; + + background-color: #DDD; + + margin:0; + margin-left: 4px; + padding:0 0 0 9px; + cursor: pointer; +} + +ul.box_tabs a { + display:block; + padding:3px 15px 3px 6px; + text-decoration:none; +} + +ul.box_tabs li.box_tab_mouseover { + background-color: #BBB; +} + + +ul.box_tabs li.box_tab_selected { +/* background:url("../images/ui/rc/tab-left-CCC.gif") no-repeat left top; + background-color: #ABABAB; */ + + background-color: #777; + + background: -webkit-gradient(linear, left top, left bottom, from(#999), to(#777)); + background: -moz-linear-gradient(top, #999, #777); + + color: #FFF; + font-weight:bold; + +} +ul.box_tabs li.box_tab_selected a { +/* background:url("../images/ui/rc/tab-right-CCC.gif") no-repeat right top; */ +} diff --git a/css/user.css b/css/user.css new file mode 100644 index 0000000000..17d7e1088b --- /dev/null +++ b/css/user.css @@ -0,0 +1 @@ +/* User CSS */ \ No newline at end of file diff --git a/css/wntoolbar.css b/css/wntoolbar.css new file mode 100644 index 0000000000..163943a6d9 --- /dev/null +++ b/css/wntoolbar.css @@ -0,0 +1,47 @@ + +/* Recent */ + +div.recent_starred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star.gif'); +} + +div.recent_unstarred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star_plain.gif'); +} + +div.status_flag { + width: 8px; + height: 8px; + margin: 4px; + font-size: 0px; + background-color: #EEE; +} + + + + + +/* Search */ + +.search_table td { + padding: 2px; +} + + + + +/*** for wn toolbar ***/ +.wntoolbar-icon { background: url('../images/icons/wntoolbar-icons.png'); width: 16px; height: 16px; } +.sprite-home { background-position: 0 0; } +.sprite-new { background-position: 0 -66px; } +.sprite-pages { background-position: 0 -132px; } +.sprite-recent { background-position: 0 -198px; } +.sprite-report { background-position: 0 -264px; } +.sprite-search { background-position: 0 -330px; } +.sprite-tools { background-position: 0 -396px; } \ No newline at end of file diff --git a/data/Framework.sql b/data/Framework.sql new file mode 100644 index 0000000000..27faa19913 --- /dev/null +++ b/data/Framework.sql @@ -0,0 +1,245 @@ +-- Core Elements to install WNFramework +-- To be called from install.py + + +-- +-- Table structure for table `__DocTypeCache` +-- + +DROP TABLE IF EXISTS `__DocTypeCache`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `__DocTypeCache` ( + `name` varchar(120) DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `content` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `__SessionCache` +-- + +DROP TABLE IF EXISTS `__SessionCache`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `__SessionCache` ( + `user` varchar(120) DEFAULT NULL, + `country` varchar(120) DEFAULT NULL, + `cache` longtext +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + + +-- +-- Table structure for table `tabDocField` +-- + +DROP TABLE IF EXISTS `tabDocField`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocField` ( + `name` varchar(120) NOT NULL, + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(40) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `fieldname` varchar(180) DEFAULT NULL, + `label` varchar(180) DEFAULT NULL, + `oldfieldname` varchar(180) DEFAULT NULL, + `fieldtype` varchar(180) DEFAULT NULL, + `oldfieldtype` varchar(180) DEFAULT NULL, + `options` text, + `search_index` int(3) DEFAULT NULL, + `hidden` int(3) DEFAULT NULL, + `print_hide` int(3) DEFAULT NULL, + `report_hide` int(3) DEFAULT NULL, + `reqd` int(3) DEFAULT NULL, + `no_copy` int(3) DEFAULT NULL, + `allow_on_submit` int(3) DEFAULT NULL, + `trigger` varchar(180) DEFAULT NULL, + `depends_on` varchar(180) DEFAULT NULL, + `permlevel` int(3) DEFAULT NULL, + `width` varchar(180) DEFAULT NULL, + `default` text, + `description` text, + `colour` varchar(180) DEFAULT NULL, + `icon` varchar(180) DEFAULT NULL, + `in_filter` int(3) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`), + KEY `label` (`label`), + KEY `fieldtype` (`fieldtype`), + KEY `fieldname` (`fieldname`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabDocFormat` +-- + +DROP TABLE IF EXISTS `tabDocFormat`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocFormat` ( + `name` varchar(120) NOT NULL, + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(40) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `format` varchar(180) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabDocPerm` +-- + +DROP TABLE IF EXISTS `tabDocPerm`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocPerm` ( + `name` varchar(120) NOT NULL, + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(40) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `permlevel` int(11) DEFAULT NULL, + `role` varchar(180) DEFAULT NULL, + `match` varchar(180) DEFAULT NULL, + `read` int(3) DEFAULT NULL, + `write` int(3) DEFAULT NULL, + `create` int(3) DEFAULT NULL, + `submit` int(3) DEFAULT NULL, + `cancel` int(3) DEFAULT NULL, + `amend` int(3) DEFAULT NULL, + `execute` int(3) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabDocType` +-- + +DROP TABLE IF EXISTS `tabDocType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocType` ( + `name` varchar(180) NOT NULL DEFAULT '', + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(180) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `search_fields` varchar(180) DEFAULT NULL, + `issingle` int(1) DEFAULT NULL, + `istable` int(1) DEFAULT NULL, + `version` int(11) DEFAULT NULL, + `module` varchar(180) DEFAULT NULL, + `autoname` varchar(180) DEFAULT NULL, + `name_case` varchar(180) DEFAULT NULL, + `description` text, + `colour` varchar(180) DEFAULT NULL, + `read_only` int(1) DEFAULT NULL, + `in_create` int(1) DEFAULT NULL, + `show_in_menu` int(3) DEFAULT NULL, + `menu_index` int(11) DEFAULT NULL, + `parent_node` varchar(180) DEFAULT NULL, + `smallicon` varchar(180) DEFAULT NULL, + `allow_print` int(1) DEFAULT NULL, + `allow_email` int(1) DEFAULT NULL, + `allow_copy` int(1) DEFAULT NULL, + `allow_rename` int(1) DEFAULT NULL, + `hide_toolbar` int(1) DEFAULT NULL, + `hide_heading` int(1) DEFAULT NULL, + `allow_attach` int(1) DEFAULT NULL, + `use_template` int(1) DEFAULT NULL, + `max_attachments` int(11) DEFAULT NULL, + `section_style` varchar(180) DEFAULT NULL, + `client_script` text, + `client_script_core` text, + `server_code` text, + `server_code_core` text, + `server_code_compiled` text, + `client_string` text, + `server_code_error` varchar(180) DEFAULT NULL, + `print_outline` varchar(180) DEFAULT NULL, + `dt_template` text, + `is_transaction_doc` int(1) DEFAULT NULL, + `change_log` text, + `read_only_onload` int(1) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabSeries` +-- + +DROP TABLE IF EXISTS `tabSeries`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabSeries` ( + `name` varchar(40) DEFAULT NULL, + `current` int(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + +-- +-- Table structure for table `tabSessions` +-- + +DROP TABLE IF EXISTS `tabSessions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +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 +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + +-- +-- Table structure for table `tabSingles` +-- + +DROP TABLE IF EXISTS `tabSingles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabSingles` ( + `doctype` varchar(40) DEFAULT NULL, + `field` varchar(40) DEFAULT NULL, + `value` text, + KEY `doctype` (`doctype`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + diff --git a/data/GeoIP.dat b/data/GeoIP.dat new file mode 100644 index 0000000000..7f504a0c51 Binary files /dev/null and b/data/GeoIP.dat differ diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo new file mode 100644 index 0000000000..26f3845796 --- /dev/null +++ b/docs/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 613316d300d09679d4b613ea92bf496e +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/docs/html/_sources/admin_login.txt b/docs/html/_sources/admin_login.txt new file mode 100644 index 0000000000..6d209e940d --- /dev/null +++ b/docs/html/_sources/admin_login.txt @@ -0,0 +1,10 @@ +Administrator Login +=================== + +An application is built via the browser front end. To have the right access to build applications, you must +login as an Administrator. + +If you are in a new system that does not have any application, your first login as "Administrator" is the +Administrator login. + + diff --git a/docs/html/_sources/apps_intro.txt b/docs/html/_sources/apps_intro.txt new file mode 100644 index 0000000000..a4fc06a6bb --- /dev/null +++ b/docs/html/_sources/apps_intro.txt @@ -0,0 +1,98 @@ +Using the Administrator Interface +================================= + +Applications are built using the web based administrator interface of the framework. + +Let us start discuss how to build applications using the basic building blocks + +What is an Application? +----------------------- + +Let us define a typical web application as being a set of: + + #. Users - who use the application + #. Roles - roles assigned to users for various functions + #. Pages - where users navigate and see relevant information + #. Forms - where users enter new data + #. Reports - where users get a tabulated view of their data + #. Permission Rules - that define what each role is allowed to do or not do + #. Logic - Automatic actions that are performed at various events + #. Validations - Checks that ensure the data entered by the users is valid + #. Print Formats - Printable documents based on the data users have entered + #. UI Widgets - Menus, Lists, Dialogs that are used for navigating, entering or displaying information + #. Module - So that you can group Roles, Forms, Pages, Reports for more complex applications + +Let us now start building these entities in the wnframework + +Administrator Login +------------------- + +An application is built via the browser front end. To have the right access to build applications, you must +login as an Administrator. + +If you are in a new system that does not have any application, your first login as "Administrator" is the +Administrator login. + +Creating Entities +----------------- + +To create any entity, you must have the relevant permission. Once you have the relevant permission, you can +create new entities from the top toolbar. + +Look out for the "New" button on the top left of the page. Via the "New" dialog box, you can create any +entity you have rights to create. + +.. note:: + + * Entities in wnframework are known by their "name". Name has the same concept as id - its a unique key + for that entity (same as a Primary Key). + * Every entity also has an "owner" - By default this is the user who creates that entity. + +Managing Roles +--------------- + +Roles are assigned to users so that you can define a group of users and set permission (or other) rules. + + #. To create a new role, click "New" on the top toolbar and select "Role" + #. Give the Role name, use descriptive names here like - "Contact Manager" + #. Set the module, (use the standard; if you want create a new module, go ahead!) + #. Click on the green "Save" button + +Your new Roles is created! To check, click on the "Search" button on the top toolbar and select "Role" +Click on "Search" and see that your new Role is added to the list of already existing roles: + +.. note:: + + Pre-defined roles. There are 3 basic roles that are pre-defined in the system. It is suggested, + you leave them as it is! + + #. Administrator: Role given to the application builder / maintainer + #. All: All logged in users have the role "All" + #. Guest: Users who are not yet logged in. + +Creating Users (Profile) +------------------------ + +A Profile (=user) has a unique identity in the system and can be tagged as an "onwer" to a data record. +Profiles can also be assigned Roles that restrict what they can do. You can also define custom logic +for a Profile + +To create a new Profile: + + #. Create a new Profile via "New" on the top toolbar + #. Enter the mandatory "First Name" and "Email" values + #. "Save" the profile via the "Save" button + #. The user will be sent an email with her random-genereated password. You can also set a custom password + by clicking on the "Password" tab and setting the password. + #. *To assign a role, click on the "Roles" tab and add a "Role" in the table.* + +Once a Profile is created, the user can login with the login id (email) and password. + +.. note:: + + Profiles are given an id that is the same as their email id. Why did we do this? + + * Email Ids are good unique identifiers. Your users may have the same first and last names, + but they would have separate Email Ids + * People usually remember their email ids + * Email Ids are these days the de-facto way to define login-ids diff --git a/docs/html/_sources/auth.txt b/docs/html/_sources/auth.txt new file mode 100644 index 0000000000..c5df2fec59 --- /dev/null +++ b/docs/html/_sources/auth.txt @@ -0,0 +1,104 @@ +:mod:`auth` --- Authentication +============================== + +.. module:: auth + :synopsis: Authentication module + +Authentication object +--------------------- + +.. class:: Authentication(self, form, in_cookies, out_cookies, out) + + A new Authenticate object is created at the beginning of any request. It will manage login, session and + cookies. :method:`update` must be called at the end of the request to update cookies and + session. + + The constructor will also set the global `webnotes.conn`, `webnotes.session` and `webnotes.user` + + To enable a login, the :object:form must have a cmd = "login" (see request handling for more details) + + .. attribute:: conn + + `webnotes.db.Database` object created after authentication + + .. attribute:: session + + session dictionary of the current session + + .. attribute:: cookies + + session dictionary of incoming cookies + + .. attribute:: domain + + domain name of the request + + .. attribute:: remote_ip + + IP address of the reqeust + + .. method:: update() + + **Must be called at the end of the request, to update the session and clear expired sessions** + + .. method:: set_env() + + Sets the properties `domain` and `remote_ip` from the environmental variables + + .. method:: set_db() + + In case of a multi-database system, this methods sets the correct database connection. + + * It will first search for cookie `account_id` + * It will next search for cookies or form variable `__account` + * It will try and search from the domain mapping table `Account Domain` in the `accounts` database + * It will try and use the default + + .. method:: check_ip() + + If the current request is from a separate IP than the one which was used to create the session, then + this throws an Exception + + .. method:: load_session(sid) + + Load session from the given session id `sid` + + .. method:: login(as_guest = 0) + + Will login user from `self.form`. If as_guest is true, it will check if Guest profile is enabled + + It will also: + + * validate if approved ips are set in `Profile` + * start the session + * set "remember me" + * return out.message as "Logged In" + + .. method:: check_password(user, pwd) + + Checks if the user has the pwd and is enabled + + .. method:: validate_ip(user) + + Validates IP address from the ip_address value in the user's `Profile` + + .. method:: start_session() + + Starts a session, and updates last login details in the users's `Profile` + + .. method:: clear_expired() + + Removes old sessions from `tabSessions` that are older than `session_expiry` in `Control Panel` or 24:00 hrs + + .. method:: set_cookies() + + Sets outgoing cookies + + .. method:: set_remember_me() + + Checks if there is a 'remember_me' property in `form` with a value and if true, its sets the + expiry of each cookie for `remember_for_days` in `Control Panel` or 7 days + + .. method:: get_cookies() + + Loads incoming cookies in `cookies` diff --git a/docs/html/_sources/autosuggest.txt b/docs/html/_sources/autosuggest.txt new file mode 100644 index 0000000000..dff5a7af44 --- /dev/null +++ b/docs/html/_sources/autosuggest.txt @@ -0,0 +1,62 @@ +Autosuggest +=========== + +Adapted from: Timothy Groves - http://www.brandspankingnew.net + +.. data:: cur_autosug + + Live Autosuggest object + +.. function:: hide_autosuggest() + + Hide the Live Autosuggest (if exists) + +.. class:: AutoSuggest(id, param) + + Create a new autosuggest object + +Overriding the default call +--------------------------- + +* To override the default server call, override the method `doAjaxRequest` +* To override updation in the INPUT element, override the method `custom_select` + +Example +------- + +Example where email id is to be retrieved:: + + // ---- add auto suggest ---- + var opts = { script: '', json: true, maxresults: 10 }; + + var as = new AutoSuggest(d.widgets['To'], opts); + as.custom_select = function(txt, sel) { + // ---- add to the last comma ---- + var r = ''; + var tl = txt.split(','); + for(var i=0;i
    \u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlight'); + }); + }, 10); + $('
  2. ') + .appendTo($('.sidebar .this-page-menu')); + } + }, + + /** + * init the modindex toggle buttons + */ + initModIndex : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + console.log($('tr.cg-' + idnum).toggle()); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('.sidebar .this-page-menu li.highlight-link').fadeOut(300); + $('span.highlight').removeClass('highlight'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/_static/file.png b/docs/html/_static/file.png new file mode 100644 index 0000000000..d18082e397 Binary files /dev/null and b/docs/html/_static/file.png differ diff --git a/docs/html/_static/jquery.js b/docs/html/_static/jquery.js new file mode 100644 index 0000000000..82b98e1d76 --- /dev/null +++ b/docs/html/_static/jquery.js @@ -0,0 +1,32 @@ +/* + * jQuery 1.2.6 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ + * $Rev: 5685 $ + */ +(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else +while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); \ No newline at end of file diff --git a/docs/html/_static/minus.png b/docs/html/_static/minus.png new file mode 100644 index 0000000000..da1c5620d1 Binary files /dev/null and b/docs/html/_static/minus.png differ diff --git a/docs/html/_static/navigation.png b/docs/html/_static/navigation.png new file mode 100644 index 0000000000..1081dc1439 Binary files /dev/null and b/docs/html/_static/navigation.png differ diff --git a/docs/html/_static/plus.png b/docs/html/_static/plus.png new file mode 100644 index 0000000000..b3cb37425e Binary files /dev/null and b/docs/html/_static/plus.png differ diff --git a/docs/html/_static/pygments.css b/docs/html/_static/pygments.css new file mode 100644 index 0000000000..1f2d2b6187 --- /dev/null +++ b/docs/html/_static/pygments.css @@ -0,0 +1,61 @@ +.hll { background-color: #ffffcc } +.c { color: #408090; font-style: italic } /* Comment */ +.err { border: 1px solid #FF0000 } /* Error */ +.k { color: #007020; font-weight: bold } /* Keyword */ +.o { color: #666666 } /* Operator */ +.cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.cp { color: #007020 } /* Comment.Preproc */ +.c1 { color: #408090; font-style: italic } /* Comment.Single */ +.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #FF0000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #00A000 } /* Generic.Inserted */ +.go { color: #303030 } /* Generic.Output */ +.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #0040D0 } /* Generic.Traceback */ +.kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #007020 } /* Keyword.Pseudo */ +.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #902000 } /* Keyword.Type */ +.m { color: #208050 } /* Literal.Number */ +.s { color: #4070a0 } /* Literal.String */ +.na { color: #4070a0 } /* Name.Attribute */ +.nb { color: #007020 } /* Name.Builtin */ +.nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.no { color: #60add5 } /* Name.Constant */ +.nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.ne { color: #007020 } /* Name.Exception */ +.nf { color: #06287e } /* Name.Function */ +.nl { color: #002070; font-weight: bold } /* Name.Label */ +.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.nt { color: #062873; font-weight: bold } /* Name.Tag */ +.nv { color: #bb60d5 } /* Name.Variable */ +.ow { color: #007020; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mf { color: #208050 } /* Literal.Number.Float */ +.mh { color: #208050 } /* Literal.Number.Hex */ +.mi { color: #208050 } /* Literal.Number.Integer */ +.mo { color: #208050 } /* Literal.Number.Oct */ +.sb { color: #4070a0 } /* Literal.String.Backtick */ +.sc { color: #4070a0 } /* Literal.String.Char */ +.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #4070a0 } /* Literal.String.Double */ +.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #4070a0 } /* Literal.String.Heredoc */ +.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.sx { color: #c65d09 } /* Literal.String.Other */ +.sr { color: #235388 } /* Literal.String.Regex */ +.s1 { color: #4070a0 } /* Literal.String.Single */ +.ss { color: #517918 } /* Literal.String.Symbol */ +.bp { color: #007020 } /* Name.Builtin.Pseudo */ +.vc { color: #bb60d5 } /* Name.Variable.Class */ +.vg { color: #bb60d5 } /* Name.Variable.Global */ +.vi { color: #bb60d5 } /* Name.Variable.Instance */ +.il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/html/_static/searchtools.js b/docs/html/_static/searchtools.js new file mode 100644 index 0000000000..e0226258a5 --- /dev/null +++ b/docs/html/_static/searchtools.js @@ -0,0 +1,467 @@ +/** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + +jQuery.makeSearchSummary = function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
    ').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlight'); + }); + return rv; +} + +/** + * Porter Stemmer + */ +var PorterStemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + /** + * Sets the index + */ + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (var i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

    ' + _('Searching') + '

    ').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

    ').appendTo(this.out); + this.output = $('
    ';c.cur_label=label;break;}}} +_f.FormGrid.prototype.refresh=function(){var docset=getchildren(this.doctype,this.field.frm.docname,this.field.df.fieldname,this.field.frm.doctype);var data=[];for(var i=0;i*';r.is_newrow=true;} +_f.FormGrid.prototype.check_selected=function(){if(!_f.cur_grid_cell){show_alert('Select a cell first');return false;} +if(_f.cur_grid_cell.grid!=this){show_alert('Select a cell first');return false;} +return true;} +_f.FormGrid.prototype.delete_row=function(dt,dn){if(dt&&dn){LocalDB.delete_record(dt,dn);this.refresh();}else{if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;var ci=_f.cur_grid_cell.cellIndex;var ri=_f.cur_grid_cell.row.rowIndex;LocalDB.delete_record(this.doctype,r.docname);this.refresh();if(ri<(this.tab.rows.length-2)) +this.cell_select(null,ri,ci);else _f.cur_grid_cell=null;} +this.set_unsaved();} +_f.FormGrid.prototype.move_row=function(up){if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;if(up&&r.rowIndex>0){var swap_row=this.tab.rows[r.rowIndex-1];}else if(!up){var len=this.tab.rows.length;if(this.tab.rows[len-1].is_newrow) +len=len-1;if(r.rowIndex<(len-1)) +var swap_row=this.tab.rows[r.rowIndex+1];} +if(swap_row){var cidx=_f.cur_grid_cell.cellIndex;this.cell_deselect();var aidx=locals[this.doctype][r.docname].idx;locals[this.doctype][r.docname].idx=locals[this.doctype][swap_row.docname].idx;locals[this.doctype][swap_row.docname].idx=aidx;var adocname=swap_row.docname;this.refresh_row(swap_row.rowIndex,r.docname);this.refresh_row(r.rowIndex,adocname);this.cell_select(this.tab.rows[swap_row.rowIndex].cells[cidx]);this.set_unsaved();}} +_p.show_dialog=function(){if(!_p.dialog){_p.make_dialog();} +_p.dialog.show();} +_p.make_dialog=function(){var d=new Dialog(360,140,"Print Formats");d.make_body([['HTML','Select'],['Check','No Letterhead','Will ignore letterhead if it can be set. May not work for all formats'],['HTML','Buttons']]);d.widgets['No Letterhead'].checked=1;$btn(d.widgets.Buttons,'Print',function(){_p.build(sel_val(cur_frm.print_sel),_p.go,d.widgets['No Letterhead'].checked);},{cssFloat:'right',marginBottom:'16px',marginLeft:'7px'},'green');$btn(d.widgets.Buttons,'Preview',function(){_p.build(sel_val(cur_frm.print_sel),_p.preview,d.widgets['No Letterhead'].checked);},{cssFloat:'right',marginBottom:'16px'},'');_p.dialog=d;d.onshow=function(){var c=d.widgets['Select'];if(c.cur_sel&&c.cur_sel.parentNode==c) +c.removeChild(c.cur_sel);c.appendChild(cur_frm.print_sel);c.cur_sel=cur_frm.print_sel;}} +_p.field_tab=function(layout_cell){var t=$a(layout_cell,'table','',{width:'100%'});var r=t.insertRow(0);this.r=r;r.insertCell(0);r.insertCell(1);r.cells[0].className='datalabelcell';r.cells[1].className='datainputcell';return r} +_p.print_std_add_table=function(t,layout,pf_list,dt,no_letterhead){if(t.appendChild){layout.cur_cell.appendChild(t);}else{for(var ti=0;ti';layout=_p.add_layout(dt,no_letterhead);pf_list[pf_list.length]=layout;layout.addrow();layout.addcell();var div=$a(layout.cur_cell,'div');div.innerHTML='Continued from previous page...';div.style.padding='4px';} +layout.cur_cell.appendChild(t[t.length-1]);} +return layout;} +_p.print_std_add_field=function(dt,dn,f,layout){var v=_f.get_value(dt,dn,f.fieldname);if(f.fieldtype!="Button"){if(!v&&!in_list(['Float','Int','Currency'],f.fieldtype)){}else{r=_p.field_tab(layout.cur_cell) +r.cells[0].innerHTML=f.label?f.label:f.fieldname;$s(r.cells[1],v,f.fieldtype);if(f.fieldtype=='Currency') +$y(r.cells[1],{textAlign:'left'});}}} +_p.get_letter_head=function(){var cp=locals['Control Panel']['Control Panel'];if(cur_frm.doc.letter_head) +var lh=cstr(_p.letter_heads[cur_frm.doc.letter_head]);else if(cp.letter_head) +var lh=cp.letter_head;else +var lh='';return lh;} +_p.add_layout=function(dt,no_letterhead){var l=new Layout();l.addrow();if(locals['DocType'][dt].print_outline=='Yes')l.with_border=1;return l;} +_p.print_std=function(no_letterhead){var dn=cur_frm.docname;var dt=cur_frm.doctype;var pf_list=[];var layout=_p.add_layout(dt,no_letterhead);pf_list[pf_list.length]=layout;var h1=$a(layout.cur_row.header,'h1','',{fontSize:'22px',marginBottom:'8px'});h1.innerHTML=cur_frm.pformat[dn]?cur_frm.pformat[dn]:get_doctype_label(dt);var h2=$a(layout.cur_row.header,'div','',{fontSize:'16px',color:'#888',marginBottom:'8px',paddingBottom:'8px',borderBottom:(layout.with_border?'0px':'1px solid #000')});h2.innerHTML=dn;var fl=getchildren('DocField',dt,'fields','DocType');if(fl[0]&&fl[0].fieldtype!="Section Break"){layout.addrow();if(fl[0].fieldtype!="Column Break") +layout.addcell();} +for(var i=0;i'+f.label+': '+'
    '+(v?v:'')+'
    ';break;case'Text Editor':var tmp=$a(layout.cur_cell,'div');var v=_f.get_value(dt,dn,f.fieldname);tmp.innerHTML=v?v:'';break;default:_p.print_std_add_field(dt,dn,f,layout);}}}} +layout.close_borders();var html='';for(var i=0;i0){for(var i=0;i'+block.innerHTML;} +if(only_body){return tmp_html+block.innerHTML.replace(/\n' ++'' ++''+title+'' ++'' ++'' ++tmp_html ++block.innerHTML.replace(/';}} +print_table=function(dt,dn,fieldname,tabletype,cols,head_labels,widths,condition,cssClass){var fl=fields_list[tabletype];var ds=getchildren(tabletype,dn,fieldname,dt);var tl=[];var cell_style={border:'1px solid #000',padding:'2px',verticalAlign:'top'};var head_cell_style={border:'1px solid #000',padding:'2px',verticalAlign:'top',backgroundColor:'#ddd'};var make_table=function(fl){var w=document.createElement('div');var t=$a(w,'table','',{width:'100%',borderCollapse:'collapse',marginBottom:'10px'});t.wrapper=w;t.insertRow(0);var c_start=0;if(fl[0]=='SR'){var cell=t.rows[0].insertCell(0) +cell.innerHTML=head_labels?head_labels[0]:'Sr';$y(cell,{width:'30px'});$y(cell,head_cell_style) +c_start=1;} +for(var c=c_start;c1)return tl;else return tl[0];} +_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) +emailfrom=user_email;var email_list=emailto.split(/[,|;]/);var valid=1;for(var i=0;i12){time=(parseInt(hr)-12)+':'+min+' PM'} +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();})}}} +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},icon:'ic-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!me.form.doc.__islocal},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:'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:'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}},{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}}]} +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();}}}} +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.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] +this.msg=$a(this.wrapper,'div','sidebar-comment-message');if(cl){this.msg.innerHTML=cl.length+' out of '+f.n_comments[me.docname]+' comments';if(f.n_comments[me.docname]>cl.length){this.msg.innerHTML+=' Show all'} +for(var i=0;i1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}function F(j){var ae,Z=1;j=String(j);if(j.charAt(0)=="#"){ae=j}else{if(/^rgb/.test(j)){var p=M(j);var ae="#",af;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){af=Math.floor(c(p[m])*255)}else{af=Number(p[m])}ae+=n[u(af,0,255)]}Z=p[3]}else{if(/^hsl/.test(j)){var p=M(j);ae=I(p);Z=p[3]}else{ae=b[j]||j}}}return{color:ae,alpha:Z}}var r={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||r.style,variant:m.fontVariant||r.variant,weight:m.fontWeight||r.weight,size:m.fontSize||r.size,family:m.fontFamily||r.family}}function w(m,j){var i={};for(var af in m){i[af]=m[af]}var ae=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ae*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ae/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=ae*(4/3)*Z}else{i.size=ae}}}}}i.size*=0.981;return i}function aa(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}function S(i){switch(i){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function D(j){this.m_=C();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=j;var i=j.ownerDocument.createElement("div");i.style.width=j.clientWidth+"px";i.style.height=j.clientHeight+"px";i.style.overflow="hidden";i.style.position="absolute";j.appendChild(i);this.element_=i;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var t=D.prototype;t.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};t.beginPath=function(){this.currentPath_=[]};t.moveTo=function(j,i){var m=this.getCoords_(j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};t.lineTo=function(j,i){var m=this.getCoords_(j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};t.bezierCurveTo=function(m,j,ai,ah,ag,ae){var i=this.getCoords_(ag,ae);var af=this.getCoords_(m,j);var Z=this.getCoords_(ai,ah);K(this,af,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}t.quadraticCurveTo=function(ag,m,j,i){var af=this.getCoords_(ag,m);var ae=this.getCoords_(j,i);var ah={x:this.currentX_+2/3*(af.x-this.currentX_),y:this.currentY_+2/3*(af.y-this.currentY_)};var Z={x:ah.x+(ae.x-this.currentX_)/3,y:ah.y+(ae.y-this.currentY_)/3};K(this,ah,Z,ae)};t.arc=function(aj,ah,ai,ae,j,m){ai*=d;var an=m?"at":"wa";var ak=aj+B(ae)*ai-f;var am=ah+o(ae)*ai-f;var i=aj+B(j)*ai-f;var al=ah+o(j)*ai-f;if(ak==i&&!m){ak+=0.125}var Z=this.getCoords_(aj,ah);var ag=this.getCoords_(ak,am);var af=this.getCoords_(i,al);this.currentPath_.push({type:an,x:Z.x,y:Z.y,radius:ai,xStart:ag.x,yStart:ag.y,xEnd:af.x,yEnd:af.y})};t.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};t.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};t.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};t.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};t.createRadialGradient=function(p,ae,m,j,Z,i){var af=new U("gradientradial");af.x0_=p;af.y0_=ae;af.r0_=m;af.x1_=j;af.y1_=Z;af.r1_=i;return af};t.drawImage=function(ao,m){var ah,af,aj,aw,am,ak,aq,ay;var ai=ao.runtimeStyle.width;var an=ao.runtimeStyle.height;ao.runtimeStyle.width="auto";ao.runtimeStyle.height="auto";var ag=ao.width;var au=ao.height;ao.runtimeStyle.width=ai;ao.runtimeStyle.height=an;if(arguments.length==3){ah=arguments[1];af=arguments[2];am=ak=0;aq=aj=ag;ay=aw=au}else{if(arguments.length==5){ah=arguments[1];af=arguments[2];aj=arguments[3];aw=arguments[4];am=ak=0;aq=ag;ay=au}else{if(arguments.length==9){am=arguments[1];ak=arguments[2];aq=arguments[3];ay=arguments[4];ah=arguments[5];af=arguments[6];aj=arguments[7];aw=arguments[8]}else{throw Error("Invalid number of arguments")}}}var ax=this.getCoords_(ah,af);var p=aq/2;var j=ay/2;var av=[];var i=10;var ae=10;av.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",av.join(""))};t.stroke=function(aj){var ah=[];var Z=false;var m=10;var ak=10;ah.push("ai.x){ai.x=j.x}if(ae.y==null||j.yai.y){ai.y=j.y}}}ah.push(' ">');if(!aj){y(this,ah)}else{G(this,ah,ae,ai)}ah.push("");this.element_.insertAdjacentHTML("beforeEnd",ah.join(""))};function y(m,ae){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ae.push("')}function G(ao,ag,aI,ap){var ah=ao.fillStyle;var az=ao.arcScaleX_;var ay=ao.arcScaleY_;var j=ap.x-aI.x;var p=ap.y-aI.y;if(ah instanceof U){var al=0;var aD={x:0,y:0};var av=0;var ak=1;if(ah.type_=="gradient"){var aj=ah.x0_/az;var m=ah.y0_/ay;var ai=ah.x1_/az;var aK=ah.y1_/ay;var aH=ao.getCoords_(aj,m);var aG=ao.getCoords_(ai,aK);var ae=aG.x-aH.x;var Z=aG.y-aH.y;al=Math.atan2(ae,Z)*180/Math.PI;if(al<0){al+=360}if(al<0.000001){al=0}}else{var aH=ao.getCoords_(ah.x0_,ah.y0_);aD={x:(aH.x-aI.x)/j,y:(aH.y-aI.y)/p};j/=az*d;p/=ay*d;var aB=Y.max(j,p);av=2*ah.r0_/aB;ak=2*ah.r1_/aB-av}var at=ah.colors_;at.sort(function(aL,i){return aL.offset-i.offset});var an=at.length;var ar=at[0].color;var aq=at[an-1].color;var ax=at[0].alpha*ao.globalAlpha;var aw=at[an-1].alpha*ao.globalAlpha;var aC=[];for(var aF=0;aF')}else{if(ah instanceof T){if(j&&p){var af=-aI.x;var aA=-aI.y;ag.push("')}}else{var aJ=F(ao.fillStyle);var au=aJ.color;var aE=aJ.alpha*ao.globalAlpha;ag.push('')}}}t.fill=function(){this.stroke(true)};t.closePath=function(){this.currentPath_.push({type:"close"})};t.getCoords_=function(p,j){var i=this.m_;return{x:d*(p*i[0][0]+j*i[1][0]+i[2][0])-f,y:d*(p*i[0][1]+j*i[1][1]+i[2][1])-f}};t.save=function(){var i={};x(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(C(),this.m_)};t.restore=function(){if(this.aStack_.length){x(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function k(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function X(j,i,p){if(!k(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}t.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];X(this,J(i,this.m_),false)};t.rotate=function(j){var p=B(j);var m=o(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];X(this,J(i,this.m_),false)};t.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];X(this,J(i,this.m_),true)};t.transform=function(Z,p,af,ae,j,i){var m=[[Z,p,0],[af,ae,0],[j,i,1]];X(this,J(m,this.m_),true)};t.setTransform=function(ae,Z,ag,af,p,j){var i=[[ae,Z,0],[ag,af,0],[p,j,1]];X(this,i,true)};t.drawText_=function(ak,ai,ah,an,ag){var am=this.m_,aq=1000,j=0,ap=aq,af={x:0,y:0},ae=[];var i=w(E(this.font),this.element_);var p=aa(i);var ar=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=ar.direction=="ltr"?"right":"left";break;case"start":Z=ar.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":af.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":af.y=-i.size/2.25;break}switch(Z){case"right":j=aq;ap=0.05;break;case"center":j=ap=aq/2;break}var ao=this.getCoords_(ai+af.x,ah+af.y);ae.push('');if(ag){y(this,ae)}else{G(this,ae,{x:-j,y:0},{x:ap,y:i.size})}var al=am[0][0].toFixed(3)+","+am[1][0].toFixed(3)+","+am[0][1].toFixed(3)+","+am[1][1].toFixed(3)+",0,0";var aj=q(ao.x/d)+","+q(ao.y/d);ae.push('','','');this.element_.insertAdjacentHTML("beforeEnd",ae.join(""))};t.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};t.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};t.measureText=function(m){if(!this.textMeasureEl_){var i='';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};t.clip=function(){};t.arcTo=function(){};t.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var W=P.prototype=new Error;W.INDEX_SIZE_ERR=1;W.DOMSTRING_SIZE_ERR=2;W.HIERARCHY_REQUEST_ERR=3;W.WRONG_DOCUMENT_ERR=4;W.INVALID_CHARACTER_ERR=5;W.NO_DATA_ALLOWED_ERR=6;W.NO_MODIFICATION_ALLOWED_ERR=7;W.NOT_FOUND_ERR=8;W.NOT_SUPPORTED_ERR=9;W.INUSE_ATTRIBUTE_ERR=10;W.INVALID_STATE_ERR=11;W.SYNTAX_ERR=12;W.INVALID_MODIFICATION_ERR=13;W.NAMESPACE_ERR=14;W.INVALID_ACCESS_ERR=15;W.VALIDATION_ERR=16;W.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P})()}; \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.barRenderer.js b/js/jquery/jqplot-plugins/jqplot.barRenderer.js new file mode 100644 index 0000000000..4feb37b799 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.barRenderer.js @@ -0,0 +1,404 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + + // Class: $.jqplot.BarRenderer + // A plugin renderer for jqPlot to draw a bar plot. + // Draws series as a line. + + $.jqplot.BarRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer; + + // called with scope of series. + $.jqplot.BarRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: barPadding + // Number of pixels between adjacent bars at the same axis value. + this.barPadding = 8; + // prop: barMargin + // Number of pixels between groups of bars at adjacent axis values. + this.barMargin = 10; + // prop: barDirection + // 'vertical' = up and down bars, 'horizontal' = side to side bars + this.barDirection = 'vertical'; + // prop: barWidth + // Width of the bar in pixels (auto by devaul). null = calculated automatically. + this.barWidth = null; + // prop: shadowOffset + // offset of the shadow from the slice and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 5; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.08; + // prop: waterfall + // true to enable waterfall plot. + this.waterfall = false; + // prop: varyBarColor + // true to color each bar separately. + this.varyBarColor = false; + $.extend(true, this, options); + // fill is still needed to properly draw the legend. + // bars have to be filled. + this.fill = true; + + if (this.waterfall) { + this.fillToZero = false; + this.disableStack = true; + } + + if (this.barDirection == 'vertical' ) { + this._primaryAxis = '_xaxis'; + this._stackAxis = 'y'; + this.fillAxis = 'y'; + } + else { + this._primaryAxis = '_yaxis'; + this._stackAxis = 'x'; + this.fillAxis = 'x'; + } + // set the shape renderer options + var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill}; + this.renderer.shapeRenderer.init(opts); + // set the shadow renderer options + var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill}; + this.renderer.shadowRenderer.init(sopts); + }; + + // called with scope of series + function barPreInit(target, data, seriesDefaults, options) { + if (this.rendererOptions.barDirection == 'horizontal') { + this._stackAxis = 'x'; + this._primaryAxis = '_yaxis'; + } + if (this.rendererOptions.waterfall == true) { + this._data = $.extend(true, [], this.data); + var sum = 0; + var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection == 'vertical') ? 1 : 0; + for(var i=0; i0) { + this.data[i][pos] += this.data[i-1][pos]; + } + } + this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; + this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; + } + } + + $.jqplot.preSeriesInitHooks.push(barPreInit); + + // needs to be called with scope of series, not renderer. + $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + // loop through all series on this axis + for (var i=0; i < paxis._series.length; i++) { + series = paxis._series[i]; + if (series === this) { + pos = i; + } + // is the series rendered as a bar? + if (series.renderer.constructor == $.jqplot.BarRenderer) { + // gridData may not be computed yet, use data length insted + nvals += series.data.length; + nseries += 1; + } + } + return [nvals, nseries, pos]; + }; + + $.jqplot.BarRenderer.prototype.setBarWidth = function() { + // need to know how many data values we have on the approprate axis and figure it out. + var i; + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + var temp = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + var nticks = paxis.numberTicks; + var nbins = (nticks-1)/2; + // so, now we have total number of axis values. + if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { + if (this._stack) { + this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin; + } + else { + this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; + // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries; + } + } + else { + if (this._stack) { + this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin; + } + else { + this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; + // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries; + } + } + return [nvals, nseries]; + }; + + $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options) { + var i; + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy, nvals, nseries, pos; + + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + pos = temp[2]; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); + var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); + var negativeColor = negativeColors.get(this.index); + if (! this.useNegativeColors) { + negativeColor = opts.fillStyle; + } + var positiveColor = opts.fillStyle; + + if (this.barDirection == 'vertical') { + for (var i=0; i 0 && i < this.gridData.length-1) { + ystart = this.gridData[i-1][1]; + } + else { + ystart = ctx.canvas.height; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + else { + opts.fillStyle = negativeColor; + } + } + else { + if (this.varyBarColor) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + points.push([base-this.barWidth/2, ystart]); + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, ystart]); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + this.renderer.shadowRenderer.draw(ctx, points, opts); + } + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + + else if (this.barDirection == 'horizontal'){ + for (var i=0; i 0 && i < this.gridData.length-1) { + xstart = this.gridData[i-1][1]; + } + else { + xstart = 0; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + } + else { + if (this.varyBarColor) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + points.push([xstart, base+this.barWidth/2]); + points.push([gridData[i][0], base+this.barWidth/2]); + points.push([gridData[i][0], base-this.barWidth/2]); + points.push([xstart, base-this.barWidth/2]); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + this.renderer.shadowRenderer.draw(ctx, points, opts); + } + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + } + + }; + + + // for stacked plots, shadows will be pre drawn by drawShadow. + $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options) { + var i; + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy, nvals, nseries, pos; + + if (this._stack && this.shadow) { + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + pos = temp[2]; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + + if (this.barDirection == 'vertical') { + for (var i=0; i0){this.data[d][j]+=this.data[d-1][j]}}this.data[this.data.length]=(j==1)?[this.data.length+1,e]:[e,this.data.length+1];this._data[this._data.length]=(j==1)?[this._data.length+1,e]:[e,this._data.length+1]}}b.jqplot.preSeriesInitHooks.push(a);b.jqplot.BarRenderer.prototype.calcSeriesNumbers=function(){var g=0;var h=0;var f=this[this._primaryAxis];var e,d,j;for(var c=0;c0&&u0&&u 528 || (p[0] == 528 && p[1] >= 16)) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + } + else if ($.browser.mozilla) { + var p = $.browser.version.split("."); + if (p[0] > 1 || (p[0] == 1 && p[1] >= 9 && p[2] > 0) ) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + + // TODO: test and enable this + // else if ($.browser.msie) { + // this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + // } + + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); + }; + + // return width along the x axis + // will check first to see if an element exists. + // if not, will return the computed text box width. + $.jqplot.CanvasAxisLabelRenderer.prototype.getWidth = function(ctx) { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); + return w; + } + }; + + // return height along the y axis. + $.jqplot.CanvasAxisLabelRenderer.prototype.getHeight = function(ctx) { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); + return w; + } + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad = function() { + var a = this.angle * Math.PI/180; + return a; + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx) { + // create a canvas here, but can't draw on it untill it is appended + // to dom for IE compatability. + var domelem = document.createElement('canvas'); + this._textRenderer.setText(this.label, ctx); + var w = this.getWidth(ctx); + var h = this.getHeight(ctx); + domelem.width = w; + domelem.height = h; + domelem.style.width = w; + domelem.style.height = h; + // domelem.style.textAlign = 'center'; + domelem.style.position = 'absolute'; + this._domelem = domelem; + this._elem = $(domelem); + this._elem.addClass('jqplot-'+this.axis+'-label'); + + return this._elem; + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.pack = function() { + if ($.browser.msie) { + window.G_vmlCanvasManager.init_(document); + this._domelem = window.G_vmlCanvasManager.initElement(this._domelem); + } + var ctx = this._elem.get(0).getContext("2d"); + this._textRenderer.draw(ctx, this.label); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js b/js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js new file mode 100644 index 0000000000..95ecfdd758 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=false;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var e={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){e.pt2px=this.pt2px}if(this.enableFontSupport){if(a.browser.safari){var d=a.browser.version.split(".");for(var c=0;c528||(d[0]==528&&d[1]>=16)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}}else{if(a.browser.mozilla){var d=a.browser.version.split(".");if(d[0]>1||(d[0]==1&&d[1]>=9&&d[2]>0)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c){var e=document.createElement("canvas");this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.position="absolute";this._domelem=e;this._elem=a(e);this._elem.addClass("jqplot-"+this.axis+"-label");return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){if(a.browser.msie){window.G_vmlCanvasManager.init_(document);this._domelem=window.G_vmlCanvasManager.initElement(this._domelem)}var b=this._elem.get(0).getContext("2d");this._textRenderer.draw(b,this.label)}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js new file mode 100644 index 0000000000..77d97f8c01 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js @@ -0,0 +1,232 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + /** + * Class: $.jqplot.CanvasAxisTickRenderer + * Renderer to draw axis ticks with a canvas element to support advanced + * featrues such as rotated text. This renderer uses a separate rendering engine + * to draw the text on the canvas. Two modes of rendering the text are available. + * If the browser has native font support for canvas fonts (currently Mozila 3.5 + * and Safari 4), you can enable text rendering with the canvas fillText method. + * You do so by setting the "enableFontSupport" option to true. + * + * Browsers lacking native font support will have the text drawn on the canvas + * using the Hershey font metrics. Even if the "enableFontSupport" option is true + * non-supporting browsers will still render with the Hershey font. + */ + $.jqplot.CanvasAxisTickRenderer = function(options) { + // Group: Properties + + // prop: mark + // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. + this.mark = 'outside'; + // prop: showMark + // wether or not to show the mark on the axis. + this.showMark = true; + // prop: showGridline + // wether or not to draw the gridline on the grid at this tick. + this.showGridline = true; + // prop: isMinorTick + // if this is a minor tick. + this.isMinorTick = false; + // prop: angle + // angle of text, measured clockwise from x axis. + this.angle = 0; + // prop: markSize + // Length of the tick marks in pixels. For 'cross' style, length + // will be stoked above and below axis, so total length will be twice this. + this.markSize = 4; + // prop: show + // wether or not to show the tick (mark and label). + this.show = true; + // prop: showLabel + // wether or not to show the label. + this.showLabel = true; + // prop: labelPosition + // 'auto', 'start', 'middle' or 'end'. + // Whether tick label should be positioned so the start, middle, or end + // of the tick mark. + this.labelPosition = 'auto'; + this.label = ''; + this.value = null; + this._styles = {}; + // prop: formatter + // A class of a formatter for the tick text. + // The default $.jqplot.DefaultTickFormatter uses sprintf. + this.formatter = $.jqplot.DefaultTickFormatter; + // prop: formatString + // string passed to the formatter. + this.formatString = ''; + // prop: fontFamily + // css spec for the font-family css attribute. + this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif'; + // prop: fontSize + // CSS spec for font size. + this.fontSize = '11px'; + // prop: fontWeight + // CSS spec for fontWeight + this.fontWeight = 'normal'; + // prop: fontStretch + // Multiplier to condense or expand font width. + // Applies only to browsers which don't support canvas native font rendering. + this.fontStretch = 1.0; + // prop: textColor + // css spec for the color attribute. + this.textColor = '#666666'; + // prop: enableFontSupport + // true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+. + // If true, tick label will be drawn with canvas tag native support for fonts. + // If false, tick label will be drawn with Hershey font metrics. + this.enableFontSupport = false; + // prop: pt2px + // Point to pixel scaling factor, used for computing height of bounding box + // around a label. The labels text renderer has a default setting of 1.4, which + // should be suitable for most fonts. Leave as null to use default. If tops of + // letters appear clipped, increase this. If bounding box seems too big, decrease. + // This is an issue only with the native font renderering capabilities of Mozilla + // 3.5 and Safari 4 since they do not provide a method to determine the font height. + this.pt2px = null; + + this._elem; + this._ctx; + this._plotWidth; + this._plotHeight; + this._plotDimensions = {height:null, width:null}; + + $.extend(true, this, options); + + var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}; + if (this.pt2px) { + ropts.pt2px = this.pt2px; + } + + if (this.enableFontSupport) { + if ($.browser.safari) { + var p = $.browser.version.split('.'); + for (var i=0; i 528 || (p[0] == 528 && p[1] >= 16)) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + } + else if ($.browser.mozilla) { + var p = $.browser.version.split("."); + if (p[0] > 1 || (p[0] == 1 && p[1] >= 9 && p[2] > 0) ) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + + // TODO: test and enable this + // else if ($.browser.msie) { + // this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + // } + + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); + }; + + // return width along the x axis + // will check first to see if an element exists. + // if not, will return the computed text box width. + $.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); + return w; + } + }; + + // return height along the y axis. + $.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); + return w; + } + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() { + var a = this.angle * Math.PI/180; + return a; + }; + + + $.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { + this.value = value; + if (isMinor) { + this.isMinorTick = true; + } + return this; + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx) { + if (!this.label) { + this.label = this.formatter(this.formatString, this.value); + } + // create a canvas here, but can't draw on it untill it is appended + // to dom for IE compatability. + var domelem = document.createElement('canvas'); + this._textRenderer.setText(this.label, ctx); + var w = this.getWidth(ctx); + var h = this.getHeight(ctx); + domelem.width = w; + domelem.height = h; + domelem.style.width = w; + domelem.style.height = h; + domelem.style.textAlign = 'left'; + domelem.style.position = 'absolute'; + this._domelem = domelem; + this._elem = $(domelem); + this._elem.css(this._styles); + this._elem.addClass('jqplot-'+this.axis+'-tick'); + + return this._elem; + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.pack = function() { + if ($.browser.msie) { + window.G_vmlCanvasManager.init_(document); + this._domelem = window.G_vmlCanvasManager.initElement(this._domelem); + } + var ctx = this._elem.get(0).getContext("2d"); + this._textRenderer.draw(ctx, this.label); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js new file mode 100644 index 0000000000..941fed2557 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11px";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=false;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var e={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){e.pt2px=this.pt2px}if(this.enableFontSupport){if(a.browser.safari){var d=a.browser.version.split(".");for(var c=0;c528||(d[0]==528&&d[1]>=16)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}}else{if(a.browser.mozilla){var d=a.browser.version.split(".");if(d[0]>1||(d[0]==1&&d[1]>=9&&d[2]>0)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c){if(!this.label){this.label=this.formatter(this.formatString,this.value)}var e=document.createElement("canvas");this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";this._domelem=e;this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){if(a.browser.msie){window.G_vmlCanvasManager.init_(document);this._domelem=window.G_vmlCanvasManager.initElement(this._domelem)}var b=this._elem.get(0).getContext("2d");this._textRenderer.draw(b,this.label)}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js new file mode 100644 index 0000000000..8536efb2b3 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js @@ -0,0 +1,408 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + // This code is a modified version of the canvastext.js code, copyright below: + // + // This code is released to the public domain by Jim Studt, 2007. + // He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ + // + $.jqplot.CanvasTextRenderer = function(options){ + this.fontStyle = 'normal'; // normal, italic, oblique [not implemented] + this.fontVariant = 'normal'; // normal, small caps [not implemented] + this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900 + this.fontSize = '10px'; + this.fontFamily = 'sans-serif'; + this.fontStretch = 1.0; + this.fillStyle = '#666666'; + this.angle = 0; + this.textAlign = 'start'; + this.textBaseline = 'alphabetic'; + this.text; + this.width; + this.height; + this.pt2px = 1.28; + + $.extend(true, this, options); + this.normalizedFontSize = this.normalizeFontSize(this.fontSize); + this.setHeight(); + }; + + $.jqplot.CanvasTextRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this.normalizedFontSize = this.normalizeFontSize(this.fontSize); + this.setHeight(); + }; + + // convert css spec into point size + // returns float + $.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) { + sz = String(sz); + n = parseFloat(sz); + if (sz.indexOf('px') > -1) { + return n/this.pt2px; + } + else if (sz.indexOf('pt') > -1) { + return n; + } + else if (sz.indexOf('em') > -1) { + return n*12; + } + else if (sz.indexOf('%') > -1) { + return n*12/100; + } + // default to pixels; + else { + return n/this.pt2px; + } + }; + + + $.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) { + // w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 + // return values adjusted for Hershey font. + if (Number(w)) { + return w/400; + } + else { + switch (w) { + case 'normal': + return 1; + break; + case 'bold': + return 1.75; + break; + case 'bolder': + return 2.25; + break; + case 'lighter': + return 0.75; + break; + default: + return 1; + break; + } + } + }; + + $.jqplot.CanvasTextRenderer.prototype.getText = function() { + return this.text; + }; + + $.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) { + this.text = t; + this.setWidth(ctx); + return this; + }; + + $.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) { + return this.width; + }; + + $.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) { + if (!w) { + this.width = this.measure(ctx, this.text); + } + else { + this.width = w; + } + return this; + }; + + // return height in pixels. + $.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) { + return this.height; + }; + + // w - height in pt + // set heigh in px + $.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) { + if (!w) { + //height = this.fontSize /0.75; + this.height = this.normalizedFontSize * this.pt2px; + } + else { + this.height = w; + } + return this; + }; + + $.jqplot.CanvasTextRenderer.prototype.letter = function (ch) + { + return this.letters[ch]; + }; + + $.jqplot.CanvasTextRenderer.prototype.ascent = function() + { + return this.normalizedFontSize; + }; + + $.jqplot.CanvasTextRenderer.prototype.descent = function() + { + return 7.0*this.normalizedFontSize/25.0; + }; + + $.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str) + { + var total = 0; + var len = str.length; + + for ( i = 0; i < len; i++) { + var c = this.letter(str.charAt(i)); + if (c) { + total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch; + } + } + return total; + }; + + $.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str) + { + var x = 0; + // leave room at bottom for descenders. + var y = this.height*0.72; + var total = 0; + var len = str.length; + var mag = this.normalizedFontSize / 25.0; + + ctx.save(); + var tx, ty; + + // 1st quadrant + if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { + tx = 0; + ty = -Math.sin(this.angle) * this.width; + } + // 4th quadrant + else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { + tx = Math.sin(this.angle) * this.height; + ty = 0; + } + // 2nd quadrant + else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { + tx = -Math.cos(this.angle) * this.width; + ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; + } + // 3rd quadrant + else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { + tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; + ty = -Math.cos(this.angle) * this.height; + } + + ctx.strokeStyle = this.fillStyle; + ctx.fillStyle = this.fillStyle; + ctx.translate(tx, ty); + ctx.rotate(this.angle); + ctx.lineCap = "round"; + // multiplier was 2.0 + var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20; + ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight); + + for ( var i = 0; i < len; i++) { + var c = this.letter( str.charAt(i)); + if ( !c) { + continue; + } + + ctx.beginPath(); + + var penUp = 1; + var needStroke = 0; + for ( var j = 0; j < c.points.length; j++) { + var a = c.points[j]; + if ( a[0] == -1 && a[1] == -1) { + penUp = 1; + continue; + } + if ( penUp) { + ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); + penUp = false; + } else { + ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); + } + } + ctx.stroke(); + x += c.width*mag*this.fontStretch; + } + ctx.restore(); + return total; + }; + + $.jqplot.CanvasTextRenderer.prototype.letters = { + ' ': { width: 16, points: [] }, + '!': { width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '"': { width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] }, + '#': { width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] }, + '$': { width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + '%': { width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, + '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, + '\'': { width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, + '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, + ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, + '*': { width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] }, + '+': { width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] }, + ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '-': { width: 18, points: [[6,9],[12,9]] }, + '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '/': { width: 22, points: [[20,25],[2,-7]] }, + '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, + '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, + '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, + '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '4': { width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] }, + '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, + '7': { width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] }, + '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, + '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, + ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, + ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, + '=': { width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] }, + '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, + '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] }, + '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] }, + 'A': { width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] }, + 'B': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, + 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, + 'D': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, + 'E': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] }, + 'F': { width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] }, + 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] }, + 'H': { width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] }, + 'I': { width: 8, points: [[4,21],[4,0]] }, + 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, + 'K': { width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] }, + 'L': { width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] }, + 'M': { width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] }, + 'N': { width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] }, + 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, + 'P': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, + 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] }, + 'R': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] }, + 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + 'T': { width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] }, + 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, + 'V': { width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] }, + 'W': { width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] }, + 'X': { width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] }, + 'Y': { width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] }, + 'Z': { width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] }, + '[': { width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] }, + '\\': { width: 14, points: [[0,21],[14,-3]] }, + ']': { width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] }, + '^': { width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] }, + '_': { width: 16, points: [[0,-2],[16,-2]] }, + '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, + 'a': { width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'b': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'd': { width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] }, + 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'h': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]] }, + 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, + 'k': { width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] }, + 'l': { width: 8, points: [[4,21],[4,0]] }, + 'm': { width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, + 'n': { width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, + 'p': { width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'q': { width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'r': { width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] }, + 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, + 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] }, + 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] }, + 'v': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] }, + 'w': { width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] }, + 'x': { width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] }, + 'y': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, + 'z': { width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] }, + '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, + '|': { width: 8, points: [[4,25],[4,-7]] }, + '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, + '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] } + }; + + $.jqplot.CanvasFontRenderer = function(options) { + options = options || {}; + if (!options.pt2px) { + options.pt2px = 1.5; + } + $.jqplot.CanvasTextRenderer.call(this, options); + }; + + $.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({}); + $.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer; + + $.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str) + { + // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; + var fstyle = this.fontSize+' '+this.fontFamily; + ctx.save(); + ctx.font = fstyle; + var w = ctx.measureText(str).width; + ctx.restore(); + return w; + }; + + $.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str) + { + var x = 0; + // leave room at bottom for descenders. + var y = this.height*0.72; + //var y = 12; + + ctx.save(); + var tx, ty; + + // 1st quadrant + if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { + tx = 0; + ty = -Math.sin(this.angle) * this.width; + } + // 4th quadrant + else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { + tx = Math.sin(this.angle) * this.height; + ty = 0; + } + // 2nd quadrant + else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { + tx = -Math.cos(this.angle) * this.width; + ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; + } + // 3rd quadrant + else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { + tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; + ty = -Math.cos(this.angle) * this.height; + } + ctx.strokeStyle = this.fillStyle; + ctx.fillStyle = this.fillStyle; + // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; + var fstyle = this.fontSize+' '+this.fontFamily; + ctx.font = fstyle; + ctx.translate(tx, ty); + ctx.rotate(this.angle); + ctx.fillText(str, x, y); + // ctx.strokeText(str, x, y); + + ctx.restore(); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js new file mode 100644 index 0000000000..0dbb8a61ac --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);n=parseFloat(b);if(b.indexOf("px")>-1){return n/this.pt2px}else{if(b.indexOf("pt")>-1){return n}else{if(b.indexOf("em")>-1){return n*12}else{if(b.indexOf("%")>-1){return n*12/100}else{return n/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,f){var e=0;var b=f.length;for(i=0;i30)?2:2+(30-this.normalizedFontSize)/20;t.lineWidth=u*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0 class. + * + * To use this renderer, include the plugin in your source + * > + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}} + **/ + $.jqplot.CategoryAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer; + + $.jqplot.CategoryAxisRenderer.prototype.init = function(options){ + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + // this.tickRenderer = $.jqplot.AxisTickRenderer; + // this.labelRenderer = $.jqplot.AxisLabelRenderer; + $.extend(true, this, {tickOptions:{formatString:'%d'}}, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + }; + + + $.jqplot.CategoryAxisRenderer.prototype.createTicks = function() { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim, interval; + var min, max; + var pos1, pos2; + var tt, i; + + // if we already have ticks, use them. + if (userTicks.length) { + this.min = 0.5; + this.max = userTicks.length + 0.5; + var range = this.max - this.min; + this.numberTicks = 2*userTicks.length + 1; + for (i=0; i0 && trackb.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]b.max||b.max==null){b.max=h[c][1]}}}}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var y=this._ticks;var v=this.ticks;var B=this.name;var x=this._dataBounds;var p,w;var n,q;var d,c;var b,r;if(v.length){this.min=0.5;this.max=v.length+0.5;var h=this.max-this.min;this.numberTicks=2*v.length+1;for(r=0;r0&&l= 1 or will often miss point intersections. + this.intersectionThreshold = 2; + // prop: showCursorLegend + // Replace the plot legend with an enhanced legend displaying intersection information. + this.showCursorLegend = false; + // prop: cursorLegendFormatString + // Format string used in the cursor legend. If showTooltipDataPosition is true, + // this will also be the default format string used by tooltipFormatString. + this.cursorLegendFormatString = $.jqplot.Cursor.cursorLegendFormatString; + $.extend(true, this, options); + }; + + $.jqplot.Cursor.cursorLegendFormatString = '%s x:%s, y:%s'; + + // called with scope of plot + $.jqplot.Cursor.init = function (target, data, opts){ + // add a cursor attribute to the plot + var options = opts || {}; + this.plugins.cursor = new $.jqplot.Cursor(options.cursor); + var c = this.plugins.cursor; + + if (c.show) { + $.jqplot.eventListenerHooks.push(['jqplotMouseEnter', handleMouseEnter]); + $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMouseLeave]); + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMouseMove]); + + if (c.showCursorLegend) { + opts.legend = opts.legend || {}; + opts.legend.renderer = $.jqplot.CursorLegendRenderer; + opts.legend.formatString = this.plugins.cursor.cursorLegendFormatString; + opts.legend.show = true; + } + + if (c.zoom) { + $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleMouseDown]); + $.jqplot.eventListenerHooks.push(['jqplotMouseUp', handleMouseUp]); + + if (c.clickReset) { + $.jqplot.eventListenerHooks.push(['jqplotClick', handleClick]); + } + + if (c.dblClickReset) { + $.jqplot.eventListenerHooks.push(['jqplotDblClick', handleDblClick]); + } + } + + this.resetZoom = function() { + var axes = this.axes; + if (!c.zoomProxy) { + for (var ax in axes) { + axes[ax].reset(); + } + this.redraw(); + } + else { + var ctx = this.plugins.cursor.zoomCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + } + this.plugins.cursor._zoom.isZoomed = false; + this.target.trigger('jqplotResetZoom', [this, this.plugins.cursor]); + }; + + + if (c.showTooltipDataPosition) { + c.showTooltipUnitPosition = false; + c.showTooltipGridPosition = false; + if (options.cursor.tooltipFormatString == undefined) { + c.tooltipFormatString = $.jqplot.Cursor.cursorLegendFormatString; + } + } + } + }; + + // called with context of plot + $.jqplot.Cursor.postDraw = function() { + var c = this.plugins.cursor; + // if (c.zoom) { + c.zoomCanvas = new $.jqplot.GenericCanvas(); + this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions)); + var zctx = c.zoomCanvas.setContext(); + // } + c._tooltipElem = $(''); + c.zoomCanvas._elem.before(c._tooltipElem); + if (c.showVerticalLine || c.showHorizontalLine) { + c.cursorCanvas = new $.jqplot.GenericCanvas(); + this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions)); + var zctx = c.cursorCanvas.setContext(); + } + + // if we are showing the positions in unit coordinates, and no axes groups + // were specified, create a default set. + if (c.showTooltipUnitPosition){ + if (c.tooltipAxisGroups.length === 0) { + var series = this.series; + var s; + var temp = []; + for (var i=0; i 6 && Math.abs(gridpos.y - c._zoom.start[1]) > 6) || (c.constrainZoomTo == 'x' && Math.abs(gridpos.x - c._zoom.start[0]) > 6) || (c.constrainZoomTo == 'y' && Math.abs(gridpos.y - c._zoom.start[1]) > 6)) { + if (!plot.plugins.cursor.zoomProxy) { + for (var ax in datapos) { + // make a copy of the original axes to revert back. + if (c._zoom.axes[ax] == undefined) { + c._zoom.axes[ax] = {}; + c._zoom.axes[ax].numberTicks = axes[ax].numberTicks; + c._zoom.axes[ax].tickInterval = axes[ax].tickInterval; + // for date axes... + c._zoom.axes[ax].daTickInterval = axes[ax].daTickInterval; + c._zoom.axes[ax].min = axes[ax].min; + c._zoom.axes[ax].max = axes[ax].max; + } + if ((c.constrainZoomTo == 'none') || (c.constrainZoomTo == 'x' && ax.charAt(0) == 'x') || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'y')) { + dp = datapos[ax]; + if (dp != null) { + if (dp > start[ax]) { + axes[ax].min = start[ax]; + axes[ax].max = dp; + } + else { + span = start[ax] - dp; + axes[ax].max = start[ax]; + axes[ax].min = dp; + } + axes[ax].tickInterval = null; + // for date axes... + axes[ax].daTickInterval = null; + axes[ax]._ticks = []; + } + } + + // if ((c.constrainZoomTo == 'x' && ax.charAt(0) == 'y' && c.autoscaleConstraint) || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'x' && c.autoscaleConstraint)) { + // dp = datapos[ax]; + // if (dp != null) { + // axes[ax].max == null; + // axes[ax].min = null; + // } + // } + } + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + plot.redraw(); + c._zoom.isZoomed = true; + } + plot.target.trigger('jqplotZoom', [gridpos, datapos, plot, cursor]); + } + }; + + $.jqplot.preInitHooks.push($.jqplot.Cursor.init); + $.jqplot.postDrawHooks.push($.jqplot.Cursor.postDraw); + + function updateTooltip(gridpos, datapos, plot) { + var c = plot.plugins.cursor; + var s = ''; + var addbr = false; + if (c.showTooltipGridPosition) { + s = gridpos.x+', '+gridpos.y; + addbr = true; + } + if (c.showTooltipUnitPosition) { + var g; + for (var i=0; i start[0]) { + l = start[0]; + w = end[0] - start[0]; + } + else { + l = end[0]; + w = start[0] - end[0]; + } + if (end[1] > start[1]) { + t = start[1]; + h = end[1] - start[1]; + } + else { + t = end[1]; + h = start[1] - end[1]; + } + ctx.fillStyle = 'rgba(0,0,0,0.2)'; + ctx.strokeStyle = '#999999'; + ctx.lineWidth = 1.0; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx.clearRect(l, t, w, h); + // IE won't show transparent fill rect, so stroke a rect also. + ctx.strokeRect(l,t,w,h); + } + + $.jqplot.CursorLegendRenderer = function(options) { + $.jqplot.TableLegendRenderer.call(this, options); + this.formatString = '%s'; + }; + + $.jqplot.CursorLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.CursorLegendRenderer.prototype.constructor = $.jqplot.CursorLegendRenderer; + + // called in context of a Legend + $.jqplot.CursorLegendRenderer.prototype.draw = function() { + if (this.show) { + var series = this._series; + // make a table. one line label per row. + this._elem = $('
    '); + + var pad = false; + for (var i = 0; i< series.length; i++) { + s = series[i]; + if (s.show) { + var lt = $.jqplot.sprintf(this.formatString, s.label.toString()); + if (lt) { + var color = s.color; + if (s._stack && !s.fill) { + color = ''; + } + addrow.call(this, lt, color, pad, i); + pad = true; + } + // let plugins add more rows to legend. Used by trend line plugin. + for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { + var item = $.jqplot.addLegendRowHooks[j].call(this, s); + if (item) { + addrow.call(this, item.label, item.color, pad); + pad = true; + } + } + } + } + } + + function addrow(label, color, pad, idx) { + var rs = (pad) ? this.rowSpacing : '0'; + var tr = $('').appendTo(this._elem); + tr.data('seriesIndex', idx); + $(''+ + '
    '+ + '
    '+ + '
    ').appendTo(tr); + var td = $(''); + td.appendTo(tr); + td.data('seriesIndex', idx); + if (this.escapeHtml) { + td.text(label); + } + else { + td.html(label); + } + } + return this._elem; + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.cursor.min.js b/js/jquery/jqplot-plugins/jqplot.cursor.min.js new file mode 100644 index 0000000000..3ce2ea5466 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.cursor.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(i){i.jqplot.Cursor=function(o){this.style="crosshair";this.previousCursor="auto";this.show=i.jqplot.config.enablePlugins;this.showTooltip=true;this.followMouse=false;this.tooltipLocation="se";this.tooltipOffset=6;this.showTooltipGridPosition=false;this.showTooltipUnitPosition=true;this.showTooltipDataPosition=false;this.tooltipFormatString="%.4P, %.4P";this.useAxesFormatters=true;this.tooltipAxisGroups=[];this.zoom=false;this.zoomProxy=false;this.zoomTarget=false;this.clickReset=false;this.dblClickReset=true;this.showVerticalLine=false;this.showHorizontalLine=false;this.constrainZoomTo="none";this.shapeRenderer=new i.jqplot.ShapeRenderer();this._zoom={start:[],end:[],started:false,zooming:false,isZoomed:false,axes:{start:{},end:{}}};this._tooltipElem;this.zoomCanvas;this.cursorCanvas;this.intersectionThreshold=2;this.showCursorLegend=false;this.cursorLegendFormatString=i.jqplot.Cursor.cursorLegendFormatString;i.extend(true,this,o)};i.jqplot.Cursor.cursorLegendFormatString="%s x:%s, y:%s";i.jqplot.Cursor.init=function(t,r,q){var o=q||{};this.plugins.cursor=new i.jqplot.Cursor(o.cursor);var u=this.plugins.cursor;if(u.show){i.jqplot.eventListenerHooks.push(["jqplotMouseEnter",b]);i.jqplot.eventListenerHooks.push(["jqplotMouseLeave",f]);i.jqplot.eventListenerHooks.push(["jqplotMouseMove",h]);if(u.showCursorLegend){q.legend=q.legend||{};q.legend.renderer=i.jqplot.CursorLegendRenderer;q.legend.formatString=this.plugins.cursor.cursorLegendFormatString;q.legend.show=true}if(u.zoom){i.jqplot.eventListenerHooks.push(["jqplotMouseDown",a]);i.jqplot.eventListenerHooks.push(["jqplotMouseUp",n]);if(u.clickReset){i.jqplot.eventListenerHooks.push(["jqplotClick",j])}if(u.dblClickReset){i.jqplot.eventListenerHooks.push(["jqplotDblClick",c])}}this.resetZoom=function(){var x=this.axes;if(!u.zoomProxy){for(var w in x){x[w].reset()}this.redraw()}else{var v=this.plugins.cursor.zoomCanvas._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height)}this.plugins.cursor._zoom.isZoomed=false;this.target.trigger("jqplotResetZoom",[this,this.plugins.cursor])};if(u.showTooltipDataPosition){u.showTooltipUnitPosition=false;u.showTooltipGridPosition=false;if(o.cursor.tooltipFormatString==undefined){u.tooltipFormatString=i.jqplot.Cursor.cursorLegendFormatString}}}};i.jqplot.Cursor.postDraw=function(){var w=this.plugins.cursor;w.zoomCanvas=new i.jqplot.GenericCanvas();this.eventCanvas._elem.before(w.zoomCanvas.createElement(this._gridPadding,"jqplot-zoom-canvas",this._plotDimensions));var v=w.zoomCanvas.setContext();w._tooltipElem=i('');w.zoomCanvas._elem.before(w._tooltipElem);if(w.showVerticalLine||w.showHorizontalLine){w.cursorCanvas=new i.jqplot.GenericCanvas();this.eventCanvas._elem.before(w.cursorCanvas.createElement(this._gridPadding,"jqplot-cursor-canvas",this._plotDimensions));var v=w.cursorCanvas.setContext()}if(w.showTooltipUnitPosition){if(w.tooltipAxisGroups.length===0){var r=this.series;var t;var o=[];for(var q=0;q6&&Math.abs(w.y-z._zoom.start[1])>6)||(z.constrainZoomTo=="x"&&Math.abs(w.x-z._zoom.start[0])>6)||(z.constrainZoomTo=="y"&&Math.abs(w.y-z._zoom.start[1])>6)){if(!x.plugins.cursor.zoomProxy){for(var o in t){if(z._zoom.axes[o]==undefined){z._zoom.axes[o]={};z._zoom.axes[o].numberTicks=y[o].numberTicks;z._zoom.axes[o].tickInterval=y[o].tickInterval;z._zoom.axes[o].daTickInterval=y[o].daTickInterval;z._zoom.axes[o].min=y[o].min;z._zoom.axes[o].max=y[o].max}if((z.constrainZoomTo=="none")||(z.constrainZoomTo=="x"&&o.charAt(0)=="x")||(z.constrainZoomTo=="y"&&o.charAt(0)=="y")){dp=t[o];if(dp!=null){if(dp>r[o]){y[o].min=r[o];y[o].max=dp}else{span=r[o]-dp;y[o].max=r[o];y[o].min=dp}y[o].tickInterval=null;y[o].daTickInterval=null;y[o]._ticks=[]}}}C.clearRect(0,0,C.canvas.width,C.canvas.height);x.redraw();z._zoom.isZoomed=true}x.target.trigger("jqplotZoom",[w,t,x,B])}};i.jqplot.preInitHooks.push(i.jqplot.Cursor.init);i.jqplot.postDrawHooks.push(i.jqplot.Cursor.postDraw);function e(D,q,A){var F=A.plugins.cursor;var v="";var J=false;if(F.showTooltipGridPosition){v=D.x+", "+D.y;J=true}if(F.showTooltipUnitPosition){var C;for(var B=0;B"}if(F.useAxesFormatters){var z=A.axes[C[0]]._ticks[0].formatter;var o=A.axes[C[1]]._ticks[0].formatter;var G=A.axes[C[0]]._ticks[0].formatString;var u=A.axes[C[1]]._ticks[0].formatString;v+=z(G,q[C[0]])+", "+o(u,q[C[1]])}else{v+=i.jqplot.sprintf(F.tooltipFormatString,q[C[0]],q[C[1]])}J=true}}if(F.showTooltipDataPosition){var t=A.series;var I=d(A,D.x,D.y);var J=false;for(var B=0;B"}v+=i.jqplot.sprintf(F.tooltipFormatString,r,y,w);J=true}}}}F._tooltipElem.html(v)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var q=i(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;By[0]){q=y[0];o=u[0]-y[0]}else{q=u[0];o=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}r.fillStyle="rgba(0,0,0,0.2)";r.strokeStyle="#999999";r.lineWidth=1;r.clearRect(0,0,r.canvas.width,r.canvas.height);r.fillRect(0,0,r.canvas.width,r.canvas.height);r.clearRect(q,v,o,x);r.strokeRect(q,v,o,x)}i.jqplot.CursorLegendRenderer=function(o){i.jqplot.TableLegendRenderer.call(this,o);this.formatString="%s"};i.jqplot.CursorLegendRenderer.prototype=new i.jqplot.TableLegendRenderer();i.jqplot.CursorLegendRenderer.prototype.constructor=i.jqplot.CursorLegendRenderer;i.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this.show){var u=this._series;this._elem=i('
    ');var x=false;for(var t=0;t').appendTo(this._elem);C.data("seriesIndex",y);i('
    ').appendTo(C);var E=i('');E.appendTo(C);E.data("seriesIndex",y);if(this.escapeHtml){E.text(B)}else{E.html(B)}}return this._elem}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js b/js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js new file mode 100644 index 0000000000..e46bc5b76c --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js @@ -0,0 +1,313 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + /** + * Class: $.jqplot.DateAxisRenderer + * A plugin for a jqPlot to render an axis as a series of date values. + * This renderer has no options beyond those supplied by the class. + * It supplies it's own tick formatter, so the tickOptions.formatter option + * should not be overridden. + * + * Thanks to Ken Synder for his enhanced Date instance methods which are + * included with this code . + * + * To use this renderer, include the plugin in your source + * > + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}}} + * + * Dates can be passed into the axis in almost any recognizable value and + * will be parsed. They will be rendered on the axis in the format + * specified by tickOptions.formatString. e.g. tickOptions.formatString = '%Y-%m-%d'. + * + * Accecptable format codes + * are: + * + * > Code Result Description + * > == Years == + * > %Y 2008 Four-digit year + * > %y 08 Two-digit year + * > == Months == + * > %m 09 Two-digit month + * > %#m 9 One or two-digit month + * > %B September Full month name + * > %b Sep Abbreviated month name + * > == Days == + * > %d 05 Two-digit day of month + * > %#d 5 One or two-digit day of month + * > %e 5 One or two-digit day of month + * > %A Sunday Full name of the day of the week + * > %a Sun Abbreviated name of the day of the week + * > %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) + * > %o th The ordinal suffix string following the day of the month + * > == Hours == + * > %H 23 Hours in 24-hour format (two digits) + * > %#H 3 Hours in 24-hour integer format (one or two digits) + * > %I 11 Hours in 12-hour format (two digits) + * > %#I 3 Hours in 12-hour integer format (one or two digits) + * > %p PM AM or PM + * > == Minutes == + * > %M 09 Minutes (two digits) + * > %#M 9 Minutes (one or two digits) + * > == Seconds == + * > %S 02 Seconds (two digits) + * > %#S 2 Seconds (one or two digits) + * > %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) + * > == Milliseconds == + * > %N 008 Milliseconds (three digits) + * > %#N 8 Milliseconds (one to three digits) + * > == Timezone == + * > %O 360 difference in minutes between local time and GMT + * > %Z Mountain Standard Time Name of timezone as reported by browser + * > %G -06:00 Hours and minutes between GMT + * > == Shortcuts == + * > %F 2008-03-26 %Y-%m-%d + * > %T 05:06:30 %H:%M:%S + * > %X 05:06:30 %H:%M:%S + * > %x 03/26/08 %m/%d/%y + * > %D 03/26/08 %m/%d/%y + * > %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y + * > %v 3-Sep-2008 %e-%b-%Y + * > %R 15:31 %H:%M + * > %r 3:31:00 PM %I:%M:%S %p + * > == Characters == + * > %n \n Newline + * > %t \t Tab + * > %% % Percent Symbol + */ + $.jqplot.DateAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.DateAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.DateAxisRenderer.prototype.constructor = $.jqplot.DateAxisRenderer; + + $.jqplot.DateTickFormatter = function(format, val) { + if (!format) { + format = '%Y/%m/%d'; + } + return Date.create(val).strftime(format); + }; + + $.jqplot.DateAxisRenderer.prototype.init = function(options){ + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + // this.tickRenderer = $.jqplot.AxisTickRenderer; + // this.labelRenderer = $.jqplot.AxisLabelRenderer; + this.tickOptions.formatter = $.jqplot.DateTickFormatter; + this.daTickInterval = null; + this._daTickInterval = null; + $.extend(true, this, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + d[j][1] = Date.create(d[j][1]).getTime(); + pd[j][1] = Date.create(d[j][1]).getTime(); + sd[j][1] = Date.create(d[j][1]).getTime(); + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + }; + + // called with scope of an axis + $.jqplot.DateAxisRenderer.prototype.reset = function() { + this.min = this._min; + this.max = this._max; + this.tickInterval = this._tickInterval; + this.numberTicks = this._numberTicks; + this.daTickInterval = this._daTickInterval; + // this._ticks = this.__ticks; + }; + + $.jqplot.DateAxisRenderer.prototype.createTicks = function() { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim, interval; + var min, max; + var pos1, pos2; + var tt, i; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0; i 200) { + this.numberTicks = parseInt(3+(dim-200)/100, 10); + } + else { + this.numberTicks = 2; + } + } + + if (this.daTickInterval == null) { + this.daTickInterval = [range / (this.numberTicks-1)/1000, 'seconds']; + } + for (var i=0; ic.max||c.max==null){c.max=l[e][0]}}else{l[e][1]=Date.create(l[e][1]).getTime();b[e][1]=Date.create(l[e][1]).getTime();k[e][1]=Date.create(l[e][1]).getTime();if(l[e][1]c.max||c.max==null){c.max=l[e][1]}}}}};a.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._min;this.max=this._max;this.tickInterval=this._tickInterval;this.numberTicks=this._numberTicks;this.daTickInterval=this._daTickInterval};a.jqplot.DateAxisRenderer.prototype.createTicks=function(){var v=this._ticks;var r=this.ticks;var w=this.name;var u=this._dataBounds;var o,s;var m,p;var d,c;var b,q;if(r.length){for(q=0;q200){this.numberTicks=parseInt(3+(o-200)/100,10)}else{this.numberTicks=2}}}if(this.daTickInterval==null){this.daTickInterval=[j/(this.numberTicks-1)/1000,"seconds"]}for(var q=0;q= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); + drag.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; + } + mr.color = drag.color; + mr.init(); + + var start = (neighbor.pointIndex > 0) ? neighbor.pointIndex - 1 : 0; + var end = neighbor.pointIndex+2; + drag._gridData = s.gridData.slice(start, end); + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (plot.plugins.dragable.dragCanvas.isDragging) { + var dc = plot.plugins.dragable.dragCanvas; + var dp = dc._neighbor; + var s = plot.series[dp.seriesIndex]; + var drag = s.plugins.dragable; + var gd = s.gridData; + + // compute the new grid position with any constraints. + var x = (drag.constrainTo == 'y') ? dp.gridData[0] : gridpos.x; + var y = (drag.constrainTo == 'x') ? dp.gridData[1] : gridpos.y; + + // compute data values for any listeners. + var xu = s._xaxis.series_p2u(x); + var yu = s._yaxis.series_p2u(y); + + // clear the canvas then redraw effect at new position. + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + + // adjust our gridData for the new mouse position + if (dp.pointIndex > 0) { + drag._gridData[1] = [x, y]; + } + else { + drag._gridData[0] = [x, y]; + } + plot.series[dp.seriesIndex].draw(dc._ctx, {gridData:drag._gridData, shadow:false, preventJqPlotSeriesDrawTrigger:true, color:drag.color, markerOptions:{color:drag.color, shadow:false}, trendline:{show:false}}); + plot.target.trigger('jqplotSeriesPointChange', [dp.seriesIndex, dp.pointIndex, [xu,yu], [x,y]]); + } + else if (neighbor != null) { + var series = plot.series[neighbor.seriesIndex]; + if (series.isDragable) { + var dc = plot.plugins.dragable.dragCanvas; + if (!dc.isOver) { + dc._cursors.push(ev.target.style.cursor); + ev.target.style.cursor = "pointer"; + } + dc.isOver = true; + } + } + else if (neighbor == null) { + var dc = plot.plugins.dragable.dragCanvas; + if (dc.isOver) { + ev.target.style.cursor = dc._cursors.pop(); + dc.isOver = false; + } + } + } + + function handleDown(ev, gridpos, datapos, neighbor, plot) { + var dc = plot.plugins.dragable.dragCanvas; + dc._cursors.push(ev.target.style.cursor); + if (neighbor != null) { + var s = plot.series[neighbor.seriesIndex]; + var drag = s.plugins.dragable; + if (s.isDragable && !dc.isDragging) { + dc._neighbor = neighbor; + dc.isDragging = true; + initDragPoint(plot, neighbor); + drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx); + ev.target.style.cursor = "move"; + } + } + // Just in case of a hickup, we'll clear the drag canvas and reset. + else { + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + dc.isDragging = false; + } + } + + function handleUp(ev, gridpos, datapos, neighbor, plot) { + if (plot.plugins.dragable.dragCanvas.isDragging) { + var dc = plot.plugins.dragable.dragCanvas; + // clear the canvas + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + dc.isDragging = false; + // redraw the series canvas at the new point. + var dp = dc._neighbor; + var s = plot.series[dp.seriesIndex]; + var drag = s.plugins.dragable; + // compute the new grid position with any constraints. + var x = (drag.constrainTo == 'y') ? dp.data[0] : datapos[s.xaxis]; + var y = (drag.constrainTo == 'x') ? dp.data[1] : datapos[s.yaxis]; + // var x = datapos[s.xaxis]; + // var y = datapos[s.yaxis]; + s.data[dp.pointIndex] = [x,y]; + plot.drawSeries({preventJqPlotSeriesDrawTrigger:true}, dp.seriesIndex); + dc._neighbor = null; + ev.target.style.cursor = dc._cursors.pop(); + } + } +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.dragable.min.js b/js/jquery/jqplot-plugins/jqplot.dragable.min.js new file mode 100644 index 0000000000..dd13ec3af5 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.dragable.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(d){d.jqplot.Dragable=function(g){this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.shapeRenderer=new d.jqplot.ShapeRenderer();this.isDragging=false;this.isOver=false;this._ctx;this._elem;this._point;this._gridData;this.color;this.constrainTo="none";d.extend(true,this,g)};function b(){d.jqplot.GenericCanvas.call(this);this.isDragging=false;this.isOver=false;this._neighbor;this._cursors=[]}b.prototype=new d.jqplot.GenericCanvas();b.prototype.constructor=b;d.jqplot.Dragable.parseOptions=function(i,h){var g=h||{};this.plugins.dragable=new d.jqplot.Dragable(g.dragable);this.isDragable=d.jqplot.config.enablePlugins};d.jqplot.Dragable.postPlotDraw=function(){this.plugins.dragable={previousCursor:"auto",isOver:false};this.plugins.dragable.dragCanvas=new b();this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding,"jqplot-dragable-canvas",this._plotDimensions));var g=this.plugins.dragable.dragCanvas.setContext()};d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Dragable.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Dragable.postPlotDraw);d.jqplot.eventListenerHooks.push(["jqplotMouseMove",e]);d.jqplot.eventListenerHooks.push(["jqplotMouseDown",c]);d.jqplot.eventListenerHooks.push(["jqplotMouseUp",a]);function f(n,p){var q=n.series[p.seriesIndex];var m=q.plugins.dragable;var h=q.markerRenderer;var i=m.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+2.5;i.size=h.size+5;if(!m.color){var l=d.jqplot.getColorComponents(h.color);var o=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);m.color="rgba("+o[0]+","+o[1]+","+o[2]+","+k+")"}i.color=m.color;i.init();var g=(p.pointIndex>0)?p.pointIndex-1:0;var j=p.pointIndex+2;m._gridData=q.gridData.slice(g,j)}function e(o,l,h,t,m){if(m.plugins.dragable.dragCanvas.isDragging){var u=m.plugins.dragable.dragCanvas;var i=u._neighbor;var w=m.series[i.seriesIndex];var k=w.plugins.dragable;var r=w.gridData;var p=(k.constrainTo=="y")?i.gridData[0]:l.x;var n=(k.constrainTo=="x")?i.gridData[1]:l.y;var g=w._xaxis.series_p2u(p);var q=w._yaxis.series_p2u(n);var v=u._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);if(i.pointIndex>0){k._gridData[1]=[p,n]}else{k._gridData[0]=[p,n]}m.series[i.seriesIndex].draw(u._ctx,{gridData:k._gridData,shadow:false,preventJqPlotSeriesDrawTrigger:true,color:k.color,markerOptions:{color:k.color,shadow:false},trendline:{show:false}});m.target.trigger("jqplotSeriesPointChange",[i.seriesIndex,i.pointIndex,[g,q],[p,n]])}else{if(t!=null){var j=m.series[t.seriesIndex];if(j.isDragable){var u=m.plugins.dragable.dragCanvas;if(!u.isOver){u._cursors.push(o.target.style.cursor);o.target.style.cursor="pointer"}u.isOver=true}}else{if(t==null){var u=m.plugins.dragable.dragCanvas;if(u.isOver){o.target.style.cursor=u._cursors.pop();u.isOver=false}}}}}function c(k,i,g,l,j){var m=j.plugins.dragable.dragCanvas;m._cursors.push(k.target.style.cursor);if(l!=null){var o=j.series[l.seriesIndex];var h=o.plugins.dragable;if(o.isDragable&&!m.isDragging){m._neighbor=l;m.isDragging=true;f(j,l);h.markerRenderer.draw(o.gridData[l.pointIndex][0],o.gridData[l.pointIndex][1],m._ctx);k.target.style.cursor="move"}}else{var n=m._ctx;n.clearRect(0,0,n.canvas.width,n.canvas.height);m.isDragging=false}}function a(m,j,g,o,k){if(k.plugins.dragable.dragCanvas.isDragging){var p=k.plugins.dragable.dragCanvas;var q=p._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);p.isDragging=false;var h=p._neighbor;var r=k.series[h.seriesIndex];var i=r.plugins.dragable;var n=(i.constrainTo=="y")?h.data[0]:g[r.xaxis];var l=(i.constrainTo=="x")?h.data[1]:g[r.yaxis];r.data[h.pointIndex]=[n,l];k.drawSeries({preventJqPlotSeriesDrawTrigger:true},h.seriesIndex);p._neighbor=null;m.target.style.cursor=p._cursors.pop()}}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.highlighter.js b/js/jquery/jqplot-plugins/jqplot.highlighter.js new file mode 100644 index 0000000000..4e7dca7d72 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.highlighter.js @@ -0,0 +1,359 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); + + /** + * Class: $.jqplot.Highlighter + * Plugin which will highlight data points when they are moused over. + * + * To use this plugin, include the js + * file in your source: + * + * > + * + * A tooltip providing information about the data point is enabled by default. + * To disable the tooltip, set "showTooltip" to false. + * + * You can control what data is displayed in the tooltip with various + * options. The "tooltipAxes" option controls wether the x, y or both + * data values are displayed. + * + * Some chart types (e.g. hi-low-close) have more than one y value per + * data point. To display the additional values in the tooltip, set the + * "yvalues" option to the desired number of y values present (3 for a hlc chart). + * + * By default, data values will be formatted with the same formatting + * specifiers as used to format the axis ticks. A custom format code + * can be supplied with the tooltipFormatString option. This will apply + * to all values in the tooltip. + * + * For more complete control, the "formatString" option can be set. This + * Allows conplete control over tooltip formatting. Values are passed to + * the format string in an order determined by the "tooltipAxes" and "yvalues" + * options. So, if you have a hi-low-close chart and you just want to display + * the hi-low-close values in the tooltip, you could set a formatString like: + * + * > highlighter: { + * > tooltipAxes: 'y', + * > yvalues: 3, + * > formatString:' + * > + * > + * >
    hi:%s
    low:%s
    close:%s
    ' + * > } + * + */ + $.jqplot.Highlighter = function(options) { + // Group: Properties + // + //prop: show + // true to show the highlight. + this.show = $.jqplot.config.enablePlugins; + // prop: markerRenderer + // Renderer used to draw the marker of the highlighted point. + // Renderer will assimilate attributes from the data point being highlighted, + // so no attributes need set on the renderer directly. + // Default is to turn off shadow drawing on the highlighted point. + this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false}); + // prop: showMarker + // true to show the marker + this.showMarker = true; + // prop: lineWidthAdjust + // Pixels to add to the lineWidth of the highlight. + this.lineWidthAdjust = 2.5; + // prop: sizeAdjust + // Pixels to add to the overall size of the highlight. + this.sizeAdjust = 5; + // prop: showTooltip + // Show a tooltip with data point values. + this.showTooltip = true; + // prop: tooltipLocation + // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + this.tooltipLocation = 'nw'; + // prop: tooltipFade + // true = fade in/out tooltip, flase = show/hide tooltip + this.fadeTooltip = true; + // prop: tooltipFadeSpeed + // 'slow', 'def', 'fast', or number of milliseconds. + this.tooltipFadeSpeed = "fast"; + // prop: tooltipOffset + // Pixel offset of tooltip from the highlight. + this.tooltipOffset = 2; + // prop: tooltipAxes + // Which axes to display in tooltip, 'x', 'y' or 'both', 'xy' or 'yx' + // 'both' and 'xy' are equivalent, 'yx' reverses order of labels. + this.tooltipAxes = 'both'; + // prop; tooltipSeparator + // String to use to separate x and y axes in tooltip. + this.tooltipSeparator = ', '; + // prop: useAxesFormatters + // Use the x and y axes formatters to format the text in the tooltip. + this.useAxesFormatters = true; + // prop: tooltipFormatString + // sprintf format string for the tooltip. + // Uses Ash Searle's javascript sprintf implementation + // found here: http://hexmen.com/blog/2007/03/printf-sprintf/ + // See http://perldoc.perl.org/functions/sprintf.html for reference. + // Additional "p" and "P" format specifiers added by Chris Leonello. + this.tooltipFormatString = '%.5P'; + // prop: formatString + // alternative to tooltipFormatString + // will format the whole tooltip text, populating with x, y values as + // indicated by tooltipAxes option. So, you could have a tooltip like: + // 'Date: %s, number of cats: %d' to format the whole tooltip at one go. + // If useAxesFormatters is true, values will be formatted according to + // Axes formatters and you can populate your tooltip string with + // %s placeholders. + this.formatString = null; + // prop: yvalues + // Number of y values to expect in the data point array. + // Typically this is 1. Certain plots, like OHLC, will + // have more y values in each data point array. + this.yvalues = 1; + this._tooltipElem; + this.isHighlighting = false; + + $.extend(true, this, options); + }; + + // axis.renderer.tickrenderer.formatter + + // called with scope of plot + $.jqplot.Highlighter.init = function (target, data, opts){ + var options = opts || {}; + // add a highlighter attribute to the plot + this.plugins.highlighter = new $.jqplot.Highlighter(options.highlighter); + }; + + // called within scope of series + $.jqplot.Highlighter.parseOptions = function (defaults, options) { + this.showHighlight = true; + }; + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + $.jqplot.Highlighter.postPlotDraw = function() { + this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions)); + var hctx = this.plugins.highlighter.highlightCanvas.setContext(); + + var p = this.plugins.highlighter; + p._tooltipElem = $(''); + this.target.append(p._tooltipElem); + }; + + $.jqplot.preInitHooks.push($.jqplot.Highlighter.init); + $.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Highlighter.parseOptions); + $.jqplot.postDrawHooks.push($.jqplot.Highlighter.postPlotDraw); + + function draw(plot, neighbor) { + var hl = plot.plugins.highlighter; + var s = plot.series[neighbor.seriesIndex]; + var smr = s.markerRenderer; + var mr = hl.markerRenderer; + mr.style = smr.style; + mr.lineWidth = smr.lineWidth + hl.lineWidthAdjust; + mr.size = smr.size + hl.sizeAdjust; + var rgba = $.jqplot.getColorComponents(smr.color); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); + mr.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; + mr.init(); + mr.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], hl.highlightCanvas._ctx); + } + + function showTooltip(plot, series, neighbor) { + // neighbor looks like: {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]} + // gridData should be x,y pixel coords on the grid. + // add the plot._gridPadding to that to get x,y in the target. + var hl = plot.plugins.highlighter; + var elem = hl._tooltipElem; + if (hl.useAxesFormatters) { + var xf = series._xaxis._ticks[0].formatter; + var yf = series._yaxis._ticks[0].formatter; + var xfstr = series._xaxis._ticks[0].formatString; + var yfstr = series._yaxis._ticks[0].formatString; + var str; + var xstr = xf(xfstr, neighbor.data[0]); + var ystrs = []; + for (var i=1; i