def get_diffs(self, req, title, old_text, new_text): diff_style, diff_options, diff_data = get_diff_options(req) diff_context = 3 for option in diff_options: if option.startswith('-U'): diff_context = int(option[2:]) break if diff_context < 0: diff_context = None diffs = diff_blocks(old_text.splitlines(), new_text.splitlines(), context=diff_context, tabwidth=2, ignore_blank_lines=True, ignore_case=True, ignore_space_changes=True) chrome = Chrome(self.env) loader = TemplateLoader(chrome.get_all_templates_dirs()) tmpl = loader.load('diff_div.html') changes=[{'diffs': diffs, 'props': [], 'title': title, 'new': {'path':"", 'rev':'', 'shortrev': '', 'href':''}, 'old': {'path':"", 'rev':'', 'shortrev': '', 'href': ''}}] data = chrome.populate_data(req, { 'changes':changes , 'no_id':True, 'diff':diff_data, 'longcol': '', 'shortcol': ''}) diff_data['style']='sidebyside'; data.update({ 'changes':changes , 'no_id':True, 'diff':diff_data, 'longcol': '', 'shortcol': ''}) stream = tmpl.generate(**data) return stream.render()
def command(self): config=load_config(self.args) path_genshi= config.get('exportanag.path_genshi') opath= config.get('exportanag.path_out') print path_genshi loader_genshi = TemplateLoader([path_genshi], auto_reload=True) if self.options.run: reparti = DBSession.query(Reparti).all() rep_dict = {} prods = {} for r in reparti: rep = slugify(r.reparto) values = [] print "========", rep prodotti = DBSession.query(Prodotti).filter_by(numeroreparto=r.numeroreparto).order_by(Prodotti.descrizioneestesa).all() for p in prodotti: desc = p.descrizioneestesa if not desc: desc = p.prodotto values.append([p.eans[0].codicebilancia, desc]) print "%4s %s"%(p.eans[0].codicebilancia,desc ) tmpl = loader_genshi.load('index.html') print "STREAM" stream = tmpl.generate(r=r, values=values) print "RENDER" s = stream.render('html', doctype='xhtml', encoding='utf-8') output_html = open(os.path.join(opath,rep+'.html'), 'w') print "WRITE" output_html.write(s) print "written %s"%(os.path.join(opath,rep+'.html'))
def run(self): ''' class for (test) orderprint; delevers a valid html-file. Uses a kid-template for the enveloping/merging. use kid to write; no envelope grammar is used ''' try: from genshi.template import TemplateLoader except: txt=botslib.txtexc() raise ImportError(_(u'Dependency failure: editype "template" requires python library "genshi". Error:\n%s'%txt)) defmessage = grammar.grammarread(self.ta_info['editype'],self.ta_info['messagetype']) #needed because we do not know envelope; read syntax for editype/messagetype self.ta_info.update(defmessage.syntax) botslib.tryrunscript(self.userscript,self.scriptname,'ta_infocontent',ta_info=self.ta_info) if not self.ta_info['envelope-template']: raise botslib.OutMessageError(_(u'While enveloping in "$editype.$messagetype": syntax option "envelope-template" not filled; is required.'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype']) templatefile = botslib.abspath('templateshtml',self.ta_info['envelope-template']) ta_list = self.filelist2absolutepaths() try: botsglobal.logger.debug(u'Start writing envelope to file "%s".',self.ta_info['filename']) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt=botslib.txtexc() raise botslib.OutMessageError(_(u'While enveloping in "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) try: f = botslib.opendata(self.ta_info['filename'],'wb') stream = tmpl.generate(data=ta_list) stream.render(method='xhtml',encoding=self.ta_info['charset'],out=f) except: txt=botslib.txtexc() raise botslib.OutMessageError(_(u'While enveloping in "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt)
class BaseController(WSGIController): def __init__(self): self.loader = TemplateLoader( os.path.join(os.path.dirname(os.path.dirname(__file__)), 'templates'), auto_reload=True ) def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] return WSGIController.__call__(self, environ, start_response) # TODO: add support for jurisdictions def license2xml(self, license, locale='en'): """Turn a cc.license.License object into XML""" tmpl = self.loader.load('license.xml') html = cc.license.formatters.HTML.format(license, locale=locale) stream = tmpl.generate(license=license, locale=locale, license_html=html) return stream.render(method='xml') def generate_error(self, id, msg): tmpl = self.loader.load('error.xml') stream = tmpl.generate(id=id, msg=msg) return stream.render(method='xml')
def __init__(self): self.data = { 'releases': [], 'releases_featured': [], 'releases_older': [], 'releases_beta': [], 'themes': [], 'news': [], 'blogs': [], 'issues': [], 'base_url': BASE_URL, 'server': SERVER, 'file_ext': EXTENSION, 'rss_files': PROJECT_FILES_RSS, 'rss_translations': TRANSLATIONS_RSS, 'rss_news': PROJECT_NEWS_RSS, 'rss_planet': PLANET_RSS, 'rss_summary': PROJECT_SUMMARY_RSS, 'rss_security': '%s%ssecurity/index.xml' % (SERVER, BASE_URL), 'rss_vcs': PROJECT_VCS_RSS, 'screenshots': data.screenshots.SCREENSHOTS, 'awards': data.awards.AWARDS, 'generated': helper.date.DateTime.utcnow(), 'themecssversions': data.themes.CSSVERSIONS, 'sfservers': data.sf.SERVERS, 'current_year': datetime.datetime.now().year, } self.loader = TemplateLoader([TEMPLATES]) self.cssloader = TemplateLoader([CSS], default_class = NewTextTemplate) self.staticloader = TemplateLoader([STATIC], default_class = NewTextTemplate) self.jsloader = TemplateLoader([JS], default_class = NewTextTemplate) self.feeds = helper.cache.FeedCache() self.xmls = helper.cache.XMLCache() self.urls = helper.cache.URLCache()
def login_html(tmpl_dir, **kwargs): '''Dispatches to the template renderer to generate the HTML of the login page ''' loader = TemplateLoader(tmpl_dir) tmpl = loader.load('oid_login.html') stream = tmpl.generate(**kwargs) return stream.render('html', doctype='html', encoding='utf-8')
def run(self): ''' class for (test) orderprint; delevers a valid html-file. Uses a kid-template for the enveloping/merging. use kid to write; no envelope grammar is used ''' try: from genshi.template import TemplateLoader except: raise ImportError(_(u'Dependency failure: editype "template" requires python library "genshi".')) self._openoutenvelope() self.ta_info.update(self.out.ta_info) botslib.tryrunscript(self.userscript,self.scriptname,'ta_infocontent',ta_info=self.ta_info) if not self.ta_info['envelope-template']: raise botslib.OutMessageError(_(u'While enveloping in "%(editype)s.%(messagetype)s": syntax option "envelope-template" not filled; is required.'), self.ta_info) templatefile = botslib.abspath('templateshtml',self.ta_info['envelope-template']) ta_list = self.filelist2absolutepaths() try: botsglobal.logger.debug(u'Start writing envelope to file "%(filename)s".',self.ta_info) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt = botslib.txtexc() raise botslib.OutMessageError(_(u'While enveloping in "%(editype)s.%(messagetype)s", error:\n%(txt)s'), {'editype':self.ta_info['editype'],'messagetype':self.ta_info['messagetype'],'txt':txt}) try: filehandler = botslib.opendata(self.ta_info['filename'],'wb') stream = tmpl.generate(data=ta_list) stream.render(method='xhtml',encoding=self.ta_info['charset'],out=filehandler) except: txt = botslib.txtexc() raise botslib.OutMessageError(_(u'While enveloping in "%(editype)s.%(messagetype)s", error:\n%(txt)s'), {'editype':self.ta_info['editype'],'messagetype':self.ta_info['messagetype'],'txt':txt})
def _render_text_template(self, filename, **kwargs): loader = TemplateLoader(['web']) tmpl = loader.load(filename, None, TextTemplate) self.output += tmpl.generate(web_dir = '/web', current_user = self.get_current_user(), txt = gettext, **kwargs).render('text')
def run(request): # Render the header. loader = TemplateLoader(['.']) tmpl = loader.load('header.tmpl', None, TextTemplate) output = tmpl.generate(version = config.__version__).render('text') request.write(output) # Perform the task. state_db = StateDB(os.path.join(config.data_dir, 'installer_states')) step_id = request.get_data().get_int('step') prev_step_id = step_id - 1 state = state_db.get(prev_step_id) step_cls = steps[step_id] if prev_step_id >= 0: prev_step = steps[prev_step_id](prev_step_id, request, state) if prev_step.check() and prev_step.submit(): state_db.save(step_id, state) step = step_cls(step_id, request, state) step.show() else: step = step_cls(step_id, request, state) step.show() # Render the footer. tmpl = loader.load('footer.tmpl', None, TextTemplate) output = tmpl.generate().render('text') request.write(output)
def _format_plaintext(self, event): blog_post = event.blog_post blog_comment = event.blog_comment data = dict( name = blog_post.name, author = event.author, time = event.timestamp, category = event.category, version = event.version, link = event.remote_addr, title = blog_post.title, body = blog_post.body, comment = event.comment, ) chrome = Chrome(self.env) dirs = [] for provider in chrome.template_providers: dirs += provider.get_templates_dirs() templates = TemplateLoader(dirs, variable_lookup='lenient') template = templates.load( 'fullblog_plaintext.txt', cls=NewTextTemplate ) if template: stream = template.generate(**data) output = stream.render('text') return output
def __call__(self, *args, **kwargs): dojo_theme=kwargs.pop('dojo_theme',None) striped=kwargs.pop('striped','odd_row,even_row') pdf=kwargs.pop('pdf',False) genshi_path=kwargs.get('genshi_path') page = self.page dojo_theme = dojo_theme or getattr(self.page, 'dojo_theme', None) or 'tundra' auth = page._checkAuth() if auth != AUTH_OK: return self.page.site.forbidden_exception if striped: kwargs['striped'] = itertools.cycle(striped.split(',')) gnr_static_handler = page.site.getStatic('gnr') tpldirectories = [os.path.dirname(genshi_path), page.parentdirpath] + page.resourceDirs + [ gnr_static_handler.path(page.gnrjsversion, 'tpl')] loader = TemplateLoader(tpldirectories) template = loader.load(os.path.basename(genshi_path)) page.charset = 'utf-8' _resources = page.site.resources.keys() _resources.reverse() arg_dict = page.build_arg_dict() arg_dict['mainpage'] = page arg_dict.update(kwargs) try: output = template.generate(**arg_dict).render() except WSGIHTTPException, exc: return exc
def test(): base_path = os.path.dirname(os.path.abspath(__file__)) loader = TemplateLoader([base_path], auto_reload=True) start = time.clock() tmpl = loader.load('test.html') print ' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000) data = dict(hello='<world>', skin='default', hey='ZYX', bozz=None, items=['Number %d' % num for num in range(1, 15)], prefix='#') print tmpl.generate(**data).render(method='html') times = [] for i in range(1000): start = time.clock() list(tmpl.generate(**data)) times.append(time.clock() - start) sys.stdout.write('.') sys.stdout.flush() print print ' --> render stage: %s ms (average)' % ( (sum(times) / len(times) * 1000))
def writeall(self): ''' Very different writeall: there is no tree of nodes; there is no grammar.structure/recorddefs; kid opens file by itself. ''' try: from genshi.template import TemplateLoader except: txt = botslib.txtexc() raise ImportError(_(u'Dependency failure: editype "template" requires python library "genshi". Error:\n%s'%txt)) #for template-grammar: only syntax is used. Section 'syntax' has to have 'template' self.outmessagegrammarread(self.ta_info['editype'],self.ta_info['messagetype']) templatefile = botslib.abspath(u'templateshtml',self.ta_info['template']) try: botsglobal.logger.debug(u'Start writing to file "%s".',self.ta_info['filename']) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt = botslib.txtexc() raise botslib.OutMessageError(_(u'While templating "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) try: filehandler = botslib.opendata(self.ta_info['filename'],'wb') stream = tmpl.generate(data=self.data) stream.render(method='xhtml',encoding=self.ta_info['charset'],out=filehandler) except: txt = botslib.txtexc() raise botslib.OutMessageError(_(u'While templating "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) botsglobal.logger.debug(_(u'End writing to file "%s".'),self.ta_info['filename'])
def _render_newspage(self,htmlfile,atomfile,title,subtitle,entries): # only look in cwd and this file's directory loader = TemplateLoader(['.' , os.path.dirname(__file__)], variable_lookup='lenient') tmpl = loader.load("etc/newspage.template.xht2") stream = tmpl.generate(title=title, entries=entries) # tmpfilename = mktemp() tmpfilename = htmlfile.replace(".html",".xht2") assert(tmpfilename != htmlfile) Util.ensureDir(tmpfilename) fp = codecs.open(tmpfilename,"w", encoding="utf-8") x = stream.render() fp.write(x) fp.close() Util.ensureDir(htmlfile) Util.transform("xsl/static.xsl", tmpfilename, htmlfile, validate=False) tmpl = loader.load("etc/newspage.template.atom") stream = tmpl.generate(title=title, subtitle=subtitle, entries=entries, feeduri=u'https://lagen.nu/%s' % atomfile.replace("data/", ""), pageuri=u'https://lagen.nu/%s' % htmlfile.replace("data/", "")) tmpfilename = mktemp() fp = codecs.open(tmpfilename,"w", encoding="utf-8") fp.write(stream.render()) fp.close() Util.ensureDir(atomfile) Util.replace_if_different(tmpfilename, atomfile) log.info("rendered %s (%s)" % (htmlfile, atomfile))
def run(self): try: from genshi.template import TemplateLoader except: raise ImportError('Dependency failure: editype "templatehtml" requires python library "genshi".') self._openoutenvelope() self.ta_info.update(self.out.ta_info) botslib.tryrunscript(self.userscript,self.scriptname,'ta_infocontent',ta_info=self.ta_info) if not self.ta_info['envelope-template']: raise botslib.OutMessageError(_('While enveloping in "%(editype)s.%(messagetype)s": syntax option "envelope-template" not filled; is required.'), self.ta_info) templatefile = botslib.abspath(self.__class__.__name__,self.ta_info['envelope-template']) ta_list = self.filelist2absolutepaths() try: botsglobal.logger.debug('Start writing envelope to file "%(filename)s".',self.ta_info) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt = botslib.txtexc() raise botslib.OutMessageError(_('While enveloping in "%(editype)s.%(messagetype)s", error:\n%(txt)s'), {'editype':self.ta_info['editype'],'messagetype':self.ta_info['messagetype'],'txt':txt}) try: filehandler = botslib.opendata_bin(self.ta_info['filename'],'wb') stream = tmpl.generate(data=ta_list) stream.render(method='xhtml',encoding=self.ta_info['charset'],out=filehandler) except: txt = botslib.txtexc() raise botslib.OutMessageError(_('While enveloping in "%(editype)s.%(messagetype)s", error:\n%(txt)s'), {'editype':self.ta_info['editype'],'messagetype':self.ta_info['messagetype'],'txt':txt}) finally: filehandler.close()
def do_conversion(self): template_filename = self.get_resource('tex_template.tex') loader = TemplateLoader('.') templ = loader.load(template_filename, cls=NewTextTemplate) stream = templ.generate(**self.resume) #TODO: embed .cls file into resume (or output a .zip with both) self.generated_resume = stream.render('text')
def __init__(self,template, pagetitle=''): if pagetitle == '': pagetitle = template loader = TemplateLoader( os.path.join(os.path.dirname(__file__), 'templates'), auto_reload=True ) tmpl = loader.load(template) self.render = tmpl.generate(title=pagetitle).render('html',doctype='html')
def transform(tmpl_filename, html_filename, context): loader = TemplateLoader('templates', auto_reload=True) tmpl = loader.load(tmpl_filename) rendered = tmpl.generate(title=context['title'] , date=context['date'], images=context['images']).render('html', doctype='html') f = open(html_filename, 'w') f.write(rendered) f.close()
def display(self, **kwargs): """Return the HTML code for the given widget.""" self._assert_rendering_was_prepared() templateloader = TemplateLoader(self._get_all_widget_template_directories(), auto_reload=True, variable_lookup='lenient') template = templateloader.load(self.template_filename, cls=MarkupTemplate) template_data = self._merge_data(kwargs) return template.generate(**template_data)
def render_template(template_name, template_vals={}): loader = TemplateLoader('theme/frontend') template = loader.load(template_name) template_vals['render']=render_template template_vals['Registry']=Registry stream = template.generate(**template_vals) rendered = stream.render() return Markup(rendered.decode('utf-8'))
def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) used = self.get_pertinent_entries(entry, metadata) basefile = used.pop(0) if entry.get('perms').lower() == 'inherit': # use on-disk permissions fname = "%s/%s" % (self.path, entry.get('name')) entry.set('perms', str(oct(stat.S_IMODE(os.stat(fname).st_mode)))) if entry.tag == 'Path': entry.set('type', 'file') if basefile.name.endswith(".genshi"): if not have_genshi: logger.error("Cfg: Genshi is not available") raise Bcfg2.Server.Plugin.PluginExecutionError try: template_cls = NewTextTemplate loader = TemplateLoader() template = loader.load(basefile.name, cls=template_cls, encoding=self.encoding) fname = entry.get('realname', entry.get('name')) stream = template.generate(name=fname, metadata=metadata, path=basefile.name).filter(removecomment) try: data = stream.render('text', encoding=self.encoding, strip_whitespace=False) except TypeError: data = stream.render('text', encoding=self.encoding) if data == '': entry.set('empty', 'true') except Exception: e = sys.exc_info()[1] logger.error("Cfg: genshi exception: %s" % e) raise Bcfg2.Server.Plugin.PluginExecutionError else: data = basefile.data for delta in used: data = process_delta(data, delta) if entry.get('encoding') == 'base64': entry.text = binascii.b2a_base64(data) else: try: entry.text = u_str(data, self.encoding) except UnicodeDecodeError: e = sys.exc_info()[1] logger.error("Failed to decode %s: %s" % (entry.get('name'), e)) logger.error("Please verify you are using the proper encoding.") raise Bcfg2.Server.Plugin.PluginExecutionError except ValueError: e = sys.exc_info()[1] logger.error("Error in specification for %s" % entry.get('name')) logger.error("%s" % e) logger.error("You need to specify base64 encoding for %s." % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError if entry.text in ['', None]: entry.set('empty', 'true')
class Engine(object): """docstring for Engine""" defaults = { 'auto_reload': False, 'search_paths': ['./templates'] } def __init__(self, app, conf=None): super(Engine, self).__init__() self.app = app self.config = conf or {} self.config.update(copy.deepcopy(Engine.defaults)) paths = self.config.get('search_paths') for i,p in enumerate(paths): if p.find('./') == 0: paths[i] = p.replace('./', config['project']['paths']['root']+'/') self._loader = TemplateLoader(paths, auto_reload=True) self.method = "xhtml" self.doctype = "xhtml-transitional" def add_search_path(self, path): """Adds a directory to the template loader search path. You can specify templates by base name as long as the directories in which they reside are in the search path. """ if path not in self._loader.search_path: self._loader.search_path.append(path) def load(self, filename): return self._loader.load(filename) def page(self, tpl, data): """Loads a Genshi template and returns its output as an XHTML page, taking care of some details. - tpl is a path, relative to the app directory. - data is a dictionary to populate the template instance. """ if isinstance(data, basestring): return data t = self._loader.load(tpl) return t.generate(**self.app.todict(**data)).render(method=self.method, doctype=self.doctype, encoding="utf-8") def render(self, *args, **kwargs): """Function to render the given data to the template specified via the ``@output`` decorator. """ if args: assert len(args) == 1, \ 'Expected exactly one argument, but got %r' % (args,) template = self._loader.load(args[0]) else: template = thread_data.template ctxt = Context(**self.app.tpl_context) ctxt.push(kwargs) return template.generate(ctxt)
def _render_xhtml_template(self, filename, **kwargs): loader = TemplateLoader(['web']) tmpl = loader.load(filename, None, MarkupTemplate) self.output += tmpl.generate(web_dir = '/web', uri = self.get_requested_uri, request_uri = self.get_requested_uri, current_user = self.get_current_user(), txt = gettext, **kwargs).render('xhtml')
def genshi(dirname, verbose=False): from genshi.template import TemplateLoader loader = TemplateLoader([dirname], auto_reload=False) template = loader.load('template.html') def render(): return template.generate(**DATA.copy()).render('xhtml') if verbose: pr(render()) return render
def run_pdflatex(context, outputfilename, overwrite=True): if context.has_key('footer_text') and context.has_key('footer_image'): context['footer_text'] = publish_parts(context['footer_text'], writer_name='latex')['body'] context['extra_head'] = ("\\setbeamertemplate{footline}{\\hskip1cm " + "" + context['footer_text'] + "\\hfill\n" + "\\includegraphics[width=.2\\textwidth]{support/" + context['footer_image'] + "}\n" + "\\hskip.5cm~\n" + "\\vskip.5cm\n" + "} ") else: context['extra_head'] = '' if not context.has_key('textemplate'): context['textemplate'] = "text-image-quer.tex" genshitex = TemplateLoader([config.textemplatedir]) template = genshitex.load( context['textemplate'], cls=NewTextTemplate, encoding='utf8') if not overwrite and os.path.isfile(outputfilename) and os.path.getmtime(template.filepath) < os.path.getmtime(outputfilename): return if context['markup'] == 'rst': context['text'] = publish_parts(context['text'], writer_name='latex')['body'] #context['headline'] = publish_parts(context['headline'], writer_name='latex')['body'] tmpdir = tempfile.mkdtemp(dir=config.tmpdir) if context.has_key('img') and context['img'] and context['img'] != '__none': try: shutil.copy(os.path.join(config.imagedir, context['img']), os.path.join(tmpdir, context['img'])) except: raise IOError("COULD NOT COPY") else: # print "MEH No image" pass tmptexfile = os.path.join(tmpdir, 'output.tex') tmppdffile = os.path.join(tmpdir, 'output.pdf') with open(tmptexfile, 'w') as texfile: texfile.write(template.generate(form=context).render(encoding='utf8')) cwd = os.getcwd() os.chdir(tmpdir) os.symlink(config.texsupportdir, os.path.join(tmpdir, 'support')) try: texlog = check_output( ['pdflatex', '--halt-on-error', tmptexfile], stderr=STDOUT) except CalledProcessError as e: if overwrite: try: flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % e.output), 'log') except: print(e.output) raise SyntaxWarning("PDFLaTeX bailed out") finally: os.chdir(cwd) if overwrite: try: flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % texlog), 'log') except: print(texlog) shutil.copy(tmppdffile, outputfilename) shutil.rmtree(tmpdir)
def do_conversion(self): #r = self.convert_to_hresume() loader = TemplateLoader('.') templ = loader.load(self.get_resource('html_template.html')) stream = templ.generate(**self.hresume) #stream = templ.generate(**r) # TODO: output to file? method param for this? self.generated_resume = stream.render('xhtml')
def handle_error_404(status, message, traceback, version): from urllib import quote from genshi.template import TemplateLoader, Context template_loader = TemplateLoader(cherrypy.config.get('tools.genshi_template.dir')) template = template_loader.load('notfound.html') context = Context(url=cherrypy.url, quote=quote) stream = template.generate(context) return stream.render('xhtml')
def deco(*a, **b): template_dict = func(*a, **b) if not TvbProfile.current.web.RENDER_HTML: return template_dict ### Generate HTML given the path to the template and the data dictionary. loader = TemplateLoader() template = loader.load(template_path) stream = template.generate(**template_dict) return stream.render('xhtml')
def write_index_file(self, output_dir, cards_per_row): loader = TemplateLoader(self.template_dir) template = loader.load(self.template_file) stream = template.generate(character=self.character, cards_per_row=cards_per_row, util=TemplateUtil()) html = stream.render('xhtml') index_file = join(output_dir, "index.html") with io.open(index_file, "w") as file: file.write(html)
def generateXhtml(self, meta, body, registry, module, globals): """Create a XTHML representation of the document""" loader = TemplateLoader(['.', os.path.dirname(__file__)], variable_lookup='lenient') t = loader.load('etc/%s.template.xht2'%module) stream = t.generate(meta=meta, body=body, registry=registry, **globals) try: res = stream.render() except Exception, e: raise
def __init__(self, title='', authors=None, cover='', lang='en-UD', sections=None, template_loader=None, template_dir=None, display_progress=True): self.impl = book.EPubBook(template_dir, display_progress=display_progress) self.title = title self.authors = authors or [] self.cover = cover self.lang = lang self.sections = sections or [] self.loader = template_loader or TemplateLoader(template_dir)
def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='projectname', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = projectname.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( paths['templates'], auto_reload=True) # Create the Jinja2 Environment config['pylons.app_globals'].jinja2_env = Environment(loader=ChoiceLoader( [FileSystemLoader(path) for path in paths['templates']])) # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) return config
def __init__(self, title='', authors=[], cover='', lang='en-US'): """ To define a book. Parameters : title='' : The title of the book, as a string authors=[] : The authors of the book, as string elements of an array cover='' : The path to the cover of the book, 'cover.jpg' for instance lang='en-US' : the lang of the book """ self.epub = epub.EpubBook() self.title = title self.authors = authors self.cover = cover self.lang = lang self.sections = [] self.templateLoader = TemplateLoader(TEMPLATE_DIR)
class render_genshi: """Rendering interface genshi templates. Example: for xml/html templates. render = render_genshi(['templates/']) render.hello(name='genshi') For text templates: render = render_genshi(['templates/'], type='text') render.hello(name='genshi') """ def __init__(self, *a, **kwargs): from genshi.template import TemplateLoader self._type = kwargs.pop("type", None) self._loader = TemplateLoader(*a, **kwargs) def __getattr__(self, name): # Assuming all templates are html path = name + ".html" if self._type == "text": from genshi.template import TextTemplate cls = TextTemplate type = "text" else: cls = None type = self._type t = self._loader.load(path, cls=cls) def template(**kw): stream = t.generate(**kw) if type: return stream.render(type) else: return stream.render() return template
class Book: def __init__(self): self.impl = epubbuilder.EpubBook() self.loader = TemplateLoader(TEMPLATE_PATH) self.impl.loader = self.loader self.title = '' self.authors = [] self.cover = '' self.lang = 'en-US' self.sections = [] def __add_section(self, section, id, depth): if depth > 0: stream = self.loader.load( section.templateFileName).generate(section=section) html = stream.render('xhtml', doctype='xhtml11', drop_xml_decl=False) item = self.impl.add_html('%s.html' % id, html.decode('utf8')) self.impl.add_spine_item(item) self.impl.add_toc_map_node(item.dest_path, section.title, parent=None) id += '.' if len(section.subsections) > 0: for i, subsection in enumerate(section.subsections): self.__add_section(subsection, id + str(i + 1), depth + 1) def make(self, output): self.impl.set_title(self.title) self.impl.set_language(self.lang) for author in self.authors: self.impl.add_creator(author) if self.cover: self.impl.add_cover(self.cover) self.impl.add_title_page() self.impl.add_toc_page() root = Section() root.subsections = self.sections self.__add_section(root, 's', 0) self.impl.create_book(output)
class Controller(object): def __init__(self, server_rpc): self.server_rpc = server_rpc self.loader = TemplateLoader(os.path.join(os.path.dirname(__file__), \ 'html'), auto_reload=True) def is_xhr(self): requested_with = cherrypy.request.headers.get('X-Requested-With') return requested_with and requested_with.lower() == 'xmlhttprequest' def render(self, template_path, **kwargs): if len(kwargs) == 0: kwargs = {"errors": {}} tmpl = self.loader.load(template_path) stream = tmpl.generate(**kwargs) return stream.render('html', doctype='html')
class GenshiTemplateLoader(TemplateLoader): """A unified interface for loading Genshi templates. Actually a quite thin wrapper for Genshi's TemplateLoader. It sets some defaults that differ from the Genshi loader, most notably auto_reload is active. All imporant options can be passed through to Genshi. The default output type is 'html', but can be adjusted easily by changing the `output_type` attribute. """ def __init__(self, search_path, encoding='utf-8', **kwargs): TemplateLoader.__init__(self, search_path, encoding) # import Genshi here, because we don't want a general Genshi # dependency, only a local one from genshi.template import TemplateLoader as GenshiLoader from genshi.template.loader import TemplateNotFound self.not_found_exception = TemplateNotFound # set auto_reload to True per default reload_template = kwargs.pop('auto_reload', True) # get rid of default_encoding as this template loaders overwrites it # with the value of encoding kwargs.pop('default_encoding', None) # now, all arguments are clean, pass them on self.loader = GenshiLoader(search_path, default_encoding=encoding, auto_reload=reload_template, **kwargs) # the default output is HTML but can be overridden easily self.output_type = 'html' self.encoding = encoding def get_template(self, template_name): """Get the template which is at the given name""" try: return self.loader.load(template_name, encoding=self.encoding) except self.not_found_exception, e: # catch the exception raised by Genshi, convert it into a werkzeug # exception (for the sake of consistency) raise TemplateNotFound(template_name)
class Book: def __init__(self, template_dir="templates"): self.impl = epub.EpubBook() self.title = '' self.authors = [] self.cover = '' self.lang = 'en-US' self.sections = [] self.templateLoader = TemplateLoader(template_dir) def __addSection(self, section, id, depth): if depth > 0: stream = self.templateLoader.load( section.templateFileName).generate(section=section) html = stream.render('xhtml', doctype='xhtml11', drop_xml_decl=False) item = self.impl.addHtml('', '%s.html' % id, html) self.impl.addSpineItem(item) self.impl.addTocMapNode(item.destPath, section.title, depth) id += '.' if len(section.subsections) > 0: for i, subsection in enumerate(section.subsections): self.__addSection(subsection, id + str(i + 1), depth + 1) def make(self, outputDir, validate=False): outputFile = outputDir + '.epub' self.impl.setTitle(self.title) self.impl.setLang(self.lang) for author in self.authors: self.impl.addCreator(author) if self.cover: self.impl.addCover(self.cover) self.impl.addTitlePage() self.impl.addTocPage() root = Section() root.subsections = self.sections self.__addSection(root, 's', 0) self.impl.createBook(outputDir) self.impl.createArchive(outputDir, outputFile) if validate: self.impl.checkEpub('epubcheck-1.0.5.jar', outputFile)
class TableDecorator(object): WHITE = 'white' RED = 'red' GREEN = 'green' BLUE = 'blue' YELLOW = 'yellow' BLACK = 'black' def __init__(self, table, table_header, table_headline=None, before=None, after=None): self.table = table self.table_header = table_header self.table_headline = table_headline self.before = before self.after = after self.loader=TemplateLoader( os.path.join(os.path.dirname(__file__), defaults.template_dir), auto_reload=True ) def decorate(self): def preprocessTableCell(td): if(isinstance(td,(list,tuple))): if(len(td) >= 2): return (Markup(str(td[0])),Markup(str(td[1]))) elif(len(td) == 1): return (Markup(str(td[0])),Markup(TableDecorator.WHITE)) else: return ('',Markup(TableDecorator.WHITE)) else: return (Markup(str(td)),Markup(TableDecorator.WHITE)) t = [[preprocessTableCell(td) for td in tr ] for tr in self.table] template = self.loader.load(defaults.table_decorator_template_file) return template.generate(table=t, table_header=self.table_header, table_headline=Markup(self.table_headline) if self.table_headline else '', before=Markup(self.before) if self.before else '', after=Markup(self.after) if self.after else '', ).render('html', encoding='utf-8')
def __init__(self, search_path, encoding='utf-8', **kwargs): TemplateLoader.__init__(self, search_path, encoding) # import Genshi here, because we don't want a general Genshi # dependency, only a local one from genshi.template import TemplateLoader as GenshiLoader from genshi.template.loader import TemplateNotFound self.not_found_exception = TemplateNotFound # set auto_reload to True per default reload_template = kwargs.pop('auto_reload', True) # get rid of default_encoding as this template loaders overwrites it # with the value of encoding kwargs.pop('default_encoding', None) # now, all arguments are clean, pass them on self.loader = GenshiLoader(search_path, default_encoding=encoding, auto_reload=reload_template, **kwargs) # the default output is HTML but can be overridden easily self.output_type = 'html' self.encoding = encoding
def template_loader(self): """A :class:`genshi.template.TemplateLoader` that loads templates from the same places as Flask. .. versionchanged:: 0.6 Removed support for flask modules and enabled support for blueprints """ path = loader.directory( os.path.join(self.app.root_path, self.app.template_folder or 'templates') ) blueprint_paths = {} blueprints = getattr(self.app, 'blueprints', {}) for name, blueprint in blueprints.items(): blueprint_path = os.path.join( blueprint.root_path, blueprint.template_folder or 'templates' ) if os.path.isdir(blueprint_path): blueprint_paths[name] = loader.directory(blueprint_path) return TemplateLoader([path, loader.prefixed(**blueprint_paths)], auto_reload=self.app.debug, callback=self.callback)
class Server(object): def __init__(self): # map urls to functions self.urls = [(r'^$', self.index), (r'hello/?$', self.hello), (r'hello/(.+)$', self.hello), (r'template/?$', self.my_template), (r'template/(.+)$', self.my_template)] self.error_404 = Controller404() # Used to load any template self.loader = TemplateLoader(os.path.join(os.path.dirname(__file__), 'static/templates'), auto_reload=True) def __call__(self, environ, start_response): path = environ.get('PATH_INFO', '').lstrip('/') for regex, callback in self.urls: match = re.search(regex, path) if match is not None: environ['cide.url_args'] = match.groups() return callback(environ, start_response) return self.error_404.error(environ, start_response) def index(self, environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return ['Index - Hello World'] def hello(self, environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return ['Hello - Hello World'] def my_template(self, environ, start_response): tmpl = self.loader.load('template1.html') res = b'{0}'.format( tmpl.generate(TestVar="This line was added dynamically")) start_response('200 OK', [('Content-Type', 'html')]) return [res]
def __init__(self, app, global_conf, **local_conf): '''Extend SignInterface to include config and set-up for Genshi object @type app: callable following WSGI interface @param app: next middleware application in the chain @type global_conf: dict @param global_conf: PasteDeploy global configuration dictionary enables other global configuration parameters to be filtered out @type local_conf: dict @param local_conf: PasteDeploy application specific configuration dictionary ''' super(GenshiSigninTemplate, self).__init__(app, global_conf, **local_conf) self.__loader = TemplateLoader(self.templateRootDir, auto_reload=True) self.title = "Enter your OpenID to Sign in" self.xml = '' self.headExtras = '' self.loginStatus = True self.loggedIn = False # TODO: handle session object scope self.session = {'username': ''} if self.staticContentRootDir is not None: staticApp = StaticURLParser(self.staticContentRootDir) appList = [staticApp] # Check next app is set - if it is, add to the Cascade - Nb. # THIS middleware may behave as an app in which case there is no # next app in the chain if self._app is not None: appList += [self._app] self._app = Cascade(appList, catch=(404, 401))
class GenshiTemplateLoader(TemplateLoader): def __init__(self, search_path, encoding = 'utf-8', **kwargs): TemplateLoader.__init__(self, search_path, encoding) from genshi.template import TemplateLoader as GenshiLoader from genshi.template.loader import TemplateNotFound self.not_found_exception = TemplateNotFound reload_template = kwargs.pop('auto_reload', True) kwargs.pop('default_encoding', None) self.loader = GenshiLoader(search_path, default_encoding=encoding, auto_reload=reload_template, **kwargs) self.output_type = 'html' self.encoding = encoding def get_template(self, template_name): try: return self.loader.load(template_name, encoding=self.encoding) except self.not_found_exception as e: raise TemplateNotFound(template_name) def render_to_string(self, template_name, context = None): context = context or {} tmpl = self.get_template(template_name) return tmpl.generate(**context).render(self.output_type, encoding=None)
def application(environ, start_response): path = environ['PATH_INFO'] routes = open('configs/routes.conf').read().split('\n') try: route = Router(routes).route_for_uri(path) except NotFoundError: response, data = not_found() else: handler = { '/': home, '/news': home, '/news/politics': category, '/news/business': category, '/news/sports': category, '/news/science': category, '/news/entertainment': category, '/news/health': category, '/news/science/space': article } tmpl = TemplateLoader('').load(route) response, data = handler.get(path, not_found)(environ, tmpl) start_response(*response) return data
def __init__(self, *arg, **opt): '''Extend RenderingInterface to include config and set-up for Genshi templating @type *arg: tuple @param *arg: RenderingInterface parent class arguments @type **opt: dict @param **opt: additional keywords to set-up Genshi rendering''' super(GenshiRendering, self).__init__(*arg, **opt) # Initialise attributes for i in self.__class__.PROPERTY_NAMES: setattr(self, i, self.__class__.PROPERTY_DEFAULTS[i]) # Update from keywords for i in opt: setattr(self, i, opt[i]) if not self.templateRootDir: self.templateRootDir = GenshiRendering.DEFAULT_TEMPLATES_DIR self.__loader = TemplateLoader(self.templateRootDir, auto_reload=True) self.title = '' self.heading = '' self.xml = '' self.headExtras = '' self.loginStatus = True self.session = '' self.success_to = '' self.fail_to = '' self.__oidRequest = None self.__oidResponse = None self.__identityURI = None self.__environ = None self.__trust_root = None
def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates'), pkg_resources.resource_filename("ordf.onto", "templates")]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='openbiblio', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = openbiblio.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( paths['templates'], auto_reload=True) # CONFIGURATIOr OPTIONS HERE (note: all config options will override # any Pylons config options) openbiblio.handler = init_handler(config) config['pylons.strict_tmpl_context'] = False return config
class GenshiTemplateLoader(TemplateLoader): """A unified interface for loading Genshi templates. Actually a quite thin wrapper for Genshi's TemplateLoader. It sets some defaults that differ from the Genshi loader, most notably auto_reload is active. All imporant options can be passed through to Genshi. The default output type is 'html', but can be adjusted easily by changing the `output_type` attribute. """ def __init__(self, search_path, encoding='utf-8', **kwargs): TemplateLoader.__init__(self, search_path, encoding) from genshi.template import TemplateLoader as GenshiLoader from genshi.template.loader import TemplateNotFound self.not_found_exception = TemplateNotFound reload_template = kwargs.pop('auto_reload', True) kwargs.pop('default_encoding', None) self.loader = GenshiLoader(search_path, default_encoding=encoding, auto_reload=reload_template, **kwargs) self.output_type = 'html' self.encoding = encoding def get_template(self, template_name): """Get the template which is at the given name""" try: return self.loader.load(template_name, encoding=self.encoding) except self.not_found_exception as e: raise TemplateNotFound(template_name) def render_to_string(self, template_name, context=None): """Load and render a template into an unicode string""" context = context or {} tmpl = self.get_template(template_name) return tmpl.generate(**context).render(self.output_type, encoding=None)
def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='freepybx', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = freepybx.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( paths['templates'], auto_reload=True) # Setup the SQLAlchemy database engine engine = engine_from_config(config, 'sqlalchemy.') init_model(engine) # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) return config
class TicketFormatter(AnnouncerTemplateProvider): implements(IAnnouncementFormatter) ticket_email_header_fields = ListOption( 'announcer', 'ticket_email_header_fields', 'owner, reporter, milestone, priority, severity', doc=N_("""Comma-separated list of fields to appear in tickets. Use * to include all headers.""")) ticket_link_with_comment = BoolOption( 'announcer', 'ticket_link_with_comment', 'false', N_("""Include last change anchor in the ticket URL.""")) def styles(self, transport, realm): if realm == "ticket": yield "text/plain" yield "text/html" def alternative_style_for(self, transport, realm, style): if realm == "ticket" and style != 'text/plain': return "text/plain" def format(self, transport, realm, style, event): if realm == "ticket": if style == "text/plain": return self._format_plaintext(event) elif style == "text/html": return self._format_html(event) def _ticket_link(self, ticket): ticket_link = self.env.abs_href('ticket', ticket.id) if self.ticket_link_with_comment == False: return ticket_link cnum = self._ticket_last_comment(ticket) if cnum != None: ticket_link += "#comment:%s" % str(cnum) return ticket_link def _ticket_last_comment(self, ticket): cnum = -1 for entry in ticket.get_changelog(): (time, author, field, oldvalue, newvalue, permanent) = entry if field != "comment": continue try: n = int(oldvalue) except: continue if cnum < n: cnum = n if cnum == -1: return None else: return cnum def _format_plaintext(self, event): ticket = event.target short_changes = {} long_changes = {} changed_items = [(field, to_unicode(old_value)) for \ field, old_value in event.changes.items()] for field, old_value in changed_items: new_value = to_unicode(ticket[field]) if ('\n' in new_value) or ('\n' in old_value): long_changes[field.capitalize()] = '\n'.join( lineup(wrap(new_value, cols=67).split('\n'))) else: short_changes[field.capitalize()] = (old_value, new_value) data = dict(ticket=ticket, author=event.author, comment=event.comment, fields=self._header_fields(ticket), category=event.category, ticket_link=self._ticket_link(ticket), project_name=self.env.project_name, project_desc=self.env.project_description, project_link=self.env.project_url or self.env.abs_href(), has_changes=short_changes or long_changes, long_changes=long_changes, short_changes=short_changes, attachment=event.attachment) chrome = Chrome(self.env) dirs = [] for provider in chrome.template_providers: dirs += provider.get_templates_dirs() templates = TemplateLoader(dirs, variable_lookup='lenient') template = templates.load('ticket_email_plaintext.txt', cls=NewTextTemplate) if template: stream = template.generate(**data) output = stream.render('text') return output def _header_fields(self, ticket): headers = self.ticket_email_header_fields fields = TicketSystem(self.env).get_ticket_fields() if len(headers) and headers[0].strip() != '*': def _filter(i): return i['name'] in headers fields = filter(_filter, fields) return fields def _format_html(self, event): ticket = event.target attachment = event.attachment short_changes = {} long_changes = {} chrome = Chrome(self.env) for field, old_value in event.changes.items(): new_value = ticket[field] if (new_value and '\n' in new_value) or \ (old_value and '\n' in old_value): long_changes[field.capitalize()] = HTML( "<pre>\n%s\n</pre>" % ('\n'.join( diff_cleanup( difflib.unified_diff( wrap(old_value, cols=60).split('\n'), wrap(new_value, cols=60).split('\n'), lineterm='', n=3))))) else: short_changes[field.capitalize()] = (old_value, new_value) def wiki_to_html(event, wikitext): if wikitext is None: return "" try: req = Mock(href=Href(self.env.abs_href()), abs_href=self.env.abs_href, authname=event.author, perm=MockPerm(), chrome=dict(warnings=[], notices=[]), args={}) context = Context.from_request(req, event.realm, event.target.id) formatter = HtmlFormatter(self.env, context, wikitext) return formatter.generate(True) except Exception, e: raise self.log.error("Failed to render %s", repr(wikitext)) self.log.error(exception_to_unicode(e, traceback=True)) return wikitext description = wiki_to_html(event, ticket['description']) if attachment: comment = wiki_to_html(event, attachment.description) else: comment = wiki_to_html(event, event.comment) data = dict(ticket=ticket, description=description, author=event.author, fields=self._header_fields(ticket), comment=comment, category=event.category, ticket_link=self._ticket_link(ticket), project_name=self.env.project_name, project_desc=self.env.project_description, project_link=self.env.project_url or self.env.abs_href(), has_changes=short_changes or long_changes, long_changes=long_changes, short_changes=short_changes, attachment=event.attachment, attachment_link=self.env.abs_href('attachment/ticket', ticket.id)) chrome = Chrome(self.env) dirs = [] for provider in chrome.template_providers: dirs += provider.get_templates_dirs() templates = TemplateLoader(dirs, variable_lookup='lenient') template = templates.load('ticket_email_mimic.html', cls=MarkupTemplate) if template: stream = template.generate(**data) output = stream.render() return output
import os.path import urllib try: import simplejson as json except ImportError: import json from genshi.template import TemplateLoader from genshi.core import Markup import highlight # FIXME: allow DB-specific templates to override standard ones loader = TemplateLoader(os.path.join(os.path.dirname(__file__), '../templates'), auto_reload=True) def doc_edit(db_name, db, schema, doc_id, doc): """Render a Bamboo document for editing. """ t = loader.load('doc_edit.html') s = t.generate( db_name=db_name, doccount=db.doccount, schema=schema, title='Edit %s document' % db_name.capitalize(), doc_id=doc_id, doc=doc, )
def send_project_index(environ, start_response, parent_dir=None, env_paths=None): req = Request(environ, start_response) loadpaths = [pkg_resources.resource_filename('trac', 'templates')] if req.environ.get('trac.env_index_template'): env_index_template = req.environ['trac.env_index_template'] tmpl_path, template = os.path.split(env_index_template) loadpaths.insert(0, tmpl_path) else: template = 'index.html' data = { 'trac': { 'version': TRAC_VERSION, 'time': user_time(req, format_datetime) }, 'req': req } if req.environ.get('trac.template_vars'): for pair in req.environ['trac.template_vars'].split(','): key, val = pair.split('=') data[key] = val try: href = Href(req.base_path) projects = [] for env_name, env_path in get_environments(environ).items(): try: env = open_environment(env_path, use_cache=not environ['wsgi.run_once']) proj = { 'env': env, 'name': env.project_name, 'description': env.project_description, 'href': href(env_name) } except Exception as e: proj = {'name': env_name, 'description': to_unicode(e)} projects.append(proj) projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower())) data['projects'] = projects loader = TemplateLoader(loadpaths, variable_lookup='lenient', default_encoding='utf-8') tmpl = loader.load(template) stream = tmpl.generate(**data) if template.endswith('.xml'): output = stream.render('xml') req.send(output, 'text/xml') else: output = stream.render('xhtml', doctype=DocType.XHTML_STRICT, encoding='utf-8') req.send(output, 'text/html') except RequestDone: pass
# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # ***** END LICENSE BLOCK ***** import os, sys, traceback, cherrypy, pickle from genshi.template import TemplateLoader from genshi.filters import HTMLFormFiller loader = TemplateLoader(os.path.join(os.path.dirname(__file__), 'templates'), auto_reload=True) VM_STATES = (None, 'Powered Off', 'Saved', 'Aborted', 'Running', 'Paused', 'Stuck', 'Starting', 'Stopping', 'Saving', 'Restoring', 'Discarding', 'Setting Up') class Root: def __init__(self, mgr, vbox): self.mgr = mgr self.vbox = vbox @cherrypy.expose def index(self): if float(self.vbox.version[:3]) < 2.2: error_message = "VBoxWeb only supports VirtualBox version 2.2 and higher, you are running VirtualBox %s" % (
def loadTemplate(filename, dirs): if not isinstance(dirs, list): dirs = [] dirs.append(resource_filename('web', 'templates')) templates = TemplateLoader(dirs) return templates.load(filename)
def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) used = self.get_pertinent_entries(entry, metadata) basefile = used.pop(0) if entry.get('perms').lower() == 'inherit': # use on-disk permissions fname = "%s/%s" % (self.path, entry.get('name')) entry.set('perms', str(oct(stat.S_IMODE(os.stat(fname).st_mode)))) if entry.tag == 'Path': entry.set('type', 'file') if basefile.name.endswith(".genshi"): if not have_genshi: logger.error("Cfg: Genshi is not available") raise Bcfg2.Server.Plugin.PluginExecutionError try: template_cls = NewTextTemplate loader = TemplateLoader() template = loader.load(basefile.name, cls=template_cls, encoding=self.encoding) fname = entry.get('realname', entry.get('name')) stream = template.generate( name=fname, metadata=metadata, path=basefile.name).filter(removecomment) try: data = stream.render('text', encoding=self.encoding, strip_whitespace=False) except TypeError: data = stream.render('text', encoding=self.encoding) if data == '': entry.set('empty', 'true') except Exception: e = sys.exc_info()[1] logger.error("Cfg: genshi exception: %s" % e) raise Bcfg2.Server.Plugin.PluginExecutionError elif basefile.name.endswith(".cheetah"): if not have_cheetah: logger.error("Cfg: Cheetah is not available") raise Bcfg2.Server.Plugin.PluginExecutionError try: fname = entry.get('realname', entry.get('name')) s = {'useStackFrames': False} template = Cheetah.Template.Template(open( basefile.name).read(), compilerSettings=s) template.metadata = metadata template.path = fname template.source_path = basefile.name data = template.respond() if data == '': entry.set('empty', 'true') except Exception: e = sys.exc_info()[1] logger.error("Cfg: cheetah exception: %s" % e) raise Bcfg2.Server.Plugin.PluginExecutionError else: data = basefile.data for delta in used: data = process_delta(data, delta) if entry.get('encoding') == 'base64': entry.text = binascii.b2a_base64(data) else: try: entry.text = u_str(data, self.encoding) except UnicodeDecodeError: e = sys.exc_info()[1] logger.error("Failed to decode %s: %s" % (entry.get('name'), e)) logger.error( "Please verify you are using the proper encoding.") raise Bcfg2.Server.Plugin.PluginExecutionError except ValueError: e = sys.exc_info()[1] logger.error("Error in specification for %s" % entry.get('name')) logger.error("%s" % e) logger.error("You need to specify base64 encoding for %s." % entry.get('name')) raise Bcfg2.Server.Plugin.PluginExecutionError if entry.text in ['', None]: entry.set('empty', 'true')
viewpointHeight = global_bounds[1, 2] + 8.0 * extent position = array(list(centerOfRotation[:2]) + [viewpointHeight]) viewpoint = ET.Element('Viewpoint') viewpoint.set('centerOfRotation', SFVec(centerOfRotation)) viewpoint.set('position', SFVec(position)) viewpoint.set('description', "Printer Overhead") viewpoints = [viewpoint] import genshi.input from os.path import dirname from genshi.template import TemplateLoader template_loader = TemplateLoader(dirname(__file__), variable_lookup='lenient') template = template_loader.load('x3d_template.xml') args = { "unit": unit, "model": genshi.input.ET(group), "metatags": metaitems, "viewpoints": [genshi.input.ET(vp) for vp in viewpoints] } stream = template.generate(**args) X3D_DOCTYPE = ('X3D', "ISO//Web3D//DTD X3D 3.3//EN", "http://www.web3d.org/specifications/x3d-3.3.dtd") stream.render(method='xml', encoding="utf-8",
import os import cherrypy, sys from genshi.core import Stream from genshi.output import encode, get_serializer from genshi.template import Context, TemplateLoader from lib import ajax loader = TemplateLoader(os.path.join(os.path.dirname(sys.argv[0]), 'templates'), auto_reload=True) def output(filename, method='html', encoding='utf-8', **options): """Decorator for exposed methods to specify what template the should use for rendering, and which serialization method and options should be applied. """ def decorate(func): def wrapper(*args, **kwargs): cherrypy.thread_data.template = loader.load(filename) opt = options.copy() if not ajax.isXmlHttpRequest() and method == 'html': opt.setdefault('doctype', 'html') serializer = get_serializer(method, **opt) stream = func(*args, **kwargs) if not isinstance(stream, Stream): return stream return encode(serializer(stream), method=serializer, encoding=encoding)
def __init__(self): self.data = { 'releases': [], 'releases_featured': [], 'releases_older': [], 'releases_beta': [], 'themes': [], 'news': [], 'blogs': [], 'issues': [], 'base_url': BASE_URL, 'server': SERVER, 'file_ext': EXTENSION, 'rss_files': PROJECT_FILES_RSS, 'rss_translations': TRANSLATIONS_RSS, 'rss_news': PROJECT_NEWS_RSS, 'rss_planet': PLANET_RSS, 'rss_summary': PROJECT_SUMMARY_RSS, 'rss_security': '%s%ssecurity/index.xml' % (SERVER, BASE_URL), 'rss_vcs': PROJECT_VCS_RSS, 'screenshots': data.screenshots.SCREENSHOTS, 'awards': data.awards.AWARDS, 'generated': helper.date.DateTime.utcnow(), 'themecssversions': data.themes.CSSVERSIONS, 'sfservers': data.sf.SERVERS, 'current_year': datetime.datetime.now().year, } self.loader = TemplateLoader([TEMPLATES]) self.cssloader = TemplateLoader( [CSS], default_class=NewTextTemplate ) self.staticloader = TemplateLoader( [STATIC], default_class=NewTextTemplate ) self.jsloader = TemplateLoader( [JS], default_class=NewTextTemplate ) self.feeds = helper.cache.FeedCache() self.xmls = helper.cache.XMLCache() self.urls = helper.cache.URLCache() # Load Twitter settings self.twitter = None if TWITTER: config = ConfigParser.RawConfigParser() config.read(os.path.expanduser('~/.pmaweb')) try: consumer_key = config.get('twitter', 'consumer_key') consumer_secret = config.get('twitter', 'consumer_secret') token_key = config.get('twitter', 'token_key') token_secret = config.get('twitter', 'token_secret') auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(token_key, token_secret) self.twitter = tweepy.API(auth) except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): pass
class SFGenerator: def __init__(self): self.data = { 'releases': [], 'releases_featured': [], 'releases_older': [], 'releases_beta': [], 'themes': [], 'news': [], 'blogs': [], 'issues': [], 'base_url': BASE_URL, 'server': SERVER, 'file_ext': EXTENSION, 'rss_files': PROJECT_FILES_RSS, 'rss_translations': TRANSLATIONS_RSS, 'rss_news': PROJECT_NEWS_RSS, 'rss_planet': PLANET_RSS, 'rss_summary': PROJECT_SUMMARY_RSS, 'rss_security': '%s%ssecurity/index.xml' % (SERVER, BASE_URL), 'rss_vcs': PROJECT_VCS_RSS, 'screenshots': data.screenshots.SCREENSHOTS, 'awards': data.awards.AWARDS, 'generated': helper.date.DateTime.utcnow(), 'themecssversions': data.themes.CSSVERSIONS, 'sfservers': data.sf.SERVERS, 'current_year': datetime.datetime.now().year, } self.loader = TemplateLoader([TEMPLATES]) self.cssloader = TemplateLoader( [CSS], default_class=NewTextTemplate ) self.staticloader = TemplateLoader( [STATIC], default_class=NewTextTemplate ) self.jsloader = TemplateLoader( [JS], default_class=NewTextTemplate ) self.feeds = helper.cache.FeedCache() self.xmls = helper.cache.XMLCache() self.urls = helper.cache.URLCache() # Load Twitter settings self.twitter = None if TWITTER: config = ConfigParser.RawConfigParser() config.read(os.path.expanduser('~/.pmaweb')) try: consumer_key = config.get('twitter', 'consumer_key') consumer_secret = config.get('twitter', 'consumer_secret') token_key = config.get('twitter', 'token_key') token_secret = config.get('twitter', 'token_secret') auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(token_key, token_secret) self.twitter = tweepy.API(auth) except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): pass def get_outname(self, page): ''' Converts page name to file name. Basically only extension is appended if none is already used. ''' if page.find('.') == -1: return '%s.%s' % (page, self.data['file_ext']) else: return page def get_renderer(self, page): ''' Returns genshi renderer type for chosen page. ''' if page[:-4] == '.xml': return 'xml' return 'xhtml' def text_to_id(self, text): ''' Converts text to something what can be used as a anchor or id (no spaces or other special chars). ''' return re.sub('[^a-z0-9A-Z.-]', '_', text) def get_version_info(self, version): ''' Returns description to the phpMyAdmin version. ''' if version[:2] == '1.': text = 'Historical release.' elif version[:2] == '2.': text = 'Version compatible with PHP 4+ and MySQL 3+.' elif version[:2] == '3.': text = ( 'Frames version not requiring Javascript. ' + 'Requires PHP 5.2 and MySQL 5. ' + 'Supported for security fixes only, until Jan 1, 2014.' ) elif version[:3] == '4.2': text = 'Development version compatible with PHP 5.3 and MySQL 5.5.' elif version[:3] == '4.1': text = 'Current version compatible with PHP 5.3 and MySQL 5.5.' elif version[:3] == '4.0': text = ( 'Older version compatible with PHP 5.2 and MySQL 5. ' + 'Supported for security fixes only, until Jul 1, 2014.' ) if version.find('beta1') != -1: text += ' First beta version.' elif version.find('beta2') != -1: text += ' Second beta version.' elif version.find('beta3') != -1: text += ' Third beta version.' elif version.find('beta4') != -1: text += ' Fourth beta version.' elif version.find('beta') != -1: helper.log.warn('Generic beta: %s' % version) text += ' Beta version.' elif version.find('rc1') != -1: text += ' First release candidate.' elif version.find('rc2') != -1: text += ' Second release candidate.' elif version.find('rc3') != -1: text += ' Third release candidate.' elif version.find('rc4') != -1: text += ' Fourth release candidate.' elif version.find('rc') != -1: text += ' Release candidate.' helper.log.warn('Generic RC: %s' % version) return text def dom2release(self, item, theme=False): ''' Parses DOM object into release hash. ''' title = item.getElementsByTagName('title')[0].childNodes[0].data helper.log.dbg('Processing release %s' % title) titleparts = title[1:].split('/') dltype = titleparts[0] version = titleparts[1] if theme: filename = titleparts[3] else: filename = titleparts[2] ext = os.path.splitext(filename)[1] link = item.getElementsByTagName('link')[0].childNodes[0].data pubdate = item.getElementsByTagName('pubDate')[0].childNodes[0].data featured = (FILES_REGEXP.match(filename) is not None) if featured: helper.log.dbg('Release is featured!') try: dlcount = item.getElementsByTagName( 'files:download-count' )[0].childNodes[0].data except: dlcount = None try: notes = item.getElementsByTagName( 'files:release-notes-url' )[0].childNodes[0].data except: notes = '' media = item.getElementsByTagName('media:content')[0] size = media.getAttribute('filesize') for media_hash in media.getElementsByTagName('media:hash'): if media_hash.getAttribute('algo') == 'md5': md5 = media_hash.childNodes[0].data release = { 'show': False, 'version': version, 'date': helper.date.DateTime.parse(pubdate[:-6] + ' GMT'), 'name': dltype, 'fullname': '%s %s' % (dltype, version), 'notes': notes, 'files': [] } if not theme: release['info'] = self.get_version_info(version) file_info = { 'name': filename, 'url': link, 'ext': ext, 'featured': featured, 'size': size, 'size_k': int(size) / 1024, 'size_m': int(size) / (1024 * 1024), 'humansize': fmt_bytes(size), 'dlcount': dlcount, 'md5': md5 } return release, file_info def version_compare(self, first, second): ''' Returns true if second version is newer than first one. ''' # Check for identical versions if first == second: return False # Split out possible suffix like beta or rc first_parts = first.split('-') second_parts = second.split('-') # Extract numeric versions first = [int(x) for x in first_parts[0].split('.')] second = [int(x) for x in second_parts[0].split('.')] # Compare numbers if tuple(first) < tuple(second): return True if tuple(first) == tuple(second): # Second is final if len(second_parts) == 1: return True # First is final if len(first_parts) == 1: return False # Both are betas return (first_parts[1] < second_parts[1]) return False def process_releases(self, xml_files): ''' Gets phpMyAdmin releases out of releases feed and fills releases, releases_beta and releases_older. ''' helper.log.dbg('Processing file releases...') releases_dict = {} for entry in xml_files.getElementsByTagName('item'): title = entry.getElementsByTagName('title')[0].childNodes[0].data titleparts = title[1:].split('/') if titleparts[0] != 'phpMyAdmin': continue dummy, ext = os.path.splitext(title) if ext not in DOWNLOAD_EXTS: continue release, file_info = self.dom2release(entry) if release is None: continue if release['version'] not in releases_dict: releases_dict[release['version']] = release if file_info['ext'] == '.html': releases_dict[release['version']]['notes'] = \ file_info['url'].replace('/download', '/view') else: releases_dict[release['version']]['files'].append(file_info) releases = [releases_dict[rel] for rel in releases_dict.keys()] helper.log.dbg('Sorting file lists...') releases.sort(key=lambda x: x['version'], reverse=True) helper.log.dbg('Detecting versions...') outversions = {} outbetaversions = {} # Split up versions to branches for idx in xrange(len(releases)): version = releases[idx] branch = BRANCH_REGEXP.match(version['version']).group(1) test = TESTING_REGEXP.match(version['version']) if test is not None: try: if self.version_compare( releases[outbetaversions[branch]]['version'], version['version']): outbetaversions[branch] = idx except KeyError: outbetaversions[branch] = idx else: try: if self.version_compare( releases[outversions[branch]]['version'], version['version']): outversions[branch] = idx except KeyError: outversions[branch] = idx # Check for old beta versions for beta in outbetaversions.keys(): try: stable_rel = releases[outversions[beta]]['version'] beta_rel = releases[outbetaversions[beta]]['version'].split( '-' )[0] if stable_rel > beta_rel or stable_rel == beta_rel: helper.log.dbg( 'Old beta: %s' % releases[outbetaversions[beta]]['version'] ) del outbetaversions[beta] except KeyError: pass # Check for old stable releases for stable in outversions.keys(): version = releases[outversions[stable]]['version'] major_branch = MAJOR_BRANCH_REGEXP.match(version).group(1) if major_branch not in LISTED_BRANCHES: del outversions[stable] continue for check in outversions.keys(): try: check_version = releases[outversions[check]]['version'] except KeyError: # We already marked this one as old continue if (major_branch == check_version[:len(major_branch)] and self.version_compare(version, check_version)): helper.log.dbg('Old release: %s' % version) del outversions[stable] continue featured = max(outversions.keys()) featured_id = outversions[featured] helper.log.dbg('Versions detected:') for idx in xrange(len(releases)): if idx in outversions.values(): self.data['releases'].append(releases[idx]) if featured_id == idx: releases[idx]['info'] += ' Currently recommended version.' self.data['releases_featured'].append(releases[idx]) helper.log.dbg(' %s (featured)' % releases[idx]['version']) else: helper.log.dbg(' %s' % releases[idx]['version']) elif idx in outbetaversions.values(): self.data['releases_beta'].append(releases[idx]) helper.log.dbg(' %s (beta)' % releases[idx]['version']) else: self.data['releases_older'].append(releases[idx]) helper.log.dbg(' %s (old)' % releases[idx]['version']) def process_themes(self, xml_files): ''' Gets theme releases out of releases feed and fills themes. ''' helper.log.dbg('Processing themes releases...') for entry in xml_files.getElementsByTagName('item'): title = entry.getElementsByTagName('title')[0].childNodes[0].data titleparts = title[1:].split('/') if titleparts[0] != 'themes': continue dummy, ext = os.path.splitext(title) if ext not in DOWNLOAD_EXTS: continue name = titleparts[1] version = titleparts[2] release, file_info = self.dom2release(entry, theme=True) if release is None: continue release['shortname'] = name release['ignore'] = False release['imgname'] = 'images/themes/%s.png' % name try: release.update(data.themes.THEMES['%s-%s' % (name, version)]) except KeyError: helper.log.warn( 'No metadata for theme %s-%s!' % (name, version) ) release['name'] = name release['support'] = 'N/A' release['info'] = '' release['fullname'] = '%s %s' % (release['name'], version) release['classes'] = data.themes.CSSMAP[release['support']] release['file'] = file_info if not release['ignore']: self.data['themes'].append(release) helper.log.dbg('Sorting file lists...') self.data['themes'].sort(key=lambda x: x['date'], reverse=True) def process_news(self, feed): ''' Fills in news based on news feed. ''' helper.log.dbg('Processing news feed...') for entry in feed.entries: item = {} item['link'] = entry.link item['date'] = helper.date.DateTime.parse(entry.updated) # replaces are workaround for broken automatic links from sf.net # rss feed item['text'] = entry.summary.replace( '.</a>', '</a>.' ).replace( '.">http', '">http' ) item['title'] = entry.title item['anchor'] = self.text_to_id(entry.title) self.data['news'].append(item) self.data['short_news'] = self.data['news'][:5] def tweet(self): ''' Finds out whether we should send update to twitter and do so. ''' if self.twitter is None: return news = self.data['news'][0] storage = helper.cache.Cache() title = news['title'] if 'phpMyAdmin' in news['title']: title = title.replace('phpMyAdmin', '#phpMyAdmin') else: title = '%s #phpMyAdmin' % title tweet = '%s, see http://www.phpmyadmin.net/' % title try: last = storage.force_get('last-tweet') except helper.cache.NoCache: last = None if last == tweet: helper.log.dbg( 'No need to tweet, the last news is still the same...' ) return helper.log.dbg('Tweeting: %s' % tweet) self.twitter.update_status(tweet) storage.set('last-tweet', tweet) def tweet_security(self): ''' Finds out whether we should send update to twitter about security issue and do so. ''' if self.twitter is None: return issue = self.data['issues'][0] storage = helper.cache.Cache() tweet = '%s: %s - %s #security' % ( issue['name'], issue['summary'].strip(), issue['fulllink'], ) try: last = storage.force_get('last-security-tweet') except helper.cache.NoCache: last = None if last == tweet: helper.log.dbg( 'No need to tweet, the last news is still the same...' ) return helper.log.dbg('Tweeting: %s' % tweet) self.twitter.update_status(tweet) storage.set('last-security-tweet', tweet) def process_planet(self, feed): ''' Fills in planet based on planet feed. ''' helper.log.dbg('Processing planet feed...') for entry in feed.entries: item = {} item['link'] = 'http://planet.phpmyadmin.net/#%s' % entry.link item['date'] = helper.date.DateTime.parse( entry.updated.replace('+0000', 'GMT') ) if hasattr(entry, 'summary_detail'): item['text'] = entry.summary_detail['value'] else: item['text'] = '' item['title'] = entry.title self.data['blogs'].append(item) self.data['short_blogs'] = self.data['blogs'][:5] def process_feed(self, name, feed, count=3): ''' Fills in feed data based on feeparser feed. ''' helper.log.dbg('Processing %s feed...' % name) self.data[name] = [] for entry in feed.entries: item = {} item['link'] = entry.link item['date'] = entry.updated_parsed item['text'] = entry.summary_detail['value'] item['title'] = entry.title self.data[name].append(item) self.data['short_%s' % name] = self.data[name][:count] def process_summary(self, feed): ''' Reads summary feed and fills some useful information into data. ''' helper.log.dbg('Processing summary feed...') info = {} links = {} trackers = [] for entry in feed.entries: if entry.title[:22] == 'Developers on project:': match = SUMMARY_DEVS.match(entry.title) info['developers'] = match.group(1) links['developers'] = entry.link elif entry.title[:13] == 'Mailing lists': match = SUMMARY_LISTS.match(entry.title) info['mailinglists'] = match.group(1) links['mailinglists'] = entry.link elif entry.title[:17] == 'Discussion forums': match = SUMMARY_FORUMS.match(entry.title) info['forums'] = match.group(1) info['forumposts'] = match.group(2) links['forums'] = entry.link elif entry.title[:8] == 'Tracker:': match = SUMMARY_TRACKER.match(entry.title) trackers.append({ 'name': match.group(1), 'open': match.group(2), 'total': match.group(3), 'description': entry.summary[21:], 'link': entry.link, }) self.data['info'] = info self.data['links'] = links trackers.sort(key=lambda x: x['name']) self.data['trackers'] = trackers def get_menu(self, active): ''' Returns list of menu entries with marked active one. ''' menu = [] for item in data.menu.MENU: title = item[1] name = item[0] field = { 'title': title, 'class': {}, } if name == active or '%sindex' % name == active: field['class'] = { 'class': 'active', } if len(name) > 0 and name[-1] != '/': name = self.get_outname(name) field['link'] = '%s%s' % (BASE_URL, name) menu.append(field) return menu def render_css(self, filename): ''' Renders CSS file from template. ''' helper.log.dbg(' %s' % filename) template = self.cssloader.load(filename) out = open(os.path.join(OUTPUT, 'css', filename), 'w') out.write(template.generate(**self.data).render()) out.close() def render_static(self, templatename, outfile, extradata=None): ''' Renders "static" file from template. ''' if extradata is None: extradata = {} helper.log.dbg(' %s' % outfile) template = self.staticloader.load(templatename) out = open(os.path.join(OUTPUT, outfile), 'w') extradata.update(self.data) out.write(template.generate(**extradata).render()) out.close() def render_js(self, filename): ''' Renders JavaScript file from template. Some defined files are not processed through template engine as they were taken from other projects. ''' helper.log.dbg(' %s' % filename) outpath = os.path.join(OUTPUT, 'js', filename) shutil.copy2(os.path.join(JS, filename), outpath) def render(self, page): ''' Renders standard page. ''' helper.log.dbg(' %s' % page) template = self.loader.load('%s.tpl' % page) menu = self.get_menu(page) out = open(os.path.join(OUTPUT, self.get_outname(page)), 'w') out.write( template.generate(menu=menu, **self.data).render( self.get_renderer(page) ) ) out.close() def render_security(self, issue): ''' Renders security issue. ''' helper.log.dbg(' %s' % issue) template = self.loader.load('security/%s' % issue) menu = self.get_menu('security/') out = open( os.path.join(OUTPUT, 'security', self.get_outname(issue)), 'w' ) out.write( template.generate(menu=menu, issue=issue, **self.data).render( 'xhtml' ) ) out.close() def list_security_issues(self): ''' Fills in issues and topissues with security issues information. ''' issues = glob.glob('templates/security/PMASA-*') issues.sort(key=lambda x: int(x[24:29]) * 100 - int(x[30:])) for issue in issues: xmldata = XML(open(issue, 'r').read()) name = os.path.basename(issue) self.data['issues'].append({ 'name': name, 'link': '%ssecurity/%s' % (BASE_URL, self.get_outname(name)), 'fulllink': '%s%ssecurity/%s' % ( SERVER, BASE_URL, self.get_outname(name) ), 'summary': str(xmldata.select( 'def[@function="announcement_summary"]/text()' )), 'date': helper.date.DateTime.parse(str(xmldata.select( 'def[@function="announcement_date"]/text()' ))), 'cves': str(xmldata.select( 'def[@function="announcement_cve"]/text()' )).split(' '), 'versions': str(xmldata.select( 'def[@function="announcement_affected"]/text()' )), }) self.data['topissues'] = self.data['issues'][:TOP_ISSUES] def prepare_output(self): ''' Copies static content to output and creates required directories. ''' helper.log.dbg('Copying static content to output...') try: shutil.rmtree(OUTPUT) except OSError: pass copyignore = shutil.ignore_patterns('.git', '.svn', '*.swp', '_*') shutil.copytree(STATIC, OUTPUT, ignore=copyignore) imgdst = os.path.join(OUTPUT, 'images') shutil.copytree(IMAGES, imgdst, ignore=copyignore) try: os.mkdir(os.path.join(OUTPUT, 'security')) except OSError: pass try: os.mkdir(os.path.join(OUTPUT, 'css')) except OSError: pass try: os.mkdir(os.path.join(OUTPUT, 'js')) except OSError: pass def get_sitemap_data(self, page): ''' Returns metadata for page for sitemap as per http://sitemaps.org. ''' priority = '0.8' changefreq = 'daily' if page[:15] == 'security/PMASA-': priority = '0.5' changefreq = 'monthly' elif page[:20] == '/pma_localized_docs/': priority = '0.6' changefreq = 'monthly' elif page in ['index', 'news']: priority = '1.0' changefreq = 'daily' elif page in ['improve', 'team', 'docs', 'devel', 'translate']: priority = '1.0' changefreq = 'weekly' elif page in ['downloads', 'donate', 'themes', 'translations']: priority = '0.9' changefreq = 'daily' elif page in ['support']: priority = '0.9' changefreq = 'weekly' elif page in ['sitemap']: priority = '0.2' changefreq = 'weekly' return { 'lastmod': helper.date.DateTime.utcnow(), 'changefreq': changefreq, 'priority': priority, } def generate_sitemap(self): ''' Generates list of pages with titles. ''' self.data['sitemap'] = [] self.data['sitemapxml'] = [] helper.log.dbg('Generating sitemap:') for root, dirs, files in os.walk(TEMPLATES): if '.svn' in dirs: dirs.remove('.svn') # don't visit .svn directories if '.git' in dirs: dirs.remove('.git') # don't visit .git directories files.sort() root_dir = root[len(TEMPLATES):].strip('/') if len(root_dir) > 0: root_dir += '/' for filename in files: name, ext = os.path.splitext(filename) if ext != '.tpl' and name[:6] != 'PMASA-': continue if name[0] in ['_', '.']: continue if filename in ['index.xml.tpl', 'sitemap.xml.tpl', '404.tpl']: continue helper.log.dbg('- %s' % filename) xmldata = XML(open(os.path.join(root, filename), 'r').read()) title = str(xmldata.select( 'def[@function="page_title"]/text()' )) title = title.strip() if len(title) == 0: title = str(xmldata.select( 'def[@function="announcement_id"]/text()' )) title = title.strip() if len(title) == 0: title = 'Index' link = root_dir + self.get_outname(name) sitemap = { 'link': link, 'loc': '%s%s%s' % (SERVER, BASE_URL, link), 'title': title } if name[:6] != 'PMASA-': self.data['sitemap'].append(sitemap) sitemap.update(self.get_sitemap_data(root_dir + name)) self.data['sitemapxml'].append(sitemap) for link in data.sitemap.ENTRIES: sitemap = { 'loc': SERVER + link, } sitemap.update(self.get_sitemap_data(link)) self.data['sitemapxml'].append(sitemap) def get_translation_stats(self): ''' Receives translation stats from external server and parses it. ''' helper.log.dbg('Processing translation stats...') self.data['translations'] = [] stats = json.loads(self.urls.load('translations', TRANSLATION_STATS)) for lang in stats: if lang['translated_percent'] < 50: css = ' b50' elif lang['translated_percent'] < 80: css = ' b80' else: css = '' if lang['last_change'] is None: updated = '' else: updated = parse(lang['last_change']) translation = { 'name': lang['name'], 'short': lang['code'], 'url': lang['url'], 'translated': lang['translated'], 'percent': lang['translated_percent'], 'updated': updated, 'css': css, } self.data['translations'].append(translation) def fetch_data(self): ''' Fetches data from remote or local sources and prepares template data. ''' xml_files = self.xmls.load('files', PROJECT_FILES_RSS) self.process_releases(xml_files) self.process_themes(xml_files) rss_news = self.feeds.load('news', PROJECT_NEWS_RSS) self.process_news(rss_news) self.tweet() rss_planet = self.feeds.load('planet', PLANET_RSS) self.process_planet(rss_planet) rss_ru = self.feeds.load('ru', RSS_RU) self.process_feed('news_ru', rss_ru) rss_summary = self.feeds.load('summary', PROJECT_SUMMARY_RSS) self.process_summary(rss_summary) self.get_translation_stats() self.list_security_issues() self.tweet_security() self.generate_sitemap() def render_pages(self): ''' Renders all content pages. ''' helper.log.dbg('Rendering pages:') templates = [os.path.basename(x) for x in glob.glob('templates/*.tpl')] templates.extend( [ os.path.join('security', os.path.basename(x)) for x in glob.glob('templates/security/*.tpl') ] ) for template in templates: name = os.path.splitext(template)[0] if os.path.basename(name)[0] == '_': continue self.render(name) helper.log.dbg('Rendering security issues pages:') for issue in self.data['issues']: self.render_security(issue['name']) helper.log.dbg('Generating CSS:') for cssfile in glob.glob('css/*.css'): self.render_css(os.path.basename(cssfile)) helper.log.dbg('Generating JavaScript:') for jsfile in glob.glob('js/*.js'): self.render_js(os.path.basename(jsfile)) helper.log.dbg('Generating static pages:') self.render_static('_version.php', 'version.php') self.render_static('_version.txt', 'version.txt') self.render_static('_version.js', 'version.js') self.render_static('_version.json', 'version.json') self.render_static('_security.php', 'security.php') self.render_static('_robots.txt', 'robots.txt') for redir in data.redirects.REDIRECTS: self.render_static( '_redirect.tpl', '%s.php' % redir, {'location': self.get_outname(data.redirects.REDIRECTS[redir])} ) def main(self): ''' Main program which does everything. ''' self.prepare_output() self.fetch_data() self.render_pages() helper.log.dbg('Done!')
def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ ###### Pylons monkey-patch # this must be run at a time when the env is semi-setup, thus inlined here. # Required by the deliverance plugin and iATI from pylons.wsgiapp import PylonsApp import pkg_resources find_controller_generic = PylonsApp.find_controller # This is from pylons 1.0 source, will monkey-patch into 0.9.7 def find_controller(self, controller): if controller in self.controller_classes: return self.controller_classes[controller] # Check to see if its a dotted name if '.' in controller or ':' in controller: mycontroller = pkg_resources \ .EntryPoint \ .parse('x=%s' % controller).load(False) self.controller_classes[controller] = mycontroller return mycontroller return find_controller_generic(self, controller) PylonsApp.find_controller = find_controller ###### END evil monkey-patch os.environ['CKAN_CONFIG'] = global_conf['__file__'] # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='ckan', paths=paths) # load all CKAN plugins p.load_all(config) # Load the synchronous search plugin, unless already loaded or # explicitly disabled if not 'synchronous_search' in config.get('ckan.plugins',[]) and \ asbool(config.get('ckan.search.automatic_indexing', True)): log.debug('Loading the synchronous search plugin') p.load('synchronous_search') for plugin in p.PluginImplementations(p.IConfigurer): # must do update in place as this does not work: # config = plugin.update_config(config) plugin.update_config(config) # This is set up before globals are initialized site_id = os.environ.get('CKAN_SITE_ID') if site_id: config['ckan.site_id'] = site_id site_url = config.get('ckan.site_url', '') ckan_host = config['ckan.host'] = urlparse(site_url).netloc if config.get('ckan.site_id') is None: if ':' in ckan_host: ckan_host, port = ckan_host.split(':') assert ckan_host, 'You need to configure ckan.site_url or ' \ 'ckan.site_id for SOLR search-index rebuild to work.' config['ckan.site_id'] = ckan_host # ensure that a favicon has been set favicon = config.get('ckan.favicon', '/images/icons/ckan.ico') config['ckan.favicon'] = favicon # Init SOLR settings and check if the schema is compatible #from ckan.lib.search import SolrSettings, check_solr_schema_version # lib.search is imported here as we need the config enabled and parsed import ckan.lib.search as search search.SolrSettings.init(config.get('solr_url'), config.get('solr_user'), config.get('solr_password')) search.check_solr_schema_version() config['routes.map'] = routing.make_map() config['routes.named_routes'] = routing.named_routes config['pylons.app_globals'] = app_globals.app_globals # initialise the globals config['pylons.app_globals']._init() # add helper functions helpers = _Helpers(h) config['pylons.h'] = helpers ## redo template setup to use genshi.search_path ## (so remove std template setup) legacy_templates_path = os.path.join(root, 'templates_legacy') jinja2_templates_path = os.path.join(root, 'templates') if asbool(config.get('ckan.legacy_templates', 'no')): # We want the new template path for extra snippets like the # dataviewer and also for some testing stuff template_paths = [legacy_templates_path, jinja2_templates_path] else: template_paths = [jinja2_templates_path, legacy_templates_path] extra_template_paths = config.get('extra_template_paths', '') if extra_template_paths: # must be first for them to override defaults template_paths = extra_template_paths.split(',') + template_paths config['pylons.app_globals'].template_paths = template_paths # Translator (i18n) translator = Translator(pylons.translator) def template_loaded(template): translator.setup(template) # Markdown ignores the logger config, so to get rid of excessive # markdown debug messages in the log, set it to the level of the # root logger. logging.getLogger("MARKDOWN").setLevel(logging.getLogger().level) # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( template_paths, auto_reload=True, callback=template_loaded) ################################################################# # # # HORRIBLE GENSHI HACK # # # ################################################################# # # # Genshi does strange things to get stuff out of the template # # variables. This stops it from handling properties in the # # correct way as it returns the property rather than the actual # # value of the property. # # # # By overriding lookup_attr() in the LookupBase class we are # # able to get the required behaviour. Using @property allows # # us to move functionality out of templates whilst maintaining # # backwards compatability. # # # ################################################################# ''' This code is based on Genshi code Copyright © 2006-2012 Edgewall Software All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ''' from genshi.template.eval import LookupBase @classmethod def genshi_lookup_attr(cls, obj, key): __traceback_hide__ = True try: val = getattr(obj, key) except AttributeError: if hasattr(obj.__class__, key): raise else: try: val = obj[key] except (KeyError, TypeError): val = cls.undefined(key, owner=obj) if isinstance(val, property): val = val.fget() return val setattr(LookupBase, 'lookup_attr', genshi_lookup_attr) del genshi_lookup_attr del LookupBase ################################################################# # # # END OF GENSHI HACK # # # ################################################################# # Create Jinja2 environment env = lib.jinja_extensions.Environment( loader=lib.jinja_extensions.CkanFileSystemLoader(template_paths), autoescape=True, extensions=[ 'jinja2.ext.do', 'jinja2.ext.with_', lib.jinja_extensions.SnippetExtension, lib.jinja_extensions.CkanExtend, lib.jinja_extensions.CkanInternationalizationExtension, lib.jinja_extensions.LinkForExtension, lib.jinja_extensions.ResourceExtension, lib.jinja_extensions.UrlForStaticExtension, lib.jinja_extensions.UrlForExtension ]) env.install_gettext_callables(_, ungettext, newstyle=True) # custom filters env.filters['empty_and_escape'] = lib.jinja_extensions.empty_and_escape env.filters['truncate'] = lib.jinja_extensions.truncate config['pylons.app_globals'].jinja_env = env # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = [ '^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) ckan_db = os.environ.get('CKAN_DB') if ckan_db: config['sqlalchemy.url'] = ckan_db # for postgresql we want to enforce utf-8 sqlalchemy_url = config.get('sqlalchemy.url', '') if sqlalchemy_url.startswith('postgresql://'): extras = {'client_encoding': 'utf8'} else: extras = {} engine = sqlalchemy.engine_from_config(config, 'sqlalchemy.', **extras) if not model.meta.engine: model.init_model(engine) for plugin in p.PluginImplementations(p.IConfigurable): plugin.configure(config)