cleanup of modules
This commit is contained in:
parent
ae2f0d0377
commit
f7ee372c97
10 changed files with 342 additions and 649 deletions
|
|
@ -0,0 +1,53 @@
|
|||
class BaseModel:
|
||||
"""
|
||||
New style models will be inherited from this base model class
|
||||
This will contain methods for save update
|
||||
|
||||
Standard attributes:
|
||||
_type
|
||||
_id
|
||||
_created_by
|
||||
_created_on
|
||||
_modified_by
|
||||
_modified_on
|
||||
"""
|
||||
def __init__(self, model_type = None, model_id = None, attributes = {}):
|
||||
self._type = model_type
|
||||
self._id = model_id
|
||||
if attributes:
|
||||
self.__dict__.update(attributes)
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""
|
||||
Getter is overridden so that it does not throw an exception
|
||||
"""
|
||||
if name in self.__dict__:
|
||||
return self.__dict__[name]
|
||||
else:
|
||||
return None
|
||||
|
||||
def _read(self):
|
||||
"""
|
||||
Read
|
||||
"""
|
||||
self.__dict__.update(webnotes.conn.sql("""
|
||||
select * from `%s` where _id=%s
|
||||
""", (self._type, self._id), as_dict=1)[0])
|
||||
|
||||
def _create(self):
|
||||
"""
|
||||
Create
|
||||
"""
|
||||
pass
|
||||
|
||||
def _update(self):
|
||||
"""
|
||||
Update
|
||||
"""
|
||||
pass
|
||||
|
||||
def _delete(self):
|
||||
"""
|
||||
Delete
|
||||
"""
|
||||
pass
|
||||
|
|
@ -54,25 +54,16 @@ def execute(code, doc=None, doclist=[]):
|
|||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -240,9 +240,7 @@ class _DocType:
|
|||
* 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():
|
||||
|
|
@ -263,8 +261,10 @@ class _DocType:
|
|||
|
||||
else:
|
||||
doclist = self._load_from_cache()
|
||||
|
||||
doclist[0].fields['__client_script'] = compress.get_doctype_js(self.name)
|
||||
|
||||
from webnotes.modules import Module
|
||||
doc = doclist[0]
|
||||
doc.fields['__client_script'] = Module(doc.module).get_doc_file('doctype', doc.name, '.js').read()
|
||||
self._load_select_options(doclist)
|
||||
self._clear_code(doclist)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ transfer_types = ['Role', 'Print Format','DocType','Page','DocType Mapper','GL M
|
|||
def scrub(txt):
|
||||
return txt.replace(' ','_').replace('-', '_').replace('/', '_').lower()
|
||||
|
||||
def scrub_dt_and_dn(dt, dn):
|
||||
def scrub_dt_dn(dt, dn):
|
||||
"""
|
||||
Returns in lowercase and code friendly names of doctype and name for certain types
|
||||
"""
|
||||
|
|
@ -22,7 +22,7 @@ def get_item_file(module, dt, dn):
|
|||
Returns the path of the item file
|
||||
"""
|
||||
import os
|
||||
ndt, ndn = scrub_dt_and_dn(dt, dn)
|
||||
ndt, ndn = scrub_dt_dn(dt, dn)
|
||||
|
||||
return os.path.join(get_module_path(module), ndt, ndn, ndn + '.txt')
|
||||
|
||||
|
|
@ -39,71 +39,128 @@ def get_module_path(module):
|
|||
Returns path of the given module (imports it and reads it from __file__)
|
||||
"""
|
||||
return Module(module).get_path()
|
||||
|
||||
def switch_module(dt, dn, to, frm=None, export=None):
|
||||
|
||||
def get_doc_path(dt, dn, module=None):
|
||||
"""
|
||||
Change the module of the given doctype, if export is true, then also export txt and copy
|
||||
code files from src
|
||||
Return the path to a particular doc folder
|
||||
"""
|
||||
import os
|
||||
webnotes.conn.sql("update `tab"+dt+"` set module=%s where name=%s", (to, dn))
|
||||
|
||||
if not module:
|
||||
if dt=='Module Def':
|
||||
module=dn
|
||||
else:
|
||||
module = webnotes.conn.get_value(dt, dn, 'module')
|
||||
|
||||
if export:
|
||||
export_doc(dt, dn)
|
||||
ndt, ndn = scrub_dt_dn(dt, dn)
|
||||
|
||||
# copy code files
|
||||
if dt in ('DocType', 'Page', 'Search Criteria'):
|
||||
from_path = os.path.join(get_module_path(frm), scrub(dt), scrub(dn), scrub(dn))
|
||||
to_path = os.path.join(get_module_path(to), scrub(dt), scrub(dn), scrub(dn))
|
||||
return os.path.join(get_module_path(module), ndt, ndn)
|
||||
|
||||
# make dire if exists
|
||||
os.system('mkdir -p %s' % os.path.join(get_module_path(to), scrub(dt), scrub(dn)))
|
||||
|
||||
for ext in ('py','js','html','css'):
|
||||
os.system('cp %s %s')
|
||||
def reload_doc(module, dt, dn):
|
||||
"""
|
||||
Sync a file from txt to module
|
||||
Alias for::
|
||||
Module(module).reload(dt, dn)
|
||||
"""
|
||||
Module(module).reload(dt, dn)
|
||||
|
||||
|
||||
class ModuleManager:
|
||||
"""
|
||||
Module manager class, used to run functions on all modules
|
||||
"""
|
||||
|
||||
def get_all_modules(self):
|
||||
"""
|
||||
Return list of all modules
|
||||
"""
|
||||
import webnotes.defs
|
||||
from webnotes.modules.utils import listfolders
|
||||
|
||||
if hasattr(webnotes.defs, 'modules_path'):
|
||||
return listfolders(webnotes.defs.modules_path, 1)
|
||||
|
||||
|
||||
class Module:
|
||||
"""
|
||||
Represents a module in the framework
|
||||
Represents a module in the framework, has classes for syncing files
|
||||
"""
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.path = None
|
||||
self.sync_types = ['txt','sql']
|
||||
self.code_types = ['js','css','py','html','sql']
|
||||
|
||||
def get_path(self):
|
||||
"""
|
||||
Returns path of the module (imports it and reads it from __file__)
|
||||
"""
|
||||
import webnotes.defs, os
|
||||
if not self.path:
|
||||
|
||||
try:
|
||||
exec ('import ' + scrub(self.name)) in locals()
|
||||
modules_path = eval(scrub(self.name) + '.__file__')
|
||||
import webnotes.defs, os
|
||||
|
||||
modules_path = os.path.sep.join(modules_path.split(os.path.sep)[:-1])
|
||||
except ImportError, e:
|
||||
modules_path = os.path.join(webnotes.defs.modules_path, scrub(self.name))
|
||||
|
||||
return modules_path
|
||||
try:
|
||||
# by import
|
||||
exec ('import ' + scrub(self.name)) in locals()
|
||||
self.path = eval(scrub(self.name) + '.__file__')
|
||||
self.path = os.path.sep.join(self.path.split(os.path.sep)[:-1])
|
||||
except ImportError, e:
|
||||
# force
|
||||
self.path = os.path.join(webnotes.defs.modules_path, scrub(self.name))
|
||||
|
||||
return self.path
|
||||
|
||||
def get_doc_file(self, dt, dn, extn='.txt'):
|
||||
"""
|
||||
Return file of a doc
|
||||
"""
|
||||
dt, dn = scrub_dt_dn(dt, dn)
|
||||
return self.get_file(dt, dn, dn + extn)
|
||||
|
||||
def get_file(self, *path):
|
||||
"""
|
||||
Returns ModuleFile object, in path specifiy the package name and file name
|
||||
For example::
|
||||
Module('accounts').get_file('doctype','account.txt')
|
||||
Module('accounts').get_file('doctype','account','account.txt')
|
||||
"""
|
||||
return ModuleFile(self, os.path.join(self.get_path(), os.path.join(*path)))
|
||||
import os
|
||||
path = os.path.join(self.get_path(), os.path.join(*path))
|
||||
if path.endswith('.txt'):
|
||||
return TxtModuleFile(path)
|
||||
if path.endswith('.sql'):
|
||||
return SqlModuleFile(path)
|
||||
if path.endswith('.js'):
|
||||
return JsModuleFile(path)
|
||||
else:
|
||||
return ModuleFile(path)
|
||||
|
||||
def reload(self, dt, dn):
|
||||
"""
|
||||
Sync the file to the db
|
||||
"""
|
||||
dt, dn = scrub_dt_dn(dt, dn)
|
||||
self.get_file(dt, dn, dn + '.txt').sync()
|
||||
|
||||
def sync_all(self):
|
||||
"""
|
||||
Walk through all the files in the modules and sync all files
|
||||
"""
|
||||
import os
|
||||
ret = []
|
||||
for walk_tuple in os.walk(self.get_path()):
|
||||
for f in walk_tuple[2]:
|
||||
if f.split('.')[-1] in self.sync_types:
|
||||
self.get_file(os.path.join(walk_tuple[0], f)).sync()
|
||||
|
||||
class ModuleFile:
|
||||
"""
|
||||
Module file class
|
||||
Module file class.
|
||||
|
||||
Module files can be dynamically generated by specifying first line is "#!python"
|
||||
the output
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = os.path.join(*path)
|
||||
self.path = path
|
||||
|
||||
def is_new(self):
|
||||
"""
|
||||
|
|
@ -144,8 +201,109 @@ class ModuleFile:
|
|||
insert into __file_timestamp(file_name, tstamp)
|
||||
values (%s, %s) on duplicate key update""", (self.path, self.timestamp))
|
||||
|
||||
def load_content(self):
|
||||
"""
|
||||
returns file contents
|
||||
"""
|
||||
try:
|
||||
f = open(self.path,'r')
|
||||
self.content = f.read()
|
||||
f.close()
|
||||
except IOError, e:
|
||||
if e.args[0]==2:
|
||||
self.content = ''
|
||||
else:
|
||||
raise e
|
||||
|
||||
return self.content
|
||||
|
||||
def read(self, do_execute = None):
|
||||
"""
|
||||
Return the file content, if dynamic, execute it
|
||||
"""
|
||||
self.load_content()
|
||||
if do_execute and self.content.startswith('#!python'):
|
||||
from webnotes.model.code import execute
|
||||
self.content = execute(self.content)
|
||||
|
||||
return self.content
|
||||
|
||||
|
||||
class TxtModuleFile(ModuleFile):
|
||||
"""
|
||||
Class for .txt files, sync the doclist in the txt file into the database
|
||||
"""
|
||||
def __init__(self, path):
|
||||
ModuleFile.__init__(self, path)
|
||||
|
||||
def sync(self):
|
||||
"""
|
||||
import the doclist if new
|
||||
"""
|
||||
if self.is_new():
|
||||
|
||||
from webnotes.model.utils import peval_doclist
|
||||
doclist = peval_doclist(self.read())
|
||||
|
||||
if doclist:
|
||||
from webnotes.utils.transfer import set_doc
|
||||
set_doc(doclist, 1, 1, 1)
|
||||
|
||||
self.update()
|
||||
|
||||
class SqlModuleFile(ModuleFile):
|
||||
def __init__(self, path):
|
||||
ModuleFile.__init__(self, path)
|
||||
|
||||
def sync(self):
|
||||
"""
|
||||
execute the sql if new
|
||||
"""
|
||||
if self.is_new():
|
||||
content = mf.read()
|
||||
|
||||
# execute everything but selects
|
||||
if content.strip().split()[0].lower()!='select':
|
||||
webnotes.conn.sql(mf.read())
|
||||
|
||||
mf.update()
|
||||
|
||||
class JsModuleFile(ModuleFile):
|
||||
"""
|
||||
JS File. read method will read file and replace all $import() with relevant code
|
||||
Example::
|
||||
$import(accounts/common.js)
|
||||
"""
|
||||
def __init__(self, path):
|
||||
ModuleFile.__init__(self, path)
|
||||
|
||||
def get_js(self, match):
|
||||
"""
|
||||
New style will expect file path or doctype
|
||||
|
||||
"""
|
||||
name = match.group('name')
|
||||
import webnotes.defs, os
|
||||
|
||||
if '/' in name:
|
||||
path = os.path.join(webnotes.defs.modules_path, name)
|
||||
else:
|
||||
# its a doctype
|
||||
path = os.path.join(get_doc_path('DocType', name), name + '.js')
|
||||
|
||||
return JSModuleFile(path).read()
|
||||
|
||||
def read(self):
|
||||
"""
|
||||
Return the file content
|
||||
return js content (replace $imports if needed)
|
||||
"""
|
||||
return open(self.path,'r').read()
|
||||
self.load_content()
|
||||
code = self.content
|
||||
|
||||
if code and code.strip():
|
||||
import re
|
||||
p = re.compile('\$import\( (?P<name> [^)]*) \)', re.VERBOSE)
|
||||
|
||||
code = p.sub(self.get_js, code)
|
||||
|
||||
return code
|
||||
|
|
@ -1,343 +0,0 @@
|
|||
"""
|
||||
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
|
||||
from webnotes.utils import 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<name> [^)]*) \)', 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<name> [^)]*) \)', 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()
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
Export files to modules
|
||||
"""
|
||||
|
||||
from webnotes.modules import scrub, get_module_path
|
||||
|
||||
def export_to_files(record_list=[], record_module=None, verbose=0):
|
||||
|
|
@ -106,8 +110,3 @@ def clear_code_fields(doclist, folder, code_type):
|
|||
|
||||
doclist[0][code_field[0]] = None
|
||||
|
||||
def to_sandbox(record_list=[], record_module='Sandbox'):
|
||||
"""
|
||||
Export record_list to Sandbox. record_list is a list of lists ([doctype],[docname] ) ,
|
||||
"""
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
"""
|
||||
Imports Documents from modules (.txt) files in the filesystem
|
||||
"""
|
||||
|
||||
import webnotes
|
||||
|
||||
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', '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)
|
||||
|
||||
def get_doclist(path, doctype, docname):
|
||||
"returns a doclist (list of dictionaries) of multiple records for the given parameters"
|
||||
import os
|
||||
from webnotes.model.utils import peval_doclist
|
||||
|
||||
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 = peval_doclist(f.read())
|
||||
f.close()
|
||||
return dl
|
||||
else:
|
||||
return None
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -1,163 +1,13 @@
|
|||
"""
|
||||
Deprecated: Will be deleted
|
||||
"""
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# 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
|
||||
from webnotes.modules import reload_doc
|
||||
reload_doc(module, dt, dn)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#==============================================================================
|
||||
|
||||
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
|
||||
37
cgi-bin/webnotes/modules/utils.py
Normal file
37
cgi-bin/webnotes/modules/utils.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
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
|
||||
|
||||
def switch_module(dt, dn, to, frm=None, export=None):
|
||||
"""
|
||||
Change the module of the given doctype, if export is true, then also export txt and copy
|
||||
code files from src
|
||||
"""
|
||||
import os
|
||||
webnotes.conn.sql("update `tab"+dt+"` set module=%s where name=%s", (to, dn))
|
||||
|
||||
if export:
|
||||
export_doc(dt, dn)
|
||||
|
||||
# copy code files
|
||||
if dt in ('DocType', 'Page', 'Search Criteria'):
|
||||
from_path = os.path.join(get_module_path(frm), scrub(dt), scrub(dn), scrub(dn))
|
||||
to_path = os.path.join(get_module_path(to), scrub(dt), scrub(dn), scrub(dn))
|
||||
|
||||
# make dire if exists
|
||||
os.system('mkdir -p %s' % os.path.join(get_module_path(to), scrub(dt), scrub(dn)))
|
||||
|
||||
for ext in ('py','js','html','css'):
|
||||
os.system('cp %s %s')
|
||||
|
|
@ -14,45 +14,68 @@ class Page:
|
|||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def get_from_files(self, doc):
|
||||
def get_from_files(self, doc, module):
|
||||
"""
|
||||
Loads page info from files in module
|
||||
"""
|
||||
from webnotes.modules import compress
|
||||
from webnotes.model.code import get_code
|
||||
|
||||
# load js
|
||||
doc.fields['__script'] = compress.get_page_js(doc)
|
||||
doc.fields['__script'] = module.get_doc_file('page',doc.name,'.js').read()
|
||||
doc.script = None
|
||||
|
||||
# load css
|
||||
css = get_code(doc.module, 'page', doc.name, 'css')
|
||||
css = module.get_doc_file('page',doc.name,'.css').read()
|
||||
if css: doc.style = css
|
||||
|
||||
# html
|
||||
doc.content = get_code(doc.module, 'page', doc.name, 'html') or doc.content
|
||||
doc.content = module.get_doc_file('page',doc.name,'.html').read() or doc.content
|
||||
|
||||
def get_template(self, template):
|
||||
"""
|
||||
Returns the page template content
|
||||
"""
|
||||
ret = '%(content)s'
|
||||
# load code from template
|
||||
if template:
|
||||
from webnotes.modules import Module
|
||||
ret = Module(webnotes.conn.get_value('Page Template', template, 'module'))\
|
||||
.get_doc_file('Page Template', template, '.html').read()
|
||||
if not ret:
|
||||
ret = webnotes.conn.get_value('Page Template', template, 'template')
|
||||
|
||||
return ret
|
||||
|
||||
def process_content(self, doc):
|
||||
"""
|
||||
Put in template and generate dynamic if starts with #!python
|
||||
"""
|
||||
template = self.get_template(doc.template)
|
||||
content = ''
|
||||
|
||||
# eval content
|
||||
if doc.content and doc.content.startswith('#!python'):
|
||||
from webnotes.model.code import execute
|
||||
content = template % {'content': execute(doc.content).get('content')}
|
||||
else:
|
||||
content = template % {'content': doc.content or ''}
|
||||
|
||||
doc.__content = content
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Returns :term:`doclist` of the `Page`
|
||||
"""
|
||||
from webnotes.model.code import get_code
|
||||
from webnotes.modules import Module
|
||||
|
||||
doclist = webnotes.model.doc.get('Page', self.name)
|
||||
doc = doclist[0]
|
||||
|
||||
if doc.module: self.get_from_files(doc)
|
||||
# load from module
|
||||
if doc.module:
|
||||
module = Module(doc.module)
|
||||
self.get_from_files(doc, module)
|
||||
|
||||
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')
|
||||
|
||||
# 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 ''}
|
||||
# process
|
||||
self.process_content(doc)
|
||||
|
||||
# add stylesheet
|
||||
if doc.stylesheet:
|
||||
|
|
@ -66,16 +89,15 @@ class Page:
|
|||
loaded = eval(webnotes.form_dict.get('stylesheets') or '[]')
|
||||
if not stylesheet in loaded:
|
||||
import webnotes.model.doc
|
||||
from webnotes.model.code import get_code
|
||||
from webnotes.modules import Module
|
||||
|
||||
# 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
|
||||
css = Module(sslist[0].module).get_doc_file('Stylesheet', stylesheet, '.css').read()
|
||||
|
||||
if css: sslist[0].stylesheet = css
|
||||
return sslist
|
||||
else:
|
||||
return []
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue