comparison roundup/instance.py @ 4588:7017c8dd704c

Small improvements on instance.py by Cheer Xiao. - _load_python split into three functions: _compile, _exec and _execfile, mimicing corresponding builtin functions; also the os.path fiddling is isolated to _exec, the motivation being that lib/ should be available for interfaces.py besides extensions and detectors. - all variables named `vars` are renamed to `env` as "vars" shadows the builtin with the same name.
author Ralf Schlatterbeck <rsc@runtux.com>
date Fri, 24 Feb 2012 10:00:09 +0100
parents a2eb4fb3e6d8
children 7b7cfb4b00eb
comparison
equal deleted inserted replaced
4587:a2eb4fb3e6d8 4588:7017c8dd704c
33 from roundup import configuration, mailgw 33 from roundup import configuration, mailgw
34 from roundup import hyperdb, backends, actions 34 from roundup import hyperdb, backends, actions
35 from roundup.cgi import client, templating 35 from roundup.cgi import client, templating
36 from roundup.cgi import actions as cgi_actions 36 from roundup.cgi import actions as cgi_actions
37 37
38 class Vars:
39 def __init__(self, vars):
40 self.__dict__.update(vars)
41
42 class Tracker: 38 class Tracker:
43 def __init__(self, tracker_home, optimize=0): 39 def __init__(self, tracker_home, optimize=0):
44 """New-style tracker instance constructor 40 """New-style tracker instance constructor
45 41
46 Parameters: 42 Parameters:
61 self.cgi_actions = {} 57 self.cgi_actions = {}
62 self.templating_utils = {} 58 self.templating_utils = {}
63 self.load_interfaces() 59 self.load_interfaces()
64 self.templates = templating.get_templates(self.config["TEMPLATES"], self.config["TEMPLATE_ENGINE"]) 60 self.templates = templating.get_templates(self.config["TEMPLATES"], self.config["TEMPLATE_ENGINE"])
65 self.backend = backends.get_backend(self.get_backend_name()) 61 self.backend = backends.get_backend(self.get_backend_name())
62
63 libdir = os.path.join(self.tracker_home, 'lib')
64 self.libdir = os.path.isdir(libdir) and libdir or ''
65
66 if self.optimize: 66 if self.optimize:
67 libdir = os.path.join(self.tracker_home, 'lib')
68 if os.path.isdir(libdir):
69 sys.path.insert(1, libdir)
70 self.templates.precompileTemplates() 67 self.templates.precompileTemplates()
71 # initialize tracker extensions 68 # initialize tracker extensions
72 for extension in self.get_extensions('extensions'): 69 for extension in self.get_extensions('extensions'):
73 extension(self) 70 extension(self)
74 # load database schema 71 # load database schema
75 schemafilename = os.path.join(self.tracker_home, 'schema.py') 72 self.schema = self._compile('schema.py')
76 # Note: can't use built-in open()
77 # because of the global function with the same name
78 schemafile = file(schemafilename, 'rt')
79 self.schema = compile(schemafile.read(), schemafilename, 'exec')
80 schemafile.close()
81 # load database detectors 73 # load database detectors
82 self.detectors = self.get_extensions('detectors') 74 self.detectors = self.get_extensions('detectors')
83 # db_open is set to True after first open() 75 # db_open is set to True after first open()
84 self.db_open = 0 76 self.db_open = 0
85 if libdir in sys.path:
86 sys.path.remove(libdir)
87 77
88 def get_backend_name(self): 78 def get_backend_name(self):
89 f = file(os.path.join(self.config.DATABASE, 'backend_name')) 79 f = file(os.path.join(self.config.DATABASE, 'backend_name'))
90 name = f.readline().strip() 80 name = f.readline().strip()
91 f.close() 81 f.close()
95 # load the database schema 85 # load the database schema
96 # we cannot skip this part even if self.optimize is set 86 # we cannot skip this part even if self.optimize is set
97 # because the schema has security settings that must be 87 # because the schema has security settings that must be
98 # applied to each database instance 88 # applied to each database instance
99 backend = self.backend 89 backend = self.backend
100 vars = { 90 env = {
101 'Class': backend.Class, 91 'Class': backend.Class,
102 'FileClass': backend.FileClass, 92 'FileClass': backend.FileClass,
103 'IssueClass': backend.IssueClass, 93 'IssueClass': backend.IssueClass,
104 'String': hyperdb.String, 94 'String': hyperdb.String,
105 'Password': hyperdb.Password, 95 'Password': hyperdb.Password,
110 'Boolean': hyperdb.Boolean, 100 'Boolean': hyperdb.Boolean,
111 'Number': hyperdb.Number, 101 'Number': hyperdb.Number,
112 'db': backend.Database(self.config, name) 102 'db': backend.Database(self.config, name)
113 } 103 }
114 104
115 libdir = os.path.join(self.tracker_home, 'lib')
116 if os.path.isdir(libdir):
117 sys.path.insert(1, libdir)
118 if self.optimize: 105 if self.optimize:
119 # execute preloaded schema object 106 # execute preloaded schema object
120 exec(self.schema, vars) 107 exec(self.schema, env)
121 if callable (self.schema_hook): 108 if callable (self.schema_hook):
122 self.schema_hook(**vars) 109 self.schema_hook(**env)
123 # use preloaded detectors 110 # use preloaded detectors
124 detectors = self.detectors 111 detectors = self.detectors
125 else: 112 else:
126 # execute the schema file 113 # execute the schema file
127 self._load_python('schema.py', vars) 114 self._execfile('schema.py', env)
128 if callable (self.schema_hook): 115 if callable (self.schema_hook):
129 self.schema_hook(**vars) 116 self.schema_hook(**env)
130 # reload extensions and detectors 117 # reload extensions and detectors
131 for extension in self.get_extensions('extensions'): 118 for extension in self.get_extensions('extensions'):
132 extension(self) 119 extension(self)
133 detectors = self.get_extensions('detectors') 120 detectors = self.get_extensions('detectors')
134 if libdir in sys.path: 121 db = env['db']
135 sys.path.remove(libdir)
136 db = vars['db']
137 # apply the detectors 122 # apply the detectors
138 for detector in detectors: 123 for detector in detectors:
139 detector(db) 124 detector(db)
140 # if we are running in debug mode 125 # if we are running in debug mode
141 # or this is the first time the database is opened, 126 # or this is the first time the database is opened,
166 self.db_open = 1 151 self.db_open = 1
167 return db 152 return db
168 153
169 def load_interfaces(self): 154 def load_interfaces(self):
170 """load interfaces.py (if any), initialize Client and MailGW attrs""" 155 """load interfaces.py (if any), initialize Client and MailGW attrs"""
171 vars = {} 156 env = {}
172 if os.path.isfile(os.path.join(self.tracker_home, 'interfaces.py')): 157 if os.path.isfile(os.path.join(self.tracker_home, 'interfaces.py')):
173 self._load_python('interfaces.py', vars) 158 self._execfile('interfaces.py', env)
174 self.Client = vars.get('Client', client.Client) 159 self.Client = env.get('Client', client.Client)
175 self.MailGW = vars.get('MailGW', mailgw.MailGW) 160 self.MailGW = env.get('MailGW', mailgw.MailGW)
176 self.TemplatingUtils = vars.get('TemplatingUtils', templating.TemplatingUtils) 161 self.TemplatingUtils = env.get('TemplatingUtils', templating.TemplatingUtils)
177 162
178 def get_extensions(self, dirname): 163 def get_extensions(self, dirname):
179 """Load python extensions 164 """Load python extensions
180 165
181 Parameters: 166 Parameters:
191 if os.path.isdir(dirpath): 176 if os.path.isdir(dirpath):
192 sys.path.insert(1, dirpath) 177 sys.path.insert(1, dirpath)
193 for name in os.listdir(dirpath): 178 for name in os.listdir(dirpath):
194 if not name.endswith('.py'): 179 if not name.endswith('.py'):
195 continue 180 continue
196 vars = {} 181 env = {}
197 self._load_python(os.path.join(dirname, name), vars) 182 self._execfile(os.path.join(dirname, name), env)
198 extensions.append(vars['init']) 183 extensions.append(env['init'])
199 sys.path.remove(dirpath) 184 sys.path.remove(dirpath)
200 return extensions 185 return extensions
201 186
202 def init(self, adminpw): 187 def init(self, adminpw):
203 db = self.open('admin') 188 db = self.open('admin')
204 self._load_python('initial_data.py', {'db': db, 'adminpw': adminpw, 189 self._execfile('initial_data.py', {'db': db, 'adminpw': adminpw,
205 'admin_email': self.config['ADMIN_EMAIL']}) 190 'admin_email': self.config['ADMIN_EMAIL']})
206 db.commit() 191 db.commit()
207 db.close() 192 db.close()
208 193
209 def exists(self): 194 def exists(self):
210 return self.backend.db_exists(self.config) 195 return self.backend.db_exists(self.config)
211 196
212 def nuke(self): 197 def nuke(self):
213 self.backend.db_nuke(self.config) 198 self.backend.db_nuke(self.config)
214 199
215 def _load_python(self, file, vars): 200 def _compile(self, fname):
216 file = os.path.join(self.tracker_home, file) 201 fname = os.path.join(self.tracker_home, fname)
217 execfile(file, vars) 202 return compile(file(fname).read(), fname, 'exec')
218 return vars 203
204 def _exec(self, obj, env):
205 if self.libdir:
206 sys.path.insert(1, self.libdir)
207 exec(obj, env)
208 if self.libdir:
209 sys.path.remove(self.libdir)
210 return env
211
212 def _execfile(self, fname, env):
213 self._exec(self._compile(fname), env)
219 214
220 def registerAction(self, name, action): 215 def registerAction(self, name, action):
221 216
222 # The logic here is this: 217 # The logic here is this:
223 # * if `action` derives from actions.Action, 218 # * if `action` derives from actions.Action,

Roundup Issue Tracker: http://roundup-tracker.org/