Mercurial > p > roundup > code
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, |
