def test_run_something(self): vm = VirtualModule('example', _CODE) self.assertEqual(vm.dir(), ['run_me', 'run_me2']) res = vm.call('run_me', 'test') self.assertEqual(res, 'Test') res = vm.doc('run_me') self.assertEqual(res, 'Will capitalize.')
def __init__(self, location=None, rbr_content=_RBR, app_content=_APP, context=None, name='undefined'): """ location contains the application, composed of: + an app.rbr file + an app.py file If location is not provided, will look into the current dir """ if location is not None and os.path.exists(location): self.root = location else: self.root = os.getcwd() self.name = name # rbr file self.rbr_file = os.path.join(self.root, '%s.rbr' % self.name) if os.path.exists(self.rbr_file): with open(self.rbr_file) as f: self.rbr_content = f.read() else: self.rbr_content = rbr_content # rbr file self.app_file = os.path.join(self.root, '%s.py' % self.name) if os.path.exists(self.app_file): with open(self.app_file) as f: self.app_content = f.read() else: self.app_content = app_content # XXX see how to do this in a more elegant way old = sys.path[:] sys.path.insert(0, self.root) try: self.module = VirtualModule(self.name, self.app_content) finally: sys.path[:] = old self.root_path = '' self.context = context self._load_rbr() self._commitmapper()
def _main(self, request): if request.path == '/__main__': tmpl = os.path.join(_HERE, 'templates', 'main.mako') with open(tmpl) as f: tmpl = Template(f.read()) return tmpl.render(appviews=self.appviews, libraries=self.libraries) if request.path == '/__main__/add' and request.method == 'POST': def _name2path(name): # MORE CHARS path = name.lower() path = path.replace(' ', '') return '/' + path data = {} name = data['name'] = request.POST['name'] data['root'] = _name2path(data['name']) data['description'] = request.POST['description'] rbr = _DEFAULT_APP % data code = _DEFAULT_CODE location = os.path.join(_APPS, name) os.mkdir(location) appview = AppView(wsgiapp=self, location=location, rbr=rbr, code=code, name=name) appview.generate() self.appviews.append((appview.get_root(), appview)) self.appviews.sort(by_len) # XXX url = 'http://%s%s/__editor__' % (request.environ['HTTP_HOST'], appview.get_root()) return HTTPFound(location=url) if request.path == '/__main__/addlib' and request.method == 'POST': # loading a new lib name = request.POST['name'] file_ = request.POST['file'] if hasattr(file_, 'file'): code = file_.file.read() else: code = '' self.libraries.append(VirtualModule(name, code)) # XXX url = 'http://%s/__lib__/%s' % (request.environ['HTTP_HOST'], name) return HTTPFound(location=url) return self._404()
def _load_libs(self): libs = [] for element in os.listdir(self.libdir): path = os.path.join(self.libdir, element) name = os.path.split(path)[-1] name, ext = os.path.splitext(name) type_ = ext[1:] with open(path) as f: content = f.read() libs.append(VirtualModule(name, content, type_)) return libs
def __init__(self, location=None, rbr_content=_RBR, app_content=_APP, context=None, name='undefined'): """ location contains the application, composed of: + an app.rbr file + an app.py file If location is not provided, will look into the current dir """ if location is not None and os.path.exists(location): self.root = location else: self.root = os.getcwd() # rbr file self.rbr_file = os.path.join(self.root, 'app.rbr') if os.path.exists(self.rbr_file): with open(self.rbr_file) as f: self.rbr_content = f.read() else: self.rbr_content = rbr_content # rbr file self.name = name self.app_file = os.path.join(self.root, '%s.py' % self.name) if os.path.exists(self.app_file): with open(self.app_file) as f: self.app_content = f.read() else: self.app_content = app_content self.module = VirtualModule('app', self.app_content) self.root_path = '' self.context = context self._load_rbr() self._commitmapper()
class RedBarrelApplication(object): def __init__(self, location=None, rbr_content=_RBR, app_content=_APP, context=None, name='undefined'): """ location contains the application, composed of: + an app.rbr file + an app.py file If location is not provided, will look into the current dir """ if location is not None and os.path.exists(location): self.root = location else: self.root = os.getcwd() self.name = name # rbr file self.rbr_file = os.path.join(self.root, '%s.rbr' % self.name) if os.path.exists(self.rbr_file): with open(self.rbr_file) as f: self.rbr_content = f.read() else: self.rbr_content = rbr_content # rbr file self.app_file = os.path.join(self.root, '%s.py' % self.name) if os.path.exists(self.app_file): with open(self.app_file) as f: self.app_content = f.read() else: self.app_content = app_content # XXX see how to do this in a more elegant way old = sys.path[:] sys.path.insert(0, self.root) try: self.module = VirtualModule(self.name, self.app_content) finally: sys.path[:] = old self.root_path = '' self.context = context self._load_rbr() self._commitmapper() def update_code(self, data): self.app_content = data self.module.update(data) def sync(self): # saving the RBR file with open(self.rbr_file, 'w') as f: # XXX should be str all the time if isinstance(self.rbr_content, unicode): self.rbr_content = self.rbr_content.encode('utf-8') f.write(self.rbr_content) # saving the Python file with open(self.app_file, 'w') as f: f.write(self.app_content) def _commitmapper(self): self._rbr_content = None self._app_content = None self._ast = None self._globs = None self._types = None self._mapper = None self.sync() def _backupmapper(self): self._rbr_content = self.rbr_content self._app_content = self.app_content self._ast = self.ast self._globs = self.globs self._types = self.types self._mapper = self.mapper def _rollbackmapper(self): if self._rbr_content is None: raise ValueError("Nothing to rollback") self.rbr_content = self._rbr_content self._app_content = self.app_content self.ast = self._ast self.globs = self._globs self.types = self._types self.mapper = self._mapper def _load_rbr(self, load_ast=True): if load_ast: self.ast = build_ast(self.rbr_content) # looking for the root path for definition in self.ast: if definition.type != 'root': continue self.root_path = definition.value break self.globs = self._create_globs() self.types = self._create_types() self.mapper = WebMapper(self) def _resolve_def(self, value, *args, **kw): if not isinstance(value, str): return value prefixed = value.split(':', 1) if prefixed[0] not in get_runner_names(): return value res = resolve_runner(value, self.root)(*args, **kw) if value == res: raise ImportError(value) else: value = res return value def _create_types(self): # reads the types definitions and loads them types = {} logger.info('Initializing types...') for definition in self.ast: if definition.type != 'type': continue name = definition.left types[name] = self._resolve_def(definition.right) return types def _create_globs(self): # reads the globs definitions and loads them globs = {} logger.info('Initializing globs...') for definition in self.ast: if definition.type != 'global': continue name = definition.left value = definition.right.value globs[name] = self._resolve_def(value, copy.copy(globs)) return globs def generate(self): logger.info('Generating the Web App...') for definition in self.ast: type_ = definition.type if type_ == 'meta': self.mapper.set_options(definition.value) continue elif type_ in _NONPATH: continue name = definition.left args = definition.right #print name #print args #if len(definition) > 2: # args = definition[2] #else: # args = [] self.mapper.add(name, args) logger.info('...ready') logger.info('') def __call__(self, request): return self.mapper(request) def get_options(self): return self.mapper.options def set_options(self, options): self.mapper.set_options(options) def add_def(self, name, definition): self.mapper.add(name, definition) def del_def(self, name): new_ast = [] for definition in self.ast: if definition.type == 'def' and definition.left == name: continue new_ast.append(definition) if len(new_ast) < len(self.ast): self.ast = new_ast self._load_rbr(load_ast=False) self.generate() def add_content(self, content): # syntax check try: ast = build_ast(content) except Exception, e: raise SyntaxError(e) if ast is None: raise SyntaxError() # actual ast change self._backupmapper() try: self.rbr_content += '\n%s' % content self._load_rbr() self.generate() self._commitmapper() except Exception: self._rollbackmapper() raise