import os, types, string from myghty.resolver import ResolverRule import myghty.csource as csource import myghty.component as comp from myghty.resolver import Resolution import myghty.importer as importer import routes from routes.base import * class RoutesComponentSource(csource.ModuleComponentSource): def __init__(self, objpath, module): self.objpath = objpath self.module = module arg = module for t in objpath: arg = getattr(arg, t) name = "method:" + string.join(objpath, '_') self.has_method = True last_modified = importer.mod_time(module) csource.ComponentSource.__init__(self, "module|%s:%s" % (module.__name__, name), last_modified = last_modified) self.module = module self.objpath = objpath self.name = name self.class_ = RoutesComponent self.callable_ = arg def reload(self, module): self.module = module arg = module for t in self.objpath: arg = getattr(arg, t) self.callable_ = arg def can_compile(self): return False class RoutesComponent(comp.FunctionComponent): def do_run_component(self, **params): m = params['m'] r = params['r'] # do stuff with routes config config = routes.request_config() config.redirect = m.send_redirect config.host = r.headers_in['host'].split(':')[0] if r.environ.get('HTTPS'): config.protocol = 'https' else: config.protocol = 'http' # update params with routes resolution args if hasattr(m, 'resolution'): params.update(m.resolution.override_args) # if we are linked to a method off of an object instance, # see if the object instance has a do_run_component method and run it if self.component_source.has_method: target = self.component_source.callable_.im_self if hasattr(target, 'do_run_component'): getattr(target, 'do_run_component')(**params) return comp.FunctionComponent.do_run_component(self, **params) class RoutesResolver(ResolverRule): name = 'routeresolver' def _find_controllers(self, dirname, prefix=''): controllers = [] for fname in os.listdir(dirname): filename = dirname + '/' + fname if os.path.isfile(filename) and fname.endswith('_controller.py') and not fname.startswith('application_'): controllers.append(prefix + fname) elif os.path.isdir(filename): controllers.extend(self._find_controllers(filename, prefix=fname+'/')) return controllers def _get_controllers(self): clist = {} controllers = self._find_controllers(self.controller_root) for con in controllers: key = con[:-14] # Remove _controller.py clist[key] = self.controller_root + '/' + con return clist def __init__(self, mapper=None, controller_root=None, **params): self.mapper = mapper self.controller_root = controller_root def do_init_resolver(self, resolver, remaining_rules, **params): self.clist = self._get_controllers() self.mapper.create_regs(self.clist.keys()) def do(self, uri, remaining, resolution_detail, **params): if resolution_detail is not None: resolution_detail.append("resolverouteresolver:" + uri) if os.environ['MYGHTY_ENV'] == 'development': self.clist = self._get_controllers() self.mapper.create_regs(self.clist.keys()) match = self.mapper.match(uri) if match: controller = match['controller'] action = match['action'] if action.startswith('_'): return remaining.next().do(uri, remaining, resolution_detail, **params) # Load up the request local singleton config config = routes.request_config() config.mapper = self.mapper config.mapper_dict = match.copy() # Remove the action/controller, rest of the args pass to the function del match['action'] del match['controller'] filename = self.clist[controller] classname = controller.split('/')[-1].lower() module = importer.filemodule(filename) resolution_detail.append("\nController:%s, Action:%s" % (controller, action)) cs = RoutesComponentSource( module=module, objpath=[classname, action], ) #raise repr(cs.__dict__) return Resolution(cs, resolution_detail, override_args = match) else: return remaining.next().do(uri, remaining, resolution_detail, **params)