@@ -51,20 +51,21 @@ 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 | |||
Modify the v170/cgi-bin/webnotes/defs file to your required settings and rename it to defs.py | |||
$ yum install mysql | |||
$ yum install httpd | |||
$ yum install MySQL-python | |||
$ yum install python-setuptools | |||
$ easy_install pytz | |||
$ easy_install email | |||
$ easy_install simplejson suds | |||
$ easy_install pygeoip (optional for geo ip) | |||
$ yum install libjpeg-devel (optional) | |||
$ yum install python-imaging (optional) | |||
- Edit /etc/httpd/conf/httpd.conf and add the options as mentioned above. | |||
- from the trunk/v170/cgi-bin folder run python webnotes/install_lib/install.py install | |||
@@ -1,22 +1,19 @@ | |||
## wnframework | |||
wnframework is a full-stack web application framework that uses python/mysql on the server side. includes a tightly integrated client side library and uses many html5 featuers. | |||
Full-stack web application framework that uses python/mysql on the server side and a tightly integrated client side library. Primarily built for erpnext. | |||
Projects: [erpnext](http://erpnext.org) | [webnotes/erpnext](https://github.com/webnotes/erpnext) | |||
## Version | |||
## Setup | |||
Version 2 is a radical reworking of the wnframework. This will be the current development version. For a stable version see -1.7 branches | |||
- In your application root, set wnframework folder as the "lib" folder. | |||
- Copy index.cgi, build.json, wnf.py in the application root | |||
- update "conf.py" with database, email authentication info | |||
#### Roadmap for version 2 | |||
## wnf.py | |||
- lazy loading + localstorage of js libs (completed) | |||
- refactoring of js library | |||
- separation of the view from the model | |||
## Librarires | |||
wnframework uses a number of libraries in the open domain, see attribution.md (it may not be a complete list but we are working on it!) | |||
wnf.py is the command line utility to build client side files. Usually all client-side files | |||
that are common are build in js/all-web.js (for non logged in users) or js/all-app.js (for logged in users) | |||
## License | |||
@@ -0,0 +1,44 @@ | |||
# app configuration | |||
# database config | |||
db_name = 'yourdbname' | |||
db_password = 'yourdbpassword' | |||
# user attachments stored in | |||
files_path = 'user_files' | |||
# max file attachment size (default 1MB) | |||
max_file_size = 1000000 | |||
# user modules - include in sys.path | |||
modules_path = '.' | |||
# generate schema (.txt files) | |||
developer_mode = 0 | |||
# clear cache on refresh | |||
auto_cache_clear = 0 | |||
# email logs to admin (beta) | |||
admin_email_notification = 0 | |||
# user timezone | |||
user_timezone = 'Asia/Calcutta' | |||
# dump backups here | |||
backup_path = '/backups' | |||
# outgoing mail settings | |||
mail_server = None | |||
mail_login = None | |||
mail_password = None | |||
mail_port = None | |||
use_ssl = None | |||
# logging settings | |||
log_file_name = 'logs/error_log.txt' | |||
debug_log_dbs = [] | |||
log_level = 'logging.INFO' | |||
log_file_size = 5000 | |||
log_file_backup_count = 5 | |||
@@ -1,21 +1,81 @@ | |||
#!/usr/bin/python | |||
# main handler file | |||
#!/usr/bin/env python | |||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||
# | |||
# MIT License (MIT) | |||
# | |||
# 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 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. | |||
# | |||
import cgi, cgitb, os, sys | |||
cgitb.enable() | |||
# import libs | |||
sys.path.append('.') | |||
sys.path.append('lib/py') | |||
sys.path.append('erpnext') | |||
import webnotes | |||
import webnotes.handler | |||
import webnotes.auth | |||
import webnotes.defs | |||
webnotes.form = cgi.FieldStorage() | |||
def init(): | |||
# make the form_dict | |||
webnotes.form = cgi.FieldStorage(keep_blank_values=True) | |||
for key in webnotes.form.keys(): | |||
webnotes.form_dict[key] = webnotes.form.getvalue(key) | |||
# make the form_dict | |||
for key in webnotes.form.keys(): | |||
webnotes.form_dict[key] = webnotes.form.getvalue(key) | |||
# init request | |||
try: | |||
webnotes.http_request = webnotes.auth.HTTPRequest() | |||
return True | |||
except webnotes.AuthenticationError, e: | |||
return True | |||
except webnotes.UnknownDomainError, e: | |||
print "Location: " + (webnotes.defs.redirect_404) | |||
except webnotes.SessionStopped, e: | |||
if 'cmd' in webnotes.form_dict: | |||
webnotes.handler.print_json() | |||
else: | |||
print "Content-Type: text/html" | |||
print """<html> | |||
<body style="background-color: #EEE;"> | |||
<h3 style="width: 900px; background-color: #FFF; border: 2px solid #AAA; padding: 20px; font-family: Arial; margin: 20px auto"> | |||
Updating. | |||
We will be back in a few moments... | |||
</h3> | |||
</body> | |||
</html>""" | |||
# pass on to legacy handler | |||
import webnotes.handler | |||
def respond(): | |||
import webnotes | |||
if 'cmd' in webnotes.form_dict: | |||
webnotes.handler.handle() | |||
else: | |||
import webnotes.cms.index | |||
print "Content-Type: text/html" | |||
webnotes.handler.print_cookies() | |||
print webnotes.cms.index.get() | |||
if __name__=="__main__": | |||
if init(): | |||
respond() |
@@ -28,7 +28,6 @@ | |||
} | |||
</script> | |||
{% endif %} | |||
<script type="text/javascript" src="lib/js/wn/ui/tree.js"></script> | |||
</head> | |||
<body> | |||
{{ body_html }} | |||
@@ -104,10 +104,10 @@ class DocType: | |||
self.change_modified_of_parent() | |||
from webnotes import defs | |||
import conf | |||
from webnotes.utils.transfer import in_transfer | |||
if (not in_transfer) and getattr(webnotes.defs,'developer_mode', 0): | |||
if (not in_transfer) and getattr(conf,'developer_mode', 0): | |||
self.export_doc() | |||
from webnotes.utils.cache import CacheItem | |||
@@ -1,82 +0,0 @@ | |||
# DocType, DocType Label | |||
[ | |||
# These values are common in all dictionaries | |||
{ | |||
'creation': '2012-03-27 14:35:37', | |||
'docstatus': 0, | |||
'modified': '2012-03-27 14:35:37', | |||
'modified_by': u'Administrator', | |||
'owner': u'Administrator' | |||
}, | |||
# These values are common for all DocType | |||
{ | |||
'_last_update': u'1307624201', | |||
'autoname': u'field:dt', | |||
'colour': u'White:FFF', | |||
'doctype': 'DocType', | |||
'module': u'Core', | |||
'name': '__common__', | |||
'section_style': u'Simple', | |||
'server_code_error': u' ', | |||
'version': 2 | |||
}, | |||
# These values are common for all DocField | |||
{ | |||
'doctype': u'DocField', | |||
'name': '__common__', | |||
'parent': u'DocType Label', | |||
'parentfield': u'fields', | |||
'parenttype': u'DocType', | |||
'permlevel': 0, | |||
'reqd': 1 | |||
}, | |||
# These values are common for all DocPerm | |||
{ | |||
'create': 1, | |||
'doctype': u'DocPerm', | |||
'name': '__common__', | |||
'parent': u'DocType Label', | |||
'parentfield': u'permissions', | |||
'parenttype': u'DocType', | |||
'permlevel': 0, | |||
'read': 1, | |||
'role': u'Administrator', | |||
'write': 1 | |||
}, | |||
# DocType, DocType Label | |||
{ | |||
'doctype': 'DocType', | |||
'name': u'DocType Label' | |||
}, | |||
# DocPerm | |||
{ | |||
'doctype': u'DocPerm' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': u'DocField', | |||
'fieldname': u'dt', | |||
'fieldtype': u'Select', | |||
'label': u'Select DocType', | |||
'oldfieldname': u'dt', | |||
'oldfieldtype': u'Select', | |||
'options': u'link:DocType' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': u'DocField', | |||
'fieldname': u'dt_label', | |||
'fieldtype': u'Data', | |||
'label': u'DocType Label', | |||
'oldfieldname': u'dt_label', | |||
'oldfieldtype': u'Data' | |||
} | |||
] |
@@ -293,7 +293,7 @@ class DocType: | |||
""" | |||
If developer_mode = 1, mapper will be written to files | |||
""" | |||
import webnotes.defs | |||
if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: | |||
import conf | |||
if hasattr(conf, 'developer_mode') and conf.developer_mode: | |||
from webnotes.modules.export_module import export_to_files | |||
export_to_files(record_list=[[self.doc.doctype, self.doc.name]]) |
@@ -65,9 +65,9 @@ class DocType: | |||
Writes the .txt for this page and if write_content is checked, | |||
it will write out a .html file | |||
""" | |||
from webnotes import defs | |||
import conf | |||
from webnotes.utils.transfer import in_transfer | |||
if not in_transfer and getattr(defs,'developer_mode', 0) and self.doc.standard=='Yes': | |||
if not in_transfer and getattr(conf,'developer_mode', 0) and self.doc.standard=='Yes': | |||
from webnotes.modules.export_module import export_to_files | |||
from webnotes.modules import get_module_path, scrub | |||
import os | |||
@@ -58,7 +58,8 @@ class DocType: | |||
def export_doc(self): | |||
# export | |||
if self.doc.standard == 'Yes' and getattr(webnotes.defs, 'developer_mode', 0) == 1: | |||
import conf | |||
if self.doc.standard == 'Yes' and getattr(conf, 'developer_mode', 0) == 1: | |||
from webnotes.modules.export_module import export_to_files | |||
export_to_files(record_list=[['Search Criteria', self.doc.name]]) | |||
@@ -107,14 +107,8 @@ def get_index_path(): | |||
return os.sep.join(os.path.dirname(os.path.abspath(__file__)).split(os.sep)[:-2]) | |||
def get_files_path(): | |||
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) | |||
import conf | |||
return conf.files_path | |||
def create_folder(path): | |||
""" | |||
@@ -179,14 +173,14 @@ remote_ip = get_env_vars('REMOTE_ADDR') #Required for login from python shell | |||
logger = None | |||
def get_db_password(db_name): | |||
"""get db password from defs""" | |||
import defs | |||
"""get db password from conf""" | |||
import conf | |||
if hasattr(defs, 'get_db_password'): | |||
return defs.get_db_password(db_name) | |||
if hasattr(conf, 'get_db_password'): | |||
return conf.get_db_password(db_name) | |||
elif hasattr(defs, 'db_password'): | |||
return defs.db_password | |||
elif hasattr(conf, 'db_password'): | |||
return conf.db_password | |||
else: | |||
return db_name | |||
@@ -24,7 +24,7 @@ import webnotes | |||
import webnotes.db | |||
import webnotes.utils | |||
import webnotes.profile | |||
import webnotes.defs | |||
import conf | |||
# ================================================================================= | |||
# HTTPRequest | |||
@@ -91,34 +91,14 @@ class HTTPRequest: | |||
# ------------------ | |||
def get_db_name(self): | |||
# highest priority if comes via form | |||
if webnotes.form_dict.get('ac_name'): | |||
db_name = webnotes.form_dict.get('ac_name') | |||
elif webnotes.form_dict.get('acx'): | |||
db_name = webnotes.form_dict.get('acx') | |||
# then from cookie | |||
elif webnotes.incoming_cookies.get('account_id'): | |||
db_name = webnotes.incoming_cookies.get('account_id') | |||
# then via defs | |||
elif hasattr(webnotes.defs, 'get_db_name'): | |||
db_name = webnotes.defs.get_db_name() | |||
# then default | |||
else: | |||
db_name = getattr(webnotes.defs,'default_db_name','') | |||
if not db_name: | |||
raise Exception, "Unable to resolve database name" | |||
return db_name | |||
"""get database name from conf""" | |||
return conf.db_name | |||
def set_db(self, ac_name = None): | |||
"""connect to db, from ac_name or db_name""" | |||
webnotes.conn = webnotes.db.Database(user = self.get_db_name(), \ | |||
password = getattr(webnotes.defs,'db_password', '')) | |||
password = getattr(conf,'db_password', '')) | |||
# ================================================================================= | |||
# Login Manager | |||
@@ -219,12 +199,6 @@ class LoginManager: | |||
for ip in ip_list: | |||
if webnotes.remote_ip.startswith(ip): | |||
return | |||
elif webnotes.form_dict.get('via_ip'): | |||
if webnotes.form_dict.get('via_ip').startswith(ip): | |||
return | |||
elif (hasattr(webnotes.defs, 'server_ip') and | |||
webnotes.form_dict.get('via_ip').startswith(webnotes.defs.server_ip)): | |||
return | |||
webnotes.msgprint('Not allowed from this IP Address') | |||
raise webnotes.AuthenticationError | |||
@@ -39,10 +39,7 @@ def get_bootinfo(): | |||
import webnotes.model.doc | |||
cp = webnotes.model.doc.getsingle('Control Panel') | |||
import webnotes.defs | |||
from webnotes.utils import cint | |||
cp['sync_with_gateway'] = hasattr(webnotes.defs, 'sync_with_gateway') and \ | |||
cint(webnotes.defs.sync_with_gateway) or 0 | |||
# system info | |||
bootinfo['control_panel'] = cp.copy() | |||
@@ -24,24 +24,24 @@ | |||
# -------------------- | |||
import MySQLdb | |||
from webnotes import defs | |||
import webnotes | |||
import conf | |||
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 | |||
login details from `conf.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=None, user=None, password=None, ac_name=None, use_default = 0): | |||
self.host = host or 'localhost' | |||
self.user = user or getattr(defs, 'default_db_name', '') | |||
self.user = user or getattr(conf, 'default_db_name', '') | |||
if ac_name: | |||
self.user = self.get_db_login(ac_name) or defs.default_db_name | |||
self.user = self.get_db_login(ac_name) or conf.db_name | |||
if use_default: | |||
self.user = defs.default_db_name | |||
self.user = conf.db_name | |||
self.is_testing = 0 | |||
self.in_transaction = 0 | |||
@@ -49,38 +49,14 @@ class Database: | |||
self.testing_tables = [] | |||
self.auto_commit_on_many_writes = 0 | |||
self.password = self.get_db_password(self.user, password) | |||
self.password = password or webnotes.get_db_password(self.user) | |||
self.connect() | |||
if self.user != 'root': | |||
self.use(self.user) | |||
def get_db_password(self, db_name, password): | |||
""" | |||
Return db password. order of importance: | |||
1. password | |||
2. defs.get_db_password() | |||
3. defs.db_password | |||
""" | |||
# password can be empty string | |||
if password: | |||
return password | |||
if hasattr(defs, 'get_db_password'): | |||
return defs.get_db_password(db_name) | |||
if hasattr(defs, 'db_password'): | |||
return defs.db_password | |||
else: | |||
return '' | |||
def get_db_login(self, ac_name): | |||
if hasattr(defs, 'db_name_map'): | |||
return getattr(defs,'db_name_map').get(ac_name, getattr(defs,'default_db_name')) | |||
else: | |||
return ac_name | |||
return ac_name | |||
def connect(self): | |||
""" | |||
@@ -1,141 +0,0 @@ | |||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||
# | |||
# MIT License (MIT) | |||
# | |||
# 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 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. | |||
# | |||
# 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 | |||
# | |||
# Auto Clear Cache: If set, automatically clears cache on refresh | |||
# | |||
auto_cache_clear = 0 | |||
# | |||
# Admin Email Notification: If the admin_email_notification is set, | |||
# then only sent notification email from the system to admin_email_address | |||
# | |||
admin_email_notification = 0 | |||
admin_email_address = 'test@example.com' | |||
# | |||
# Global Send Email: Global email settings, if 1 then only mail will go from the system | |||
# | |||
global_send_email = 1 | |||
# | |||
# 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 | |||
# | |||
# Backup Settings | |||
# | |||
# where the dumps will be stored | |||
backup_path = '/backups' | |||
# where the latest dump will show up so that it can be | |||
# downloaded from the web | |||
backup_link_path = '/var/www/wnframework/backups' | |||
# url to be emailed to the "System Manager" Role to download | |||
# the backup | |||
backup_url = 'http://localhost/backups' |
@@ -22,7 +22,6 @@ | |||
import sys, os | |||
import webnotes | |||
import webnotes.defs | |||
import webnotes.utils | |||
form = webnotes.form | |||
@@ -38,10 +38,10 @@ class DatabaseInstance: | |||
# self.setup_users() | |||
def create_db_and_user(self): | |||
import webnotes.defs | |||
import conf | |||
# 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 USER '%s'@'localhost' IDENTIFIED BY '%s'" % (self.db_name, conf.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") | |||
@@ -22,22 +22,6 @@ | |||
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 | |||
# | |||
@@ -46,7 +30,6 @@ class Installer: | |||
import webnotes | |||
import webnotes.db | |||
import webnotes.defs | |||
self.root_password = root_password | |||
from webnotes.model.db_schema import DbManager | |||
@@ -55,7 +38,6 @@ class Installer: | |||
webnotes.conn=self.conn | |||
webnotes.session= {'user':'Administrator'} | |||
self.dbman = DbManager(self.conn) | |||
self.mysql_path = hasattr(webnotes.defs, 'mysql_path') and webnotes.defs.mysql_path or '' | |||
# | |||
# run framework related cleanups | |||
@@ -167,18 +149,13 @@ class Installer: | |||
""" | |||
Get the db_password by method | |||
""" | |||
import webnotes.defs | |||
if hasattr(webnotes.defs, 'get_db_password'): | |||
return webnotes.defs.get_db_password(db_name) | |||
if hasattr(webnotes.defs, 'db_password'): | |||
return webnotes.defs.db_password | |||
return '' | |||
import conf | |||
return conf.db_password | |||
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. | |||
""" | |||
import webnotes.defs | |||
# delete user (if exists) | |||
self.dbman.delete_user(target) | |||
@@ -223,54 +200,6 @@ class Installer: | |||
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(webnotes.defs,'scheduler_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 | |||
# | |||
@@ -292,31 +221,17 @@ if __name__=='__main__': | |||
parser = get_parser() | |||
(options, args) = parser.parse_args() | |||
try: | |||
import webnotes | |||
import webnotes.db | |||
import webnotes.defs | |||
except ImportError: | |||
copy_defs() | |||
import webnotes | |||
import webnotes.db | |||
import webnotes.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) | |||
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" | |||
print "Database created, please edit conf.py to get started" | |||
else: | |||
parser.print_help() | |||
@@ -359,16 +359,13 @@ class DbManager: | |||
"""get list of databases""" | |||
return [d[0] for d in self.conn.sql("SHOW DATABASES")] | |||
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' | |||
def restore_database(self,target,source,root_password): | |||
from webnotes.utils import make_esc | |||
esc = make_esc('$ ') | |||
try: | |||
ret = os.system("%s -u root -p%s %s < %s"%(mysql, esc(root_password), esc(target), source)) | |||
ret = os.system("mysql -u root -p%s %s < %s" % \ | |||
(esc(root_password), esc(target), source)) | |||
except Exception,e: | |||
raise e | |||
@@ -703,9 +703,8 @@ 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 | |||
import webnotes.model | |||
import webnotes.defs | |||
dn = dn or dt | |||
@@ -22,13 +22,13 @@ def sync_core_doctypes(force=0): | |||
def sync_modules(force=0): | |||
import os | |||
import webnotes.defs | |||
for path, folders, files in os.walk(webnotes.defs.modules_path): | |||
if path == webnotes.defs.modules_path: | |||
import conf | |||
for path, folders, files in os.walk(conf.modules_path): | |||
if path == conf.modules_path: | |||
modules_list = folders | |||
for f in files: | |||
if f.endswith(".txt"): | |||
rel_path = os.path.relpath(path, webnotes.defs.modules_path) | |||
rel_path = os.path.relpath(path, conf.modules_path) | |||
path_tuple = rel_path.split(os.sep) | |||
if (len(path_tuple)==3 and path_tuple[0] in modules_list and | |||
path_tuple[1] == 'doctype'): | |||
@@ -40,14 +40,14 @@ def scrub_dt_dn(dt, dn): | |||
def get_module_path(module): | |||
"""Returns path of the given module""" | |||
import os, webnotes.defs | |||
import os, conf | |||
m = scrub(module) | |||
if m in ('core'): | |||
path_to_lib = os.sep.join(webnotes.defs.modules_path.split(os.path.sep)[:-1]) | |||
path_to_lib = os.sep.join(conf.modules_path.split(os.path.sep)[:-1]) | |||
return os.path.join(path_to_lib, 'lib', 'py', 'core') | |||
else: | |||
return os.path.join(webnotes.defs.modules_path, m) | |||
return os.path.join(conf.modules_path, m) | |||
def reload_doc(module, dt=None, dn=None): | |||
@@ -93,10 +93,10 @@ def export_doc(doctype, name): | |||
def get_all_modules(): | |||
"""Return list of all modules""" | |||
import webnotes.defs | |||
import conf | |||
from webnotes.modules.utils import listfolders | |||
if hasattr(webnotes.defs, 'modules_path'): | |||
return listfolders(webnotes.defs.modules_path, 1) | |||
if hasattr(conf, 'modules_path'): | |||
return listfolders(conf.modules_path, 1) | |||
@@ -23,7 +23,7 @@ | |||
"""get diff bettween txt files and database records""" | |||
import webnotes | |||
import os, webnotes.defs | |||
import os, conf | |||
from webnotes.model.utils import peval_doclist | |||
dt_map = { | |||
@@ -47,7 +47,7 @@ def diff_ref_file(): | |||
missing = property_diff = 0 | |||
property_count = {} | |||
get_diff(webnotes.defs.modules_path) | |||
get_diff(conf.modules_path) | |||
get_diff(os.path.join(os.getcwd(), 'lib', 'py', 'core')) | |||
print_stats() | |||
@@ -71,7 +71,7 @@ def diff_ref_db(): | |||
# get file for this doc | |||
doc['doctype'] = dt | |||
#print doc['name'], doc['doctype'], doc['module'] | |||
path = os.path.join(webnotes.defs.modules_path, scrub(doc['module']), \ | |||
path = os.path.join(conf.modules_path, scrub(doc['module']), \ | |||
scrub(dt), scrub(doc['name']), scrub(doc['name']) + '.txt') | |||
path_core = os.path.join(os.getcwd(), 'lib', 'py', 'core', \ | |||
scrub(dt), scrub(doc['name']), scrub(doc['name']) + '.txt') | |||
@@ -51,10 +51,10 @@ def reload_doc(args): | |||
def run_single(patchmodule=None, method=None, methodargs=None, force=False): | |||
"""run a single patch""" | |||
import webnotes.defs | |||
import conf | |||
# don't write txt files | |||
webnotes.defs.developer_mode = 0 | |||
conf.developer_mode = 0 | |||
if force or method or not executed(patchmodule): | |||
return execute_patch(patchmodule, method, methodargs) | |||
@@ -93,8 +93,8 @@ def execute_patch(patchmodule, method=None, methodargs=None): | |||
def add_to_patch_log(tb): | |||
"""add error log to patches/patch.log""" | |||
import webnotes.defs, os | |||
with open(os.path.join(webnotes.defs.modules_path,'erpnext','patches','patch.log'),'a') as patchlog: | |||
import conf, os | |||
with open(os.path.join(conf.modules_path,'erpnext','patches','patch.log'),'a') as patchlog: | |||
patchlog.write('\n\n' + tb) | |||
def update_patch_log(patchmodule): | |||
@@ -50,13 +50,14 @@ def clear_cache(user=''): | |||
def get(): | |||
"""get session boot info""" | |||
import webnotes.defs | |||
import webnotes | |||
import conf | |||
# get country | |||
country = webnotes.session['data'].get('ipinfo', {}).get('countryName', 'Unknown Country') | |||
# check if cache exists | |||
if not getattr(webnotes.defs,'auto_cache_clear',None): | |||
if not getattr(conf,'auto_cache_clear',None): | |||
cache = load(country) | |||
if cache: | |||
return cache | |||
@@ -1,85 +0,0 @@ | |||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||
# | |||
# MIT License (MIT) | |||
# | |||
# 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 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. | |||
# | |||
""" | |||
Run tests from modules. Sets up database connection, modules path and session before running test | |||
Usage: from shell, run | |||
python tests.py [test modules] | |||
Options: | |||
test modules: list of modules separated by space | |||
if no modules are specified, it will run all "tests.py" files from all modules | |||
""" | |||
import sys, os | |||
import unittest | |||
# webnotes path | |||
sys.path.append('lib/py') | |||
# modules path | |||
import webnotes | |||
import webnotes.defs | |||
if webnotes.defs.__dict__.get('modules_path'): | |||
sys.path.append(webnotes.defs.modules_path) | |||
def get_tests(): | |||
""" | |||
Returns list of test modules identified by "test*.py" | |||
""" | |||
ret = [] | |||
for walk_tuple in os.walk(webnotes.defs.modules_path): | |||
for test_file in filter(lambda x: x.startswith('test') and x.endswith('.py'), walk_tuple[2]): | |||
dir_path = os.path.relpath(walk_tuple[0], webnotes.defs.modules_path) | |||
if dir_path=='.': | |||
ret.append(test_file[:-3]) | |||
else: | |||
ret.append(dir_path.replace('/', '.') + '.' + test_file[:-3]) | |||
return ret | |||
def setup(): | |||
""" | |||
Sets up connection and session | |||
""" | |||
from webnotes.db import Database | |||
webnotes.conn = Database() | |||
webnotes.session = {'user':'Administrator', 'profile':'Administrator'} | |||
if __name__=='__main__': | |||
setup() | |||
if len(sys.argv) > 1: | |||
tests_list = sys.argv[1:] | |||
# for unittest.main | |||
sys.argv = sys.argv[:1] | |||
else: | |||
tests_list = get_tests() | |||
for tests in tests_list: | |||
exec 'from %s import *' % str(tests) | |||
unittest.main() |
@@ -34,7 +34,7 @@ from datetime import datetime | |||
#Global constants | |||
from webnotes.defs import backup_path, backup_link_path | |||
from conf import backup_path, backup_link_path | |||
verbose = 0 | |||
#------------------------------------------------------------------------------- | |||
@@ -98,14 +98,14 @@ class BackupGenerator: | |||
""" | |||
Sends the link to backup file located at erpnext/backups | |||
""" | |||
if hasattr(webnotes.defs, 'backup_url'): | |||
backup_url = webnotes.defs.backup_url | |||
if hasattr(conf, 'backup_url'): | |||
backup_url = conf.backup_url | |||
else: | |||
backup_url = webnotes.conn.get_value('Website Settings', | |||
'Website Settings', 'subdomain') or '' | |||
if hasattr(webnotes.defs, 'backup_folder_name'): | |||
if hasattr(conf, 'backup_folder_name'): | |||
backup_url = os.path.join(backup_url, | |||
webnotes.defs.backup_folder_name) | |||
conf.backup_folder_name) | |||
file_url = os.path.join(backup_url, backup_file) | |||
from webnotes.utils.email_lib import sendmail | |||
@@ -151,29 +151,15 @@ def get_backup(): | |||
This function is executed when the user clicks on | |||
Toos > Download Backup | |||
""" | |||
#if verbose: print webnotes.conn.cur_db_name + " " + webnotes.defs.db_password | |||
#if verbose: print webnotes.conn.cur_db_name + " " + conf.db_password | |||
odb = BackupGenerator(webnotes.conn.cur_db_name, webnotes.conn.cur_db_name,\ | |||
get_db_password(webnotes.conn.cur_db_name)) | |||
webnotes.get_db_password(webnotes.conn.cur_db_name)) | |||
recipient_list = odb.get_backup() | |||
delete_temp_backups() | |||
webnotes.msgprint("""A download link to your backup will be emailed \ | |||
to you shortly on the following email address: | |||
%s""" % (', '.join(recipient_list))) | |||
def get_db_password(db_name): | |||
""" | |||
Get db password from defs | |||
""" | |||
from webnotes import defs | |||
if hasattr(defs, 'get_db_password'): | |||
return defs.get_db_password(db_name) | |||
if hasattr(defs, 'db_password'): | |||
return defs.db_password | |||
def delete_temp_backups(): | |||
""" | |||
Cleans up the backup_link_path directory by deleting files older than 24 hours | |||
@@ -20,11 +20,11 @@ curpath = os.path.dirname(__file__) | |||
sys.path.append(os.path.join(curpath, '..', '..')) | |||
import webnotes | |||
import webnotes.defs | |||
import conf | |||
from webnotes.modules.export_module import export_to_files | |||
from termcolor import colored | |||
sys.path.append(webnotes.defs.modules_path) | |||
sys.path.append(conf.modules_path) | |||
def update_field_property(f, property): | |||
import webnotes | |||
@@ -68,7 +68,7 @@ def replace_code(old, new): | |||
def update_fieldname_patch_file(fdata): | |||
"""update patch file with list""" | |||
with open(webnotes.defs.fieldname_patch_file, 'a') as patchfile: | |||
with open(conf.fieldname_patch_file, 'a') as patchfile: | |||
patchfile.write(str(fdata) + '\n') | |||
def search_replace_with_prompt(fpath, txt1, txt2): | |||
@@ -26,7 +26,7 @@ Allows easy adding of Attachments of "File" objects | |||
""" | |||
import webnotes | |||
import webnotes.defs | |||
import conf | |||
from webnotes import msgprint | |||
import email | |||
@@ -164,11 +164,11 @@ class EMail: | |||
""" | |||
if self.from_defs: | |||
import webnotes | |||
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) | |||
self.server = getattr(conf,'mail_server','') | |||
self.login = getattr(conf,'mail_login','') | |||
self.port = getattr(conf,'mail_port',None) | |||
self.password = getattr(conf,'mail_password','') | |||
self.use_ssl = getattr(conf,'use_ssl',0) | |||
else: | |||
import webnotes.model.doc | |||
@@ -176,11 +176,11 @@ class EMail: | |||
# get defaults from control panel | |||
es = webnotes.model.doc.Document('Email Settings','Email Settings') | |||
self.server = es.outgoing_mail_server.encode('utf-8') or getattr(webnotes.defs,'mail_server','') | |||
self.login = es.mail_login.encode('utf-8') or getattr(webnotes.defs,'mail_login','') | |||
self.port = cint(es.mail_port) or getattr(webnotes.defs,'mail_port',None) | |||
self.password = es.mail_password.encode('utf-8') or getattr(webnotes.defs,'mail_password','') | |||
self.use_ssl = cint(es.use_ssl) or cint(getattr(webnotes.defs, 'use_ssl', '')) | |||
self.server = es.outgoing_mail_server.encode('utf-8') or getattr(conf,'mail_server','') | |||
self.login = es.mail_login.encode('utf-8') or getattr(conf,'mail_login','') | |||
self.port = cint(es.mail_port) or getattr(conf,'mail_port',None) | |||
self.password = es.mail_password.encode('utf-8') or getattr(conf,'mail_password','') | |||
self.use_ssl = cint(es.use_ssl) or cint(getattr(conf, 'use_ssl', '')) | |||
def make_msg(self): | |||
self.msg_root['Subject'] = self.subject | |||
@@ -216,10 +216,6 @@ class EMail: | |||
self.validate() | |||
self.make_msg() | |||
if (not send_now) and getattr(webnotes.defs, 'batch_emails', 0): | |||
self.add_to_queue() | |||
return | |||
sess = self.smtp_connect() | |||
sess.sendmail(self.sender, self.recipients, self.msg_root.as_string()) | |||
@@ -250,82 +246,4 @@ class EMail: | |||
msgprint(ret[1]) | |||
raise Exception | |||
return sess | |||
# =========================================== | |||
# 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() | |||
return sess |
@@ -190,12 +190,12 @@ def save_file(fname, content, module=None): | |||
# ------------------------------------------------------- | |||
def write_file(fid, content): | |||
import os, webnotes.defs | |||
import os, conf | |||
# test size | |||
max_file_size = 1000000 | |||
if hasattr(webnotes.defs, 'max_file_size'): | |||
max_file_size = webnotes.defs.max_file_size | |||
if hasattr(conf, 'max_file_size'): | |||
max_file_size = conf.max_file_size | |||
if len(content) > max_file_size: | |||
raise Exception, 'Maximum File Limit (%s MB) Crossed' % (int(max_file_size / 1000000)) | |||
@@ -113,9 +113,9 @@ def getpage(): | |||
def get_page_path(page_name, module): | |||
"""get path of the page html file""" | |||
import os | |||
import webnotes.defs | |||
import conf | |||
from webnotes.modules import scrub | |||
return os.path.join(webnotes.defs.modules_path, 'erpnext', scrub(module), \ | |||
return os.path.join(conf.modules_path, 'erpnext', scrub(module), \ | |||
'page', scrub(page_name), scrub(page_name) + '.html') | |||
def get_page_html(page_name): | |||