def test_template_not_found(self): # Python 2.6 compatibility. try: find('missing.txt', self.mlist) except TemplateNotFoundError as error: self.assertEqual(error.template_file, 'missing.txt') else: raise AssertionError('TemplateNotFoundError expected')
def test_site_context_mailman(self): self._manager.set('list:user:notice:welcome', None, 'mailman:///welcome.txt') template_content = self._loader.get('list:user:notice:welcome') path, fp = find('list:user:notice:welcome.txt') try: found_contents = fp.read() finally: fp.close() self.assertEqual(template_content, found_contents)
def mailman_open(self, req): list_manager = getUtility(IListManager) # Parse urls of the form: # # mailman:///<fqdn_listname|list_id>/<language>/<template_name> # # where only the template name is required. mlist = code = template = None # Parse the full requested URL and be sure it's something we handle. original_url = req.get_full_url() parsed = urlparse(original_url) assert parsed.scheme == 'mailman' # The path can contain one, two, or three components. Since no empty # path components are legal, filter them out. parts = [p for p in parsed.path.split('/') if p] if len(parts) == 0: raise URLError('No template specified') elif len(parts) == 1: template = parts[0] elif len(parts) == 2: part0, template = parts # Is part0 a language code or a mailing list? This is rather # tricky because if it's a mailing list, it could be a list-id and # that will contain dots, as could the language code. language = getUtility(ILanguageManager).get(part0) if language is None: # part0 must be a fqdn-listname or list-id. mlist = (list_manager.get(part0) if '@' in part0 else list_manager.get_by_list_id(part0)) if mlist is None: raise URLError('Bad language or list name') else: code = language.code elif len(parts) == 3: part0, code, template = parts # part0 could be an fqdn-listname or a list-id. mlist = (getUtility(IListManager).get(part0) if '@' in part0 else getUtility(IListManager).get_by_list_id(part0)) if mlist is None: raise URLError('Missing list') language = getUtility(ILanguageManager).get(code) if language is None: raise URLError('No such language') code = language.code else: raise URLError('No such file') # Find the template, mutating any missing template exception. try: path, fp = find(template, mlist, code) except TemplateNotFoundError: raise URLError('No such file') return addinfourl(fp, {}, original_url)
def mailman_open(self, req): # Parse urls of the form: # # mailman:///<fqdn_listname>/<language>/<template_name> # # where only the template name is required. mlist = code = template = None # Parse the full requested URL and be sure it's something we handle. original_url = req.get_full_url() parsed = urlparse(original_url) assert parsed.scheme == 'mailman' # The path can contain one, two, or three components. Since no empty # path components are legal, filter them out. parts = filter(None, parsed.path.split('/')) if len(parts) == 0: raise urllib2.URLError('No template specified') elif len(parts) == 1: template = parts[0] elif len(parts) == 2: part0, template = parts # Is part0 a language code or a mailing list? It better be one or # the other, and there's no possibility of namespace collisions # because language codes don't contain @ and mailing list names # MUST contain @. language = getUtility(ILanguageManager).get(part0) mlist = getUtility(IListManager).get(part0) if language is None and mlist is None: raise urllib2.URLError('Bad language or list name') elif mlist is None: code = language.code elif len(parts) == 3: fqdn_listname, code, template = parts mlist = getUtility(IListManager).get(fqdn_listname) if mlist is None: raise urllib2.URLError('Missing list') language = getUtility(ILanguageManager).get(code) if language is None: raise urllib2.URLError('No such language') code = language.code else: raise urllib2.URLError('No such file') # Find the template, mutating any missing template exception. try: path, fp = find(template, mlist, code) except TemplateNotFoundError: raise urllib2.URLError('No such file') return addinfourl(fp, {}, original_url)
def mailman_open(self, req): # Parse urls of the form: # # mailman:///<fqdn_listname>/<language>/<template_name> # # where only the template name is required. mlist = code = template = None # Parse the full requested URL and be sure it's something we handle. original_url = req.get_full_url() parsed = urlparse(original_url) assert parsed.scheme == 'mailman' # The path can contain one, two, or three components. Since no empty # path components are legal, filter them out. parts = [p for p in parsed.path.split('/') if p] if len(parts) == 0: raise URLError('No template specified') elif len(parts) == 1: template = parts[0] elif len(parts) == 2: part0, template = parts # Is part0 a language code or a mailing list? It better be one or # the other, and there's no possibility of namespace collisions # because language codes don't contain @ and mailing list names # MUST contain @. language = getUtility(ILanguageManager).get(part0) mlist = getUtility(IListManager).get(part0) if language is None and mlist is None: raise URLError('Bad language or list name') elif mlist is None: code = language.code elif len(parts) == 3: fqdn_listname, code, template = parts mlist = getUtility(IListManager).get(fqdn_listname) if mlist is None: raise URLError('Missing list') language = getUtility(ILanguageManager).get(code) if language is None: raise URLError('No such language') code = language.code else: raise URLError('No such file') # Find the template, mutating any missing template exception. try: path, fp = find(template, mlist, code) except TemplateNotFoundError: raise URLError('No such file') return addinfourl(fp, {}, original_url)
def find_template(self, request): # XXX We currently only support .txt and .html files. extension = EXTENSIONS.get(self.content_type) if extension is None: return http.not_found() template = self.template + extension fp = None try: try: path, fp = find(template, self.mlist, self.language) except TemplateNotFoundError: return http.not_found() else: return fp.read() finally: if fp is not None: fp.close()
def on_get(self, request, response): # XXX We currently only support .txt and .html files. extension = EXTENSIONS.get(self.content_type) if extension is None: not_found(response) return template = self.template + extension fp = None try: try: path, fp = find(template, self.mlist, self.language) except TemplateNotFoundError: not_found(response) return else: return fp.read() finally: if fp is not None: fp.close()
def test_template_not_found(self): with self.assertRaises(TemplateNotFoundError) as cm: find('missing.txt', self.mlist) self.assertEqual(cm.exception.template_file, 'missing.txt')
def test_find_list_template(self): filename, self.fp = find('list.txt', self.mlist) self.assertEqual(filename, self.xxlist) self.assertEqual(self.fp.read(), 'List template')
def test_find_domain_template(self): filename, self.fp = find('domain.txt', self.mlist) self.assertEqual(filename, self.xxdomain) self.assertEqual(self.fp.read(), 'Domain template')
def test_find_site_template(self): filename, self.fp = find('site.txt', language='xx') self.assertEqual(filename, self.xxsite) self.assertEqual(self.fp.read(), 'Site template')
def get(self, name, context=None, **kws): """See `ITemplateLoader`.""" # Gather some additional information based on the context. substitutions = {} if IMailingList.providedBy(context): mlist = context domain = context.domain lookup_contexts = [ mlist.list_id, mlist.mail_host, None, ] substitutions.update( dict( list_id=mlist.list_id, # For backward compatibility, we call this $listname. listname=mlist.fqdn_listname, domain_name=domain.mail_host, language=mlist.preferred_language.code, )) elif IDomain.providedBy(context): mlist = None domain = context lookup_contexts = [ domain.mail_host, None, ] substitutions['domain_name'] = domain.mail_host elif context is None: mlist = domain = None lookup_contexts = [None] else: raise ValueError('Bad context type: {!r}'.format(context)) # The passed in keyword arguments take precedence. substitutions.update(kws) # See if there's a cached template registered for this name and # context, passing in the url substitutions. This handles http:, # https:, and file: urls. for lookup_context in lookup_contexts: try: contents = getUtility(ITemplateManager).get( name, lookup_context, **substitutions) except (HTTPError, URLError): pass else: if contents is not None: return contents # Fallback to searching within the source code. code = substitutions.get('language', config.mailman.default_language) # Find the template, mutating any missing template exception. missing = object() default_uri = ALL_TEMPLATES.get(name, missing) if default_uri is None: return '' elif default_uri is missing: raise URLError('No such file') path, fp = find(default_uri, mlist, code) try: return fp.read() finally: fp.close()
def get(url, **kws): parsed = urlparse(url) if parsed.scheme in ('http', 'https'): response = requests.get(url, **kws) response.raise_for_status() return response.text if parsed.scheme == 'file': mode = kws.pop('mode', 'r') arguments = dict(mode=mode) if 'encoding' in kws or 'b' not in mode: arguments['encoding'] = kws.pop('encoding', 'utf-8') if len(kws) > 0: raise ValueError('Unexpected arguments: {}'.format( COMMASPACE.join(sorted(kws)))) with open(parsed.path, **arguments) as fp: return fp.read() if parsed.scheme == 'mailman': mlist = code = None if len(kws) > 0: raise ValueError('Unexpected arguments: {}'.format( COMMASPACE.join(sorted(kws)))) # The path can contain one, two, or three components. Since no empty # path components are legal, filter them out. parts = [p for p in parsed.path.split('/') if p] if len(parts) == 0: raise URLError('No template specified') elif len(parts) == 1: template = parts[0] elif len(parts) == 2: part0, template = parts # Is part0 a language code or a mailing list? This is rather # tricky because if it's a mailing list, it could be a list-id and # that will contain dots, as could the language code. language = getUtility(ILanguageManager).get(part0) if language is None: list_manager = getUtility(IListManager) # part0 must be a fqdn-listname or list-id. mlist = (list_manager.get(part0) if '@' in part0 else list_manager.get_by_list_id(part0)) if mlist is None: raise URLError('Bad language or list name') else: code = language.code elif len(parts) == 3: part0, code, template = parts # part0 could be an fqdn-listname or a list-id. mlist = (getUtility(IListManager).get(part0) if '@' in part0 else getUtility(IListManager).get_by_list_id(part0)) if mlist is None: raise URLError('Missing list') language = getUtility(ILanguageManager).get(code) if language is None: raise URLError('No such language') code = language.code else: raise URLError('No such file') # Find the template, mutating any missing template exception. try: path, fp = find(template, mlist, code) except TemplateNotFoundError: raise URLError('No such file') try: return fp.read() finally: fp.close() raise URLError(url)