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 _make_table(self): form = self._form if form is None: return lcg.Content() table = pytis.output.data_table(form.view_spec(), form.data(), condition=form.condition(), sorting=form.sorting(), transaction=self._transaction) return table.lcg()
def _make_agg(self, op): if self._form is None: return lcg.Content() dictionary = _ProxyDict() for column in self._form.data().columns(): if op == pytis.data.Data.AGG_COUNT or isinstance(column.type(), pytis.data.Number): def value(column=column): return self._make_agg_value(op, column) dictionary[column.id()] = value return dictionary
def _make_agg_value(self, op, column): form = self._form if form is None: return lcg.Content() colid = column.id() if not pytis.form.has_access(form.name(), perm=pytis.data.Permission.VIEW, column=colid): return column.type().secret_export() data = form.data() condition = form.condition() return data.select_aggregate((op, colid,), condition=condition, transaction=self._transaction).value()
def _root(self): if self._root_node: node = self._root_node else: node = self.ContentNode('help:', content=lcg.Content(), hidden=True, children=( self.ContentNode('help:application', title=_("%s application help") % pytis.config.application_name, content=lcg.NodeIndex(), foldable=True, resource_provider=self._resource_provider, children=self._application_help_nodes()), self._pytis_help_nodes(), )) self._root_node = node return node
def _content(self, record): par = os.path.pardir return pytis.util.lcg_node( ( lcg.fieldset(( (_("Price"), record['price'].export()), (_("Available since"), lcg.LocalizableDateTime(record['since'].value())), )), lcg.sec(_("Notes"), lcg.Parser().parse(record['notes'].value()), name='notes') if record['notes'].value() else lcg.Content(), ), title=record['product'].value(), resource_path=(os.path.normpath(os.path.join(__file__, par, par, par, par, 'css')),), resources=('pytis-demo-product.css',), )
def _application_help_page_content(self, node, uri): self._data.select(condition=pd.EQ('help_id', pd.sval(uri[5:]))) row = self._data.fetchone() self._data.close() if row: if row['page_id'].value(): storage = pytis.presentation.DbAttachmentStorage( 'e_pytis_help_pages_attachments', 'page_id', row['page_id'].value(), ) return lcg.Container(lcg.Parser().parse(row['content'].value() or ''), resources=storage.resources()) if row['menu_help'].value(): return lcg.Parser().parse(row['menu_help'].value()) else: spec_name = row['spec_name'].value() # TODO: Use the default descriptions from HelpUpdater. if spec_name: content = self._spec_help_content(spec_name)[1] if content: return content return lcg.Content()
def _lcg(self): return lcg.Content()
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 _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
def __init__(self, id, title=None, brief_title=None, heading=None, descr=None, children=(), hidden=False, active=True, foldable=False, resource_provider=None, globals=None, cover_image=None, metadata=None, variants=(), **kwargs): """Initialize the instance. Arguments: id -- a unique textual identifier of this node (as a string). title -- the title of this node (as a unicode string). brief_title -- the brief (shorter) form of title of this node (as a unicode string). If given, this title will be used to refer to this node from places, where brevity matters. If None, the 'title' will be used instead. heading -- content to be used as node heading. By default (when None), the content is created automatically as TextContent(title), but you may pass any lcg.Content instance when some more fancy content is desired. descr -- a short textual description of this node (as a uni code string). Additional information, which may determine the content of the node in addition to the title. children -- a sequence of child nodes in the hierarchy. hidden -- a boolean flag indicating, that this node should not appear in the automatically generated Indexes (Tables of Contents). Such a node will usually be refered explicitely. active -- a boolean flag indicating, that this node is active. Usage of this flag may be application specific and there is currently no difference in behavior of LCG in respect to this flag, except for marking the items by css class 'inactive' on export. foldable -- iff true, the node's submenu will be presented as a foldable in foldable tree presentations which support it. resource_provider -- a 'ResourceProvider' instance or None. globals -- node global variables as a dictionary keyed by variable names. The variables are allowed to contain nested dictionaries. The variables are used for substitution by `Substitution' instances, but they may be also used for other purposes depending on the application. cover_image -- 'lcg.Resource' instance to be used as a cover image. metadata -- an instance of 'lcg.Metadata' defining the publication meta data; Only relevant for the root node of the publication. variants -- available language variants of this node as a sequence of 'Variant' instances. Each item may define a language specific variant of language dependent attributes, such as 'content', 'page_header', 'page_footer' etc. (see 'Variant' constructor arguments for a complete list). These variant specific values will take precedence over the same attributes passed directly as 'ContentNode' arguments (see below). content, page_header, first_page_header, page_footer, left_page_footer, right_page_footer, page_background, presentation -- default variants of node content and parameters may be passed directly as node keyword arguments. The names and meaning of the arguments match the names of 'lcg.Variant' constructor arguments. These defaults are used when no matching variant is found in 'variants' for given export language, when that variant does not define given attribute (such as 'page_footer') or when 'lang' is not passed to the methods obtaining given content or parameter. The most typical usage is for language independent content, which consists of localizable texts (see 'lcg.Localizable') or for content of undefined language -- 'ContentNode' doesn't force you to define the language of the content. """ assert isinstance(id, basestring), repr(id) assert isinstance(hidden, bool), hidden assert isinstance(active, bool), active assert isinstance(foldable, bool), foldable assert is_sequence_of(variants, Variant) assert is_sequence_of(children, ContentNode) assert cover_image is None or isinstance(cover_image, lcg.Image), cover_image assert metadata is None or isinstance(metadata, Metadata) assert heading is None or isinstance(heading, lcg.Content), heading self._id = id self._parent = None # parent self._title = title if title is not None else brief_title or id self._heading = heading or lcg.TextContent(self._title) self._brief_title = brief_title or title self._descr = descr self._hidden = hidden self._active = active self._foldable = foldable for child in children: child._set_parent(self) self._children = tuple(children) self._resource_provider = resource_provider if globals is None: self._globals = {} else: self._globals = copy.copy(globals) self._metadata = metadata self._variants = tuple(v.lang() for v in variants) self._variants_dict = dict((v.lang(), v) for v in variants) self._default_variant = Variant('--', **kwargs) self._cover_image = cover_image for variant in tuple(variants) + (self._default_variant,): if variant.content(): variant.content().set_parent(self) self._empty_content = lcg.Content() # if __debug__: # seen = {} # for n in self.linear(): # nid = n.id() # assert nid not in seen, \ # "Duplicate node id: %s, %s" % (n, seen[nid]) # seen[nid] = n self._used_content_resources = []