def config(self): '''The :ref:`configuration <configuration>` dictionary for this :class:`App`. Evaluated lazily when :attr:`extensions` are loaded. ''' parser = self.get_parser(with_commands=False, add_help=False) options, _ = parser.parse_known_args(self.meta.argv) config_module = import_module(options.config) if options.config != self.config_module: # Different config file, configure again self.configure(config_module.__file__) # # setup application config = self.setup(config_module, options.debug, options.loglevel, self._params) # # Load extensions self.logger.debug('Setting up extensions') apps = list(config['EXTENSIONS']) add_app(apps, 'lux', 0) add_app(apps, self.meta.name) config['MEDIA_URL'] = remove_double_slash('/%s/' % config['MEDIA_URL']) config['EXTENSIONS'] = tuple(apps) config['EXTENSION_HANDLERS'] = extensions = OrderedDict() for name in config['EXTENSIONS'][1:]: Ext = self.load_extension(name) if Ext: extension = Ext() extensions[extension.meta.name] = extension self.bind_events(extension) config.update( extension.setup(config_module, options.debug, options.loglevel, self._params)) return config
def absolute_path(self, path): '''Return a suitable absolute url for ``path``. The url is calculated in the following way: * Check if ``path`` is an entry in the :attr:`known_libraries` dictionary. In this case replace ``path`` with ``known_libraries[path]``. * If ``path`` :meth:`is_relative` build a sutable url by prepending the :attr:`media_path` attribute. :return: A url path to insert in a HTML ``link`` or ``script``. ''' if path in self.known_libraries: path = self.known_libraries[path] if self.is_relative(path): if self.minified: for media in self.mediatype: media = '.%s' % media if path.endswith(media): path = self._minify(path, media) break return remove_double_slash('/%s/%s' % (self.media_path, path)) else: return path
def absolute_path(self, path, with_media_ending=True): '''Return a suitable absolute url for ``path``. The url is calculated in the following way: * Check if ``path`` is an entry in the :attr:`known_libraries` dictionary. In this case replace ``path`` with ``known_libraries[path]``. * If ``path`` :meth:`is_relative` build a sutable url by prepending the :attr:`media_path` attribute. :return: A url path to insert in a HTML ``link`` or ``script``. ''' urlparams = '' ending = '.%s' % self.mediatype if path in self.known_libraries: lib = self.known_libraries[path] if isinstance(lib, dict): urlparams = lib.get('urlparams', '') lib = lib['url'] path = '%s%s' % (lib, ending) if self.minified: if path.endswith(ending): path = self._minify(path, ending) if not with_media_ending: path = path[:-len(ending)] if urlparams: path = '%s?%s' % (path, urlparams) if self.is_relative(path): return remove_double_slash('/%s/%s' % (self.media_path, path)) else: return path
def config(self): '''The :ref:`configuration <configuration>` dictionary for this :class:`App`. Evaluated lazily when :attr:`extensions` are loaded. ''' parser = self.get_parser(with_commands=False, add_help=False) options, _ = parser.parse_known_args(self.meta.argv) config_module = import_module(options.config) if options.config != self.config_module: # Different config file, configure again self.configure(config_module.__file__) # # setup application config = self.setup(config_module, options.debug, options.loglevel, self._params) # # Load extensions self.logger.debug('Setting up extensions') apps = list(config['EXTENSIONS']) add_app(apps, 'lux', 0) add_app(apps, self.meta.name) config['MEDIA_URL'] = remove_double_slash('/%s/' % config['MEDIA_URL']) config['EXTENSIONS'] = tuple(apps) config['EXTENSION_HANDLERS'] = extensions = OrderedDict() for name in config['EXTENSIONS'][1:]: Ext = self.load_extension(name) if Ext: extension = Ext() extensions[extension.meta.name] = extension self.bind_events(extension) config.update(extension.setup(config_module, options.debug, options.loglevel, self._params)) return config
def middleware(self, app): # API urls not available - no middleware to add if not app.apis: return middleware = [] # Add routers and models routes = OrderedDict() for extension in app.extensions.values(): api_sections = getattr(extension, "api_sections", None) if api_sections: for router in api_sections(app) or (): routes[router.route.path] = router # Allow router override for router in routes.values(): if isinstance(router, RestRouter): # Register model router.model = app.models.register(router.model) if router.model: router.model.api_route = router.route # Add router to API root-router app.apis.add_child(router) # Create the rest-api handler app.api = app.providers["Api"](app) # # Create paginator dotted_path = app.config["PAGINATION"] pagination = module_attribute(dotted_path) if not pagination: raise ImproperlyConfigured('Could not load paginator "%s"', dotted_path) app.pagination = pagination() has_api = False for api in app.apis: # router not required when api is remote if api.netloc: continue has_api = True # # Add API root-router to middleware middleware.append(api.router) url = str(api.router) if url != "/": # when the api is served by a path, make sure 404 is raised # when no suitable routes are found middleware.append(Rest404(remove_double_slash("%s/<path:path>" % url))) # # Add the preflight and token events if has_api: app.add_events(("on_preflight", "on_token")) return middleware
def middleware(self, app): '''Build the API middleware. If :setting:`API_URL` is defined, it loops through all extensions and checks if the ``api_sections`` method is available. ''' middleware = [] url = app.config['API_URL'] if url: app.config['API_URL'] = url = remove_double_slash('/%s/' % url) sections = {} self.api = api = Api(url, sections=sections) middleware.append(api) docs = None url = app.config['API_DOCS_URL'] if url: app.config['API_DOCS_URL'] = url = remove_double_slash('/%s/' % url) self.docs = Router(url, sections=sections) middleware.append(self.docs) # for extension in itervalues(app.extensions): api_sections = getattr(extension, 'api_sections', None) if api_sections: for name, routers in api_sections(app): # Routes must be instances of CRUD # name is the section name if name not in sections: sections[name] = ApiSection() section = sections[name] for router in routers: api.add_child(router) section.append(router) manager = router.manager self.api_crud_routers[manager] = manager url = app.config['ADMIN_URL'] if url: app.config['ADMIN_URL'] = url = remove_double_slash('/%s/' % url) sections = {} admin = Admin(url, sections=sections) middleware.append(admin) #for extension in itervalues(app.extensions): # api_sections = getattr(extension, 'api_sections', None) # if api_sections: # pass return middleware
def url(self, request, path=None): urlp = list(self.urlp) if path: urlp[2] = remove_double_slash('%s/%s' % (urlp[2], str(path))) if not urlp[1]: r_url = urlparse(request.absolute_uri('/')) urlp[0] = r_url.scheme urlp[1] = r_url.netloc return urlunparse(urlp)
def on_html_document(self, app, request, doc): favicon = app.config['FAVICON'] if favicon: parsed = urlparse(favicon) if not parsed.scheme and not parsed.netloc: media = app.config['MEDIA_URL'] if not favicon.startswith(media): favicon = remove_double_slash('%s%s' % (media, favicon)) doc.head.links.append(favicon, rel="icon", type='image/x-icon')
def full_path(self, *args, **query): """Return a full path""" path = None if args: if len(args) > 1: raise TypeError("full_url() takes exactly 1 argument " "(%s given)" % len(args)) path = args[0] if not path: path = self.path elif not path.startswith("/"): path = remove_double_slash("%s/%s" % (self.path, path)) return iri_to_uri(path, query)
def full_path(self, *args, **query): """Return a full path""" path = None if args: if len(args) > 1: raise TypeError("full_url() takes exactly 1 argument " "(%s given)" % len(args)) path = args[0] if not path: path = self.path elif not path.startswith('/'): path = remove_double_slash('%s/%s' % (self.path, path)) return iri_to_uri(path, query)
def add_router(self, router, sitemap=True): if isinstance(router, Content): router = TextCMS(router) if sitemap: path = str(router.route) if path != '/': url = remove_double_slash('%s/sitemap.xml' % path) else: url = '/sitemap1.xml' sitemap = RouterMap(url, content_router=router) self.sitemaps.append(sitemap) self._middleware.append(router)
def full_path(self, *args, **query): '''Return a full path''' path = None if args: if len(args) > 1: raise TypeError("full_url() takes exactly 1 argument " "(%s given)" % len(args)) path = args[0] if path is None: path = self.path if not query: query = self.url_data elif not path.startswith('/'): path = remove_double_slash('%s/%s' % (self.path, path)) return iri_to_uri(path, **query)
def routes(self): """Build the API routes This method generates routes only when it is a server side API """ # # Create paginator dotted_path = self.config['PAGINATION'] pagination = module_attribute(dotted_path) if not pagination: raise ImproperlyConfigured('Could not load paginator "%s"', dotted_path) self.app.pagination = pagination() api_routers = OrderedDict() # Allow router override for extension in self.app.extensions.values(): api_sections = getattr(extension, 'api_sections', None) if api_sections: for router in api_sections(self.app) or (): api_routers[router.route.path] = router for router in api_routers.values(): if isinstance(router, RestRouter): # Register model router.model = self.app.models.register(router.model) if router.model: router.model.api_route = router.route # Add router to an API self.add_child(router) for api in self: # router not required when api is remote if api.netloc: continue # # Add API root-router to middleware router = api.router() yield router url = str(router) if url != '/': # when the api is served by a path, make sure 404 is raised # when no suitable routes are found yield Rest404(remove_double_slash('%s/<path:path>' % url))
def __init__(self, rule, defaults=None): rule = remove_double_slash('/%s' % rule) self.defaults = defaults if defaults is not None else {} self.is_leaf = not rule.endswith('/') self.rule = rule[1:] self.variables = set(map(str, self.defaults)) breadcrumbs = [] self._converters = {} regex_parts = [] if self.rule: for bit in self.rule.split('/'): if not bit: continue s = bit[0] e = bit[-1] if s == '<' or e == '>': if s + e != '<>': raise ValueError('malformed rule {0}'.format( self.rule)) converter, parameters, variable = parse_rule(bit[1:-1]) if variable in self._converters: raise ValueError('variable name {0} used twice in ' 'rule {1}.'.format( variable, self.rule)) convobj = get_converter(converter, parameters) regex_parts.append('(?P<%s>%s)' % (variable, convobj.regex)) breadcrumbs.append((True, variable)) self._converters[variable] = convobj self.variables.add(str(variable)) else: variable = bit regex_parts.append(re.escape(variable)) breadcrumbs.append((False, variable)) self.breadcrumbs = tuple(breadcrumbs) self._regex_string = '/'.join(regex_parts) if self._regex_string and not self.is_leaf: self._regex_string += '/' self._regex = re.compile(self.regex, re.UNICODE)
def __init__(self, rule, defaults=None, is_re=False): rule = remove_double_slash('/%s' % rule) self.defaults = defaults if defaults is not None else {} self.is_leaf = not rule.endswith('/') self.rule = rule[1:] self.variables = set(map(str, self.defaults)) breadcrumbs = [] self._converters = {} regex_parts = [] if self.rule: for bit in self.rule.split('/'): if not bit: continue s = bit[0] e = bit[-1] if s == '<' or e == '>': if s + e != '<>': raise ValueError( 'malformed rule {0}'.format(self.rule)) converter, parameters, variable = parse_rule(bit[1:-1]) if variable in self._converters: raise ValueError('variable name {0} used twice in ' 'rule {1}.'.format(variable, self.rule)) convobj = get_converter(converter, parameters) regex_parts.append('(?P<%s>%s)' % (variable, convobj.regex)) breadcrumbs.append((True, variable)) self._converters[variable] = convobj self.variables.add(str(variable)) else: variable = bit if is_re else re.escape(bit) regex_parts.append(variable) breadcrumbs.append((False, bit)) self.breadcrumbs = tuple(breadcrumbs) self._regex_string = '/'.join(regex_parts) if self._regex_string and not self.is_leaf: self._regex_string += '/' self._regex = re.compile(self.regex, re.UNICODE)
def _build_config(self, module_name): # Check if an extension module is available module = import_module(module_name) self.meta = self.meta.copy(module) if self.meta.name != 'lux': # self.meta.path.add2python(self.meta.name, up=1) extension = self.load_extension(self.meta.name) if extension: # extension available, get the version from it self.meta.version = extension.meta.version # parser = self.get_parser(with_commands=False, add_help=False) opts, _ = parser.parse_known_args(self.meta.argv) config_module = import_module(opts.config) if opts.config != self.config_module: # Different config file, configure again return self._build_config(config_module.__file__) # # setup application config = {} self.setup(config, config_module, self.params, opts) # # Load extensions self.logger.debug('Setting up extensions') apps = list(config['EXTENSIONS']) add_app(apps, 'lux', 0) add_app(apps, self.meta.name) media_url = config['MEDIA_URL'] if media_url: config['MEDIA_URL'] = remove_double_slash('/%s/' % media_url) config['EXTENSIONS'] = tuple(apps) config['EXTENSION_HANDLERS'] = extensions = OrderedDict() for name in config['EXTENSIONS'][1:]: Ext = self.load_extension(name) if Ext: extension = Ext() extensions[extension.meta.name] = extension self.bind_events(extension) extension.setup(config, config_module, self.params) return config
def absolute_path(self, path, with_media_ending=True): '''Return a suitable absolute url for ``path``. The url is calculated in the following way: * Check if ``path`` is an entry in the :attr:`known_libraries` dictionary. In this case replace ``path`` with ``known_libraries[path]``. * If ``path`` :meth:`is_relative` build a sutable url by prepending the :attr:`media_path` attribute. :return: A url path to insert in a HTML ``link`` or ``script``. ''' ending = '.%s' % self.mediatype minify = True urlparams = '' if isinstance(path, dict): urlparams = path.get('urlparams', urlparams) minify = path.get('minify', minify) path = path['url'] if path in self.known_libraries: lib = self.known_libraries[path] if isinstance(lib, dict): urlparams = lib.get('urlparams', '') minify = lib.get('minify', minify) lib = lib['url'] path = '%s%s' % (lib, ending) if self.minified and minify: if path.endswith(ending): path = self._minify(path, ending) if not with_media_ending: path = path[:-len(ending)] if urlparams: path = '%s?%s' % (path, urlparams) if self.is_relative(path): return remove_double_slash('%s/%s' % (self.media_path, path)) else: return path
def api_url(cls, path=None): if 'API_URL' in cls.app.config: url = cls.app.config['API_URL'] return remove_double_slash('%s/%s' % (url, path)) if path else url
def middleware(self, app): # API urls not available - no middleware to add if not app.apis: return middleware = [] # Add routers and models routes = OrderedDict() for extension in app.extensions.values(): api_sections = getattr(extension, 'api_sections', None) if api_sections: for router in api_sections(app) or (): routes[router.route.path] = router # Allow router override for router in routes.values(): if isinstance(router, RestRouter): # Register model router.model = app.models.register(router.model) if router.model: router.model.api_route = router.route # Add router to API root-router app.apis.add_child(router) # Create the rest-api handler app.api = app.providers['Api'](app) # # Create paginator dotted_path = app.config['PAGINATION'] pagination = module_attribute(dotted_path) if not pagination: raise ImproperlyConfigured('Could not load paginator "%s"', dotted_path) app.pagination = pagination() has_api = False for api in app.apis: # router not required when api is remote if api.netloc: continue has_api = True # # Add API root-router to middleware middleware.append(api.router) url = str(api.router) if url != '/': # when the api is served by a path, make sure 404 is raised # when no suitable routes are found middleware.append( Rest404(remove_double_slash('%s/<path:path>' % url))) # # Add the preflight and token events if has_api: app.add_events(('on_preflight', 'on_token')) return middleware
def _path(self, request, path): '''Append extension to file name ''' return remove_double_slash('/%s/%s' % (self.url, path))