def _pdf(self): start_time = pytis.data.DateTime.now() T = pytis.data.DBTransactionDefault transaction = T(connection_data=config.dbconnection, isolation=T.REPEATABLE_READ) children = [] if self._form is not None and self._row_template is not None: i = 1 row_template = self._row_template for row in self._form.presented_rows(): row_lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, current_row=row, parameters=self._parameters) id_ = 'pytissubdoc%d' % (i,) row_template_lcg = row_template.lcg() parameters = self._template_parameters(row_template) document = lcg.ContentNode(id=id_, title=' ', # let's avoid printing the id content=row_template_lcg, globals=row_lcg_globals, **parameters) children.append(document) i += 1 lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, parameters=self._parameters) lcg_globals['app'] = self._application_variables body = self._body if not body: body = [] elif not isinstance(body, (list, tuple,)): body = [body] children = ([document_.lcg_document(globals=lcg_globals) for document_ in body] + children) lcg_content = lcg.ContentNode(id='__dummy', content=lcg.Content(), children=children, **self._body_parameters) presentation = lcg.Presentation() presentation.font_name = 'DejaVu' presentation.font_family = lcg.FontFamily.FIXED_WIDTH def margin(key): size = self._page_layout.get(key) if size is None: size = UMm(10) return size presentation.top_margin = margin(PAGE_TOP_MARGIN) presentation.bottom_margin = margin(PAGE_BOTTOM_MARGIN) presentation.left_margin = margin(PAGE_LEFT_MARGIN) presentation.right_margin = margin(PAGE_RIGHT_MARGIN) presentation.page_width = self._page_layout.get(PAGE_WIDTH) presentation.page_height = self._page_layout.get(PAGE_HEIGHT) presentation.landscape = self._page_layout.get(PAGE_LANDSCAPE_MODE) start_time_export = pytis.data.DateTime.now() exporter = lcg.pdf.PDFExporter(translations=self._translations) presentation_args = (self._style or []) presentation_set = lcg.PresentationSet(presentation_args) context = exporter.context(lcg_content, self._language, presentation=presentation_set) try: pdf = exporter.export(context, global_presentation=presentation) except lcg.SubstitutionIterator.IteratorError, e: message = _("Invalid use of iterator.\n" "Maybe you refer to an non-existent or inaccessible object in the table?") message += "\n" + unicode(e) pytis.form.run_dialog(pytis.form.Error, message) return ''
def build(self): """Build hierarchy of 'ContentNode' instances and return the root node.""" try: variants = self._variants() if variants: # There is one or more known source language (files have the lang extension). kwargs = dict(variants=[lcg.Variant(lang, **self._content(lang)) for lang in variants]) else: # There is one unknown source language. kwargs = self._content(None) return lcg.ContentNode(id=self._id, title=self._title(), brief_title=self._brief_title(), descr=self._descr(), children=[child.build() for child in self._children()], resource_provider=self._resource_provider_, globals=self._globals(), hidden=self._hidden, **kwargs) except Exception as e: if hasattr(self, '_source_filename'): # TODO: This is a quick hack. The attribute `_source_filename' is prefilled in # 'FileReader._read_file', so it would be at least more appropriate to move this # hack into the 'FileReader' class. Even then, there is no guarantee, that the # exception was actually raised during processing this file. e = lcg.add_processing_info(e, 'File', self._source_filename) raise
def clone(node, node_id): # Clone the content node, but force `id' to help URI and `foldable' to True. return lcg.ContentNode(node_id, title=node.title(), descr=node.descr(), content=node.content(), hidden=node.hidden(), children=[clone(n, 'help:pytis/'+n.id()) for n in node.children()], resource_provider=resource_provider, foldable=True)
def _pytis_help(self, resource_dirs): image_dir = os.path.join(config.help_dir, 'img') resource_provider = lcg.ResourceProvider(dirs=[image_dir] + resource_dirs) def clone(node, node_id): # Clone the content node, but force `id' to help URI and `foldable' to True. return lcg.ContentNode(node_id, title=node.title(), descr=node.descr(), content=node.content(), hidden=node.hidden(), children=[clone(n, 'help:pytis/'+n.id()) for n in node.children()], resource_provider=resource_provider, foldable=True) try: node = self._pytis_help_root_node except AttributeError: directory = os.path.join(config.help_dir, 'src') reader = lcg.reader(directory, 'pytis', ext='txt', resource_provider=resource_provider) try: node = self._pytis_help_root_node = reader.build() except IOError as e: log(OPERATIONAL, "Unable to read Pytis help files from '%s':" % directory, e) node = lcg.ContentNode('pytis:', title=_("Pytis User Guide"), content=lcg.p(_("Help files not found!")), hidden=True, resource_provider=resource_provider) # We need to clone on every request because set_parent() is called on # the result when added to the help tree and set_parent may not be # called multiple times. return clone(node, 'help:pytis')
def lcg_document(self, **kwargs): """Return the document(s) as an 'lcg.ContentNode' instance. Arguments: kwargs -- kwargs to pass to 'lcg.ContentNode' constructor """ def arg(definition): if definition is None or isinstance(definition, lcg.Content): value = definition else: value = definition.lcg() return value content_id = 'pytismarkup%d' % (self._counter.next(), ) return lcg.ContentNode( id=content_id, title=' ', # let's avoid printing the id content=self.lcg(), page_header=arg(self.arg_page_header), page_footer=arg(self.arg_page_footer), first_page_header=arg(self.arg_first_page_header), page_background=arg(self.arg_page_background), presentation=self.arg_presentation, **kwargs)
def _handle_maintenance_mode(self, req): import http.client # Translators: Meaning that the system (webpage) does not work now # because we are updating/fixing something but will work again after # the maintaince is finished. node = lcg.ContentNode(req.uri().encode('utf-8'), title=_("Maintenance Mode"), content=lcg.p(_("The system is temporarily down for maintenance."))) exporter = wiking.MinimalExporter(translations=wiking.cfg.translation_path) try: lang = req.preferred_language() except Exception: lang = wiking.cfg.default_language_by_domain.get(req.server_hostname(), wiking.cfg.default_language) or 'en' context = exporter.context(node, lang=lang) exported = exporter.export(context) return req.send_response(context.localize(exported), status_code=http.client.SERVICE_UNAVAILABLE)
def mknode(item): # Caution - make the same uri transformation as above to get same # results in all cases (such as for '/'). item_uri = '/' + item.id().strip('/') if item_uri == uri: # Note, the document title should not override the menu item title. # Only the main page heading is affected, but the ContentNode's # title matches the MenuItem's title. title = document.title() or item.title() if title and document.subtitle(): title = lcg.concat(title, ' :: ', document.subtitle()) heading = lcg.TextContent(title) content = document.content() if isinstance(content, (list, tuple)): content = lcg.Container([c for c in content if c is not None]) variants = document.variants() if variants is None: variants = item.variants() globals_ = document.globals() else: variants = item.variants() heading = None content = None globals_ = None if variants is None: variants = all_variants node = lcg.ContentNode(item_uri, title=item.title(), heading=heading, descr=item.descr(), content=content, variants=[lcg.Variant(v) for v in variants], active=item.active(), foldable=item.foldable(), hidden=item.hidden() or lang not in variants, children=[mknode(i) for i in item.submenu()], resource_provider=resource_provider, globals=globals_) nodes[item_uri] = node return node
def make_node(row, children): if row['help_id'].value() == topic: # If this is the currently displayed node, create the content. # Other nodes are only generated for their presence in the # menu. parser = lcg.Parser() if row['page_id'].value(): storage = pytis.presentation.DbAttachmentStorage( 'e_pytis_help_pages_attachments', 'page_id', row['page_id'].value()) content = lcg.Container(parser.parse(row['content'].value()), resources=storage.resources()) else: content = [lcg.TableOfContents(title=_("Contents"))] fullname, spec_name = row['fullname'].value(), row['spec_name'].value() if row['menu_help'].value(): content.extend(parser.parse(row['menu_help'].value())) if fullname and fullname.startswith('handle/'): pass elif fullname and fullname.startswith('proc/'): pass elif spec_name == 'export': pass elif spec_name == 'ui': pass elif spec_name: spec_help_content = self._spec_help_content(spec_name)[1] if spec_help_content: content.append(spec_help_content) else: content = () return lcg.ContentNode('help:'+row['help_id'].value(), title=row['title'].value(), descr=row['description'].value(), foldable=True, content=lcg.Container(content), resource_provider=resource_provider, children=[make_node(r, children) for r in children.get(row['position'].value(), ())])
def _serve_content(self, req, content): """Serve a document using the Wiking exporter.""" node = lcg.ContentNode(req.uri(), content=content, resource_provider=self._resource_provider(req)) context = self._exporter.context(node, lang=req.preferred_language(), req=req) return req.send_response(context.localize(content.export(context)))
def _build(self, req, document, lang): """Return the 'lcg.ContentNode' instance representing the given document. The whole application menu structure must be built in order to create the 'lcg.ContentNone' instance. """ uri = '/' + req.uri().strip('/') nodes = {} application = self._application all_variants = application.languages() resource_provider = self._resource_provider(req) def mknode(item): # Caution - make the same uri transformation as above to get same # results in all cases (such as for '/'). item_uri = '/' + item.id().strip('/') if item_uri == uri: # Note, the document title should not override the menu item title. # Only the main page heading is affected, but the ContentNode's # title matches the MenuItem's title. title = document.title() or item.title() if title and document.subtitle(): title = lcg.concat(title, ' :: ', document.subtitle()) heading = lcg.TextContent(title) content = document.content() if isinstance(content, (list, tuple)): content = lcg.Container([c for c in content if c is not None]) variants = document.variants() if variants is None: variants = item.variants() globals_ = document.globals() else: variants = item.variants() heading = None content = None globals_ = None if variants is None: variants = all_variants node = lcg.ContentNode(item_uri, title=item.title(), heading=heading, descr=item.descr(), content=content, variants=[lcg.Variant(v) for v in variants], active=item.active(), foldable=item.foldable(), hidden=item.hidden() or lang not in variants, children=[mknode(i) for i in item.submenu()], resource_provider=resource_provider, globals=globals_) nodes[item_uri] = node return node top_level_nodes = [mknode(item) for item in application.menu(req)] try: node = nodes[uri] except KeyError: # The current document's node was not created with the menu. # We need to create an extra node and add into the structure. parent = None pathlen = len(req.path) for i in range(pathlen - 1): # Find the parent node by the closest uri prefix. subpath = '/' + '/'.join(req.path[:pathlen - i - 1]) if subpath in nodes: parent = nodes[subpath] break node = mknode(wiking.MenuItem( uri, hidden=True, title=document.title() or parent and parent.title() or None, variants=document.variants() or parent and parent.variants() or None, )) if parent: node._set_parent(parent) parent._children += (node,) else: top_level_nodes.append(node) lcg.ContentNode('__wiking_root_node__', title='root', content=lcg.Content(), children=top_level_nodes) return node
def help_page(self, topic): """Return the help page for given topic as lcg.ContentNode instance.""" resource_dirs = [d[:-3]+'resources' for d in sys.path if d.endswith('/pytis/lib') or d.endswith('/lcg/lib')] resource_provider = lcg.ResourceProvider(dirs=resource_dirs) def make_node(row, children): if row['help_id'].value() == topic: # If this is the currently displayed node, create the content. # Other nodes are only generated for their presence in the # menu. parser = lcg.Parser() if row['page_id'].value(): storage = pytis.presentation.DbAttachmentStorage( 'e_pytis_help_pages_attachments', 'page_id', row['page_id'].value()) content = lcg.Container(parser.parse(row['content'].value()), resources=storage.resources()) else: content = [lcg.TableOfContents(title=_("Contents"))] fullname, spec_name = row['fullname'].value(), row['spec_name'].value() if row['menu_help'].value(): content.extend(parser.parse(row['menu_help'].value())) if fullname and fullname.startswith('handle/'): pass elif fullname and fullname.startswith('proc/'): pass elif spec_name == 'export': pass elif spec_name == 'ui': pass elif spec_name: spec_help_content = self._spec_help_content(spec_name)[1] if spec_help_content: content.append(spec_help_content) else: content = () return lcg.ContentNode('help:'+row['help_id'].value(), title=row['title'].value(), descr=row['description'].value(), foldable=True, content=lcg.Container(content), resource_provider=resource_provider, children=[make_node(r, children) for r in children.get(row['position'].value(), ())]) #data = pytis.data.dbtable('ev_pytis_user_help', # ('help_id', 'fullname', 'spec_name', 'page_id', 'position', # 'title', 'description', 'menu_help', 'content', 'language',), # config.dbconnection) #data.select(condition=pytis.data.EQ('language', pytis.data.sval(current_language())), # sort=(('position', pytis.data.ASCENDENT),)) data = pytis.data.dbtable('ev_pytis_user_help', ('help_id', 'fullname', 'spec_name', 'page_id', 'position', 'title', 'description', 'menu_help', 'content',), config.dbconnection) data.select(sort=(('position', pytis.data.ASCENDENT),)) children = {} while True: row = data.fetchone() if not row: break parent = '.'.join(row['position'].value().split('.')[:-1]) children.setdefault(parent, []).append(row) data.close() nodes = [lcg.ContentNode('help:application', title=_("%s application help") % config.application_name, content=lcg.NodeIndex(), resource_provider=resource_provider, children=[make_node(r, children) for r in children['']]), self._pytis_help(resource_dirs), lcg.ContentNode('NotFound', title=_("Not Found"), hidden=True, content=lcg.p(_("The requested help page not found: %s", topic)), resource_provider=resource_provider)] if topic.startswith('spec/'): # Separate specification descriptions are not in the menu generated # from ev_pytis_help. If specification description page is # requested, we generate one and add it to the menu here. spec_name = topic[5:] title, content = self._spec_help_content(spec_name) if title and content: content = lcg.Container((lcg.TableOfContents(title=_("Contents")), content)) node = lcg.ContentNode('help:'+topic, title=title, hidden=True, content=content, resource_provider=resource_provider) nodes.append(node) root = lcg.ContentNode('help:', content=lcg.Content(), hidden=True, children=nodes) return root.find_node('help:'+topic) or root.find_node('NotFound')
def export_context(lang): exporter = lcg.Html5Exporter(sorted_attributes=True) node = lcg.ContentNode('test') return exporter.context(node, lang=lang, timezone=Timezone())
def _pdf(self): start_time = pytis.data.DateTime.now() T = pytis.data.DBTransactionDefault transaction = T(connection_data=pytis.config.dbconnection, isolation=T.REPEATABLE_READ) template_nodes = [] if self._form is not None and self._row_template is not None: i = 1 row_template = self._row_template for row in self._form.presented_rows(): row_lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, current_row=row, parameters=self._parameters) id_ = 'pytissubdoc%d' % (i, ) row_template_lcg = row_template.lcg() parameters = self._template_parameters(row_template) document = lcg.ContentNode( id=id_, title=' ', # let's avoid printing the id content=row_template_lcg, globals=row_lcg_globals, **parameters) template_nodes.append(document) i += 1 lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, parameters=self._parameters) lcg_globals['app'] = self._application_variables def margin(key): size = self._page_layout.get(key) if size is None: size = UMm(10) return size presentation = lcg.Presentation( font_name='DejaVu', font_family=lcg.FontFamily.FIXED_WIDTH, top_margin=margin(PAGE_TOP_MARGIN), bottom_margin=margin(PAGE_BOTTOM_MARGIN), left_margin=margin(PAGE_LEFT_MARGIN), right_margin=margin(PAGE_RIGHT_MARGIN), page_width=self._page_layout.get(PAGE_WIDTH), page_height=self._page_layout.get(PAGE_HEIGHT), landscape=self._page_layout.get(PAGE_LANDSCAPE_MODE), ) start_time_export = pytis.data.DateTime.now() exporter = lcg.pdf.PDFExporter(translations=self._translations) body = xtuple(self._body) if self._body else () body_nodes = [doc.lcg_document(globals=lcg_globals) for doc in body] root_node = lcg.ContentNode(id='__dummy', content=lcg.Content(), children=body_nodes + template_nodes, **self._body_parameters) context = exporter.context(root_node, self._language, presentation=lcg.PresentationSet(self._style or [])) try: pdf = exporter.export(context, global_presentation=presentation) except lcg.SubstitutionIterator.IteratorError as e: message = _( "Invalid use of iterator.\n" "Maybe you refer to an non-existent or inaccessible object in the table?" ) message += "\n" + unistr(e) pytis.form.run_dialog(pytis.form.Error, message) return '' show_time = pytis.data.DateTime.now() log(EVENT, ('Output formatting took %.3fs (PDF export %.3fs)' % ( pytis.data.DateTime.diff_seconds(start_time, show_time), pytis.data.DateTime.diff_seconds(start_time_export, show_time), ))) try: transaction.commit() except pytis.data.DBSystemException: pass return pdf