def get_table_summary(cls, obj, ar): """Customized :meth:`summary view <lino.core.actors.Actor.get_table_summary>` for this table. """ sar = cls.request_from(ar, master_instance=obj) html = [] # items = [ar.obj2html(o, str(o.milestone)) for o in sar] qs = cls.model.objects.filter(ticket=obj) qs = dd.plugins.tickets.milestone_model.add_param_filter( qs, lookup_prefix='milestone__', # show_active=dd.YesNo.yes ) items = E.ul() for o in qs: items.append( E.li(o.obj2href(ar, text=getattr(o.wish_type,'text', _("Wish"))), " in ", o.milestone.obj2href(ar), " : ", o.remark) ) if len(items) > 0: html.append(tostring(items)) # items = [o.milestone.obj2href(ar) for o in sar] sar = cls.insert_action.request_from(sar) if sar.get_permission(): btn = sar.ar2button() html.append(btn) return ar.html_text(ar.parse_memo(tostring(html)))
def render_request(self, ar, sar): """ Render the given table action request. `ar` is the incoming request (the one which displays the dashboard), `sar` is the table we want to show (a child of `ar`). This is a helper function for shared use by :class:`ActorItem` and :class:`RequestItem`. """ T = sar.actor if not sar.get_total_count(): # print("20180212 render no rows in ", sar) return '' if self.header_level is None: s = '' else: s = tostring(E.h2( str(sar.actor.get_title_base(sar)), ' ', ar.window_action_button( T.default_action, # label="🗗", # label="☌", # conjunction # label="◱", # 25F1 # label="◳", # 25F3 # label="⏍", # 23CD label="⏏", # 23CF # label="⍐", # 2350 # style="text-decoration:none; font-size:80%;", style="text-decoration:none;", title=_("Show this table in own window")))) s += tostring(ar.show(sar)) return s
def get_table_summary(cls, obj, ar): """Customized :meth:`summary view <lino.core.actors.Actor.get_table_summary>` for this table. """ sar = cls.request_from(ar, master_instance=obj) html = [] # items = [ar.obj2html(o, str(o.milestone)) for o in sar] qs = cls.model.objects.filter(ticket=obj) qs = dd.plugins.tickets.milestone_model.add_param_filter( qs, lookup_prefix='milestone__', # show_active=dd.YesNo.yes ) items = E.ul() for o in qs: items.append( E.li( o.obj2href(ar, text=getattr(o.wish_type, 'text', _("Wish"))), " in ", o.milestone.obj2href(ar), " : ", o.remark)) if len(items) > 0: html.append(tostring(items)) # items = [o.milestone.obj2href(ar) for o in sar] sar = cls.insert_action.request_from(sar) if sar.get_permission(): btn = sar.ar2button() html.append(btn) return ar.html_text(ar.parse_memo(tostring(html)))
def show_story(self, ar, story, stripped=True, **kwargs): """ Render the given story and return it as a raw HTML string. Ignore `stripped` because it makes no sense in HTML. """ from lino.core.actors import Actor from lino.core.tables import TableRequest from lino.core.requests import ActionRequest elems = [] try: for item in forcetext(story): # print("20180907 {}".format(item)) if isinstance(item, str): elems.append(item) elif iselement(item): # 20200501 elems.append(item) elems.append(tostring(item)) elif isinstance(item, type) and issubclass(item, Actor): ar = item.default_action.request(parent=ar) # 20200501 elems.extend(self.table2story(ar, **kwargs)) elems += [tostring(e) for e in self.table2story(ar, **kwargs)] elif isinstance(item, TableRequest): assert item.renderer is not None # 20200501 elems.extend(self.table2story(item, **kwargs)) elems += [tostring(e) for e in self.table2story(item, **kwargs)] elif isinstance(item, ActionRequest): # example : courses.StatusReport in dashboard assert item.renderer is not None # 20200501 elems.append(self.show_story(ar, item.actor.get_story(None, ar), **kwargs)) elems += [tostring(e) for e in self.show_story(ar, item.actor.get_story(None, ar), **kwargs)] elif isinstance(item, DashboardItem): elems.extend(item.render(ar, **kwargs)) # html = self.show_story(ar, item.render(ar), **kwargs) # elems.append(html) # # 20200501 if len(html): # # elems.append(E.div( # # html, # # CLASS="dashboard-item " + item.actor.actor_id.replace(".","-") if getattr(item, "actor", False) else "" # if html: # should always be a string, never a list # if hasattr(item, "actor"): # css_class = "dashboard-item " + item.actor.actor_id.replace(".","-") # else: # css_class = '' # elems.append('<div class="{}">{}</div>'.format(css_class, html)) elif isiterable(item): elems.append(self.show_story(ar, item, **kwargs)) # for i in self.show_story(item, *args, **kwargs): # yield i else: raise Exception("Cannot handle story item %r" % item) except Warning as e: elems.append(str(e)) # print("20180907 show_story in {} : {}".format(ar.renderer, elems)) # return E.div(*elems) if len(elems) else "" if len(elems): return "<div>{}</div>".format(''.join(elems)) return ""
def as_li(cls, self, ar): chunks = [ar.parse_memo(self.body_preview)] by = _("{0} by {1}").format( naturaltime(self.created), str(self.user)) if (self.modified - self.created).total_seconds() < 1: t = _("Created " + self.created.strftime('%Y-%m-%d %H:%M') ) else: t = _("Modified " + self.modified.strftime('%Y-%m-%d %H:%M') ) chunks += [ " (", tostring(ar.obj2html(self, by, title=t)), ")" ] # if self.more_text: # chunks.append(" (...)") if ar.get_user().authenticated: sar = cls.insert_action.request_from(ar) # print(20170217, sar) sar.known_values = dict(reply_to=self, owner=self.owner) if sar.get_permission(): btn = sar.ar2button( None, _("Reply"), icon_name=None) chunks.append(' '+tostring(btn)) html = ''.join(chunks) return html
def as_li(cls, self, ar): # chunks = [ar.parse_memo(self.short_preview)] chunks = [self.short_preview] by = _("{0} by {1}").format(naturaltime(self.created), str(self.user)) if (self.modified - self.created).total_seconds() < 1: t = _("Created " + self.created.strftime('%Y-%m-%d %H:%M')) else: t = _("Modified " + self.modified.strftime('%Y-%m-%d %H:%M')) chunks += [" (", tostring(ar.obj2html(self, by, title=t)), ")"] # if self.more_text: # chunks.append(" (...)") if ar.get_user().authenticated: sar = cls.insert_action.request_from(ar) # print(20170217, sar) sar.known_values = dict(reply_to=self, owner=self.owner) if sar.get_permission(): btn = sar.ar2button(None, _("Reply"), icon_name=None) chunks.append(' ' + tostring(btn)) html = ''.join(chunks) return html
def get_rfc_description(self, ar): html = '' _ = gettext if self.description: # html += tostring(E.b(_("Description"))) html += ar.parse_memo(self.description) if self.upgrade_notes: html += tostring(E.b(_("Resolution"))) + ": " html += ar.parse_memo(self.upgrade_notes) if self.duplicate_of_id: html += tostring(_("Duplicate of")) + " " html += tostring(self.duplicate_of.obj2href(ar)) return html
def resolve_conflicts(self, we, ar, rset, until): date = we.start_date if rset == Recurrencies.once: return date if not self.care_about_conflicts(we): return date # if date.day == 9 and date.month == 3: # ar.info("20171130 resolve_conflicts() %s", # we.has_conflicting_events()) # ar.debug("20140310 resolve_conflicts %s", we.start_date) while we.has_conflicting_events(): qs = we.get_conflicting_events() date = rset.get_next_alt_date(ar, date) ar.debug("%s wants %s but conflicts with %s, moving to %s. ", we.summary, we.start_date, qs, date) if date is None or date > until: ar.debug("Failed to get next date for %s (%s > %s).", we, date, until) conflicts = [tostring(ar.obj2html(o)) for o in qs] msg = ', '.join(conflicts) ar.warning("%s conflicts with %s. ", we, msg) return None rset.move_event_to(we, date) return date
def as_button(self, *args, **kwargs): """Return a HTML chunk with a "button" which, when clicked, will execute this action on this instance. This is being used in the :ref:`lino.tutorial.polls`. """ return tostring(self.as_button_elem(*args, **kwargs))
def get_address_html(self, *args, **kwargs): """Returns the full postal address a a string containing html markup of style:: <p>line1<br/>line2...</p> This returns always exactly one paragraph, even if the address is empty (in which case the paragraph is empty): >>> print(TestAddress().get_address_html()) <p/> Optional attributes for the enclosing `<p>` tag can be specified as keyword arguments. Example: >>> addr = TestAddress('line1', 'line2') >>> print(addr.get_address_html(**{'class':"Recipient"})) <p class="Recipient">line1<br/>line2</p> If `min_height` is specified, makes sure that the string contains at least that many lines. Adds as many empty lines (``<br/>``) as needed. This is useful in a template which wants to get a given height for every address. >>> print(addr.get_address_html(min_height=5)) <p>line1<br/>line2<br/><br/><br/></p> Any arguments are forwarded to :meth:`lines2p <etgen.html.lines2p>` which is used to pack the address lines into a paragraph (see there for more examples). """ lines = list(self.get_address_lines()) return tostring(lines2p(lines, *args, **kwargs))
def insert_html(self, html, **kw): if html is None or html == '': # Testing for `if not html:` caused a FutureWarning: The # behavior of this method will change in future versions. # Use specific 'len(elem)' or 'elem is not None' test # instead. return '' if iselement(html): html = tostring(html) try: html = html2xhtml(html) except Exception as e: raise Exception( "20150923 html2xhtml(%r) failed: %s" % (html, e)) # dd.logger.info("20180831 insert_html() got:<<<\n%s\n>>>", html) # print(__file__, ">>>") # print(html) # print("<<<", __file__) try: return self.renderXhtml(html, **kw) except Exception as e: if not isinstance(html, six.string_types): raise # some sax parsers refuse unicode strings. # appy.pod always expects utf-8 encoding. # See /blog/2011/0622. html = html.encode('utf-8') # logger.info("20120726 renderXhtml(%r) failed : %s", html, e) return self.renderXhtml(html, **kw)
def get_comment_header(cls, comment, ar): ch = [] if (comment.modified - comment.created).total_seconds() < 1: t = _("Created " + comment.created.strftime('%Y-%m-%d %H:%M')) else: t = _("Modified " + comment.modified.strftime('%Y-%m-%d %H:%M')) ch.append(ar.obj2html(comment, naturaltime(comment.created), title=t)) ch += [" ", _("by"), " ", ar.obj2html(comment.user, str(comment.user))] sar = cls.insert_action.request_from(ar) # print(20170217, sar) sar.known_values = dict(reply_to=comment, **gfk2lookup(comment.__class__.owner, comment.owner)) if ar.get_user().is_authenticated: btn = sar.ar2button(None, _(" Reply "), icon_name=None) # btn.set("style", "padding-left:10px") ch += [" [", btn, "]"] # ch.append(' ') # ch.append( # E.a(u"⁜", onclick="toggle_visibility('comment-{}');".format( # comment.id), title=str(_("Hide")), href="#") # ) return tostring(ch)
def http_response(ar, tplname, context): "Deserves a docstring" u = ar.get_user() lang = get_language() k = (u.user_type, lang) menu = MENUS.get(k, None) if menu is None: menu = settings.SITE.get_site_menu(None, u.user_type) bs3 = settings.SITE.plugins.bootstrap3 if False: # 20150803 home button now in base.html assert bs3.renderer is not None url = bs3.build_plain_url() menu.add_url_button(url, label=_("Home")) e = bs3.renderer.show_menu(ar, menu) menu = tostring(e) MENUS[k] = menu context.update(menu=menu) context = ar.get_printable_context(**context) context['ar'] = ar context['memo'] = ar.parse_memo # MEMO_PARSER.parse env = settings.SITE.plugins.jinja.renderer.jinja_env template = env.get_template(tplname) response = http.HttpResponse(template.render(**context), content_type='text/html;charset="utf-8"') return response
def as_ul(action_spec): a = settings.SITE.models.resolve(action_spec) ar = a.request(user=settings.SITE.user_model.get_anonymous_user()) # 20150810 ar.renderer = self # ar.renderer = settings.SITE.plugins.bootstrap3.renderer return tostring(E.ul(*[obj.as_list_item(ar) for obj in ar]))
def http_response(ar, tplname, context): "Deserves a docstring" u = ar.get_user() lang = get_language() k = (u.user_type, lang) menu = MENUS.get(k, None) if menu is None: menu = settings.SITE.get_site_menu(u.user_type) bs3 = settings.SITE.plugins.bootstrap3 if False: # 20150803 home button now in base.html assert bs3.renderer is not None url = bs3.build_plain_url() menu.add_url_button(url, label=_("Home")) e = bs3.renderer.show_menu(ar, menu) menu = tostring(e) MENUS[k] = menu context.update(menu=menu) context = ar.get_printable_context(**context) context['ar'] = ar context['memo'] = ar.parse_memo # MEMO_PARSER.parse env = settings.SITE.plugins.jinja.renderer.jinja_env template = env.get_template(tplname) response = http.HttpResponse( template.render(**context), content_type='text/html;charset="utf-8"') return response
def get_comment_header(cls, comment, ar): ch = [] if (comment.modified - comment.created).total_seconds() < 1: t = _("Created " + comment.created.strftime('%Y-%m-%d %H:%M')) else: t = _("Modified " + comment.modified.strftime('%Y-%m-%d %H:%M')) ch.append(ar.obj2html( comment, naturaltime(comment.created), title=t)) ch += [" ", _("by"), " ", ar.obj2html(comment.user, str(comment.user))] sar = cls.insert_action.request_from(ar) # print(20170217, sar) sar.known_values = dict( reply_to=comment, **gfk2lookup( comment.__class__.owner, comment.owner)) if ar.get_user().authenticated: btn = sar.ar2button(None, _(" Reply "), icon_name=None) # btn.set("style", "padding-left:10px") ch += [" [", btn, "]"] ch.append(' ') ch.append( E.a(u"⁜", onclick="toggle_visibility('comment-{}');".format( comment.id), title=str(_("Hide")), href="#") ) return tostring(ch)
def resolve_conflicts(self, we, ar, rset, until): date = we.start_date if rset == Recurrencies.once: return date if not self.care_about_conflicts(we): return date # if date.day == 9 and date.month == 3: # ar.info("20171130 resolve_conflicts() %s", # we.has_conflicting_events()) # ar.debug("20140310 resolve_conflicts %s", we.start_date) while we.has_conflicting_events(): qs = we.get_conflicting_events() date = rset.get_next_alt_date(ar, date) ar.debug("%s wants %s but conflicts with %s, moving to %s. ", we.summary, we.start_date, qs, date) if date is None or date > until: ar.debug( "Failed to get next date for %s (%s > %s).", we, date, until) conflicts = [tostring(ar.obj2html(o)) for o in qs] msg = ', '.join(conflicts) ar.warning("%s conflicts with %s. ", we, msg) return None rset.move_event_to(we, date) return date
def insert_html(self, html, **kw): if not HAS_TIDYLIB: raise Exception("You must install tidylib on your system") if html is None or html == '': # Testing for `if not html:` caused a FutureWarning: The # behavior of this method will change in future versions. # Use specific 'len(elem)' or 'elem is not None' test # instead. return '' if iselement(html): html = tostring(html) try: html = html2xhtml(html) except Exception as e: raise Exception( "20150923 html2xhtml(%r) failed: %s" % (html, e)) # dd.logger.info("20180831 insert_html() got:<<<\n%s\n>>>", html) # print(__file__, ">>>") # print(html) # print("<<<", __file__) try: return self.renderXhtml(html, **kw) except Exception as e: if not isinstance(html, six.string_types): raise # some sax parsers refuse unicode strings. # appy.pod always expects utf-8 encoding. # See /blog/2011/0622. html = html.encode('utf-8') # logger.info("20120726 renderXhtml(%r) failed : %s", html, e) return self.renderXhtml(html, **kw)
def __init__(self, ar, message, uid=None): self.message = message self.choices = [] self.choices_dict = {} self.ar = ar str_msg = tostring(message).encode() self.uid = uid if uid is not None else str(md5(str_msg).digest())
def as_ul(action_spec): a = settings.SITE.models.resolve(action_spec) ar = a.request( user=settings.SITE.user_model.get_anonymous_user()) # 20150810 ar.renderer = self # ar.renderer = settings.SITE.plugins.bootstrap3.renderer return tostring(E.ul(*[obj.as_list_item(ar) for obj in ar]))
def as_table2(ar): # 20150810 # ar.renderer = settings.SITE.plugins.bootstrap3.renderer ar.renderer = self t = xghtml.Table() ar.dump2html(t, ar.sliced_data_iterator, header_links=False) #~ print ar.get_total_count() return tostring(t.as_element())
def fmt(obj): s = tostring(ar.action_button(ba, obj)) s += fds(obj.created) + " " + obj.created.strftime( settings.SITE.time_format_strftime) + " " if obj.body: s += ar.parse_memo(obj.body) else: s += ar.parse_memo(obj.subject) e = etree.parse(StringIO(s), html_parser) return E.li(E.div(*e.iter()))
def fmt(obj): s = tostring(ar.action_button(ba, obj)) s += fds(obj.created) + " " + obj.created.strftime( settings.SITE.time_format_strftime) + " " if obj.body: s += ar.parse_memo(obj.body) else: s += ar.parse_memo(obj.subject) # s += obj.body return "<li>{}</li>".format(s)
def get_address_html(self, *args, **kwargs): """ Return the address of the :attr:`recipient` of this object. See :meth:`Addressable.get_address_html <lino.utils.addressable.Addressable.get_address_html>`. """ rec = self.get_recipient() if rec is None: return tostring(lines2p([], *args, **kwargs)) return rec.get_address_html(*args, **kwargs)
def on_update(sender=None, watcher=None, request=None, **kw): """ Log a Change if there is a `change_watcher_spec`. `watcher` is a :class:`lino.core.diff.ChangeWatcher` instance. """ master = get_master(watcher.watched) if master is None: # No master, nothing to log return cs = watcher.watched.change_watcher_spec changed_fields = '' if False: # I tried a html version, but it doesn't help to make # things more end-user friendly. And it caused # problems when being rendered in a grid. changes = list(watcher.get_updates_html(cs.ignored_fields)) if len(changes) == 0: msg = '(no changes)' elif len(changes) == 1: msg = tostring(changes[0]) else: msg = tostring(E.ul(*changes)) else: changes = [] for k, old, new in watcher.get_updates(cs.ignored_fields): changed_fields += k + " " changes.append("%s : %s --> %s" % (k, dd.obj2str(old), dd.obj2str(new))) if len(changes) == 0: msg = '(no changes)' elif len(changes) == 1: msg = changes[0] else: msg = '- ' + ('\n- '.join(changes)) log_change( ChangeTypes.update, request, master, watcher.watched, msg, changed_fields)
def get_table_summary(self, obj, ar): sar = self.request_from(ar, master_instance=obj) html = obj.get_rfc_description(ar) sar = self.insert_action.request_from(sar) if sar.get_permission(): btn = sar.ar2button(None, _("Write comment"), icon_name=None) html += "<p>" + tostring(btn) + "</p>" html += "<ul>" for c in sar: html += "<li>{}<div id=\"{}\">{}</div></li>".format( self.get_comment_header(c, sar), "comment-" + str(c.id), ar.parse_memo(c.body)) html += "</ul>" return ar.html_text(html)
def get_change_body(self, ar, cw): ctx = dict(user=ar.user, what=ar.obj2memo(self)) if cw is None: elems = [E.p(_("{user} created {what}").format(**ctx), ".")] elems += list(self.get_change_info(ar, cw)) else: items = list(cw.get_updates_html(["_user_cache"])) if len(items) == 0: return elems = [] elems += list(self.get_change_info(ar, cw)) elems.append( E.p(_("{user} modified {what}").format(**ctx), ":")) elems.append(E.ul(*items)) # print("20170210 {}".format(tostring(E.div(*elems)))) return tostring(E.div(*elems))
def get_change_body(self, ar, cw): ctx = dict(user=ar.user, what=ar.obj2memo(self)) if cw is None: elems = [E.p( _("{user} created {what}").format(**ctx), ".")] elems += list(self.get_change_info(ar, cw)) else: items = list(cw.get_updates_html(["_user_cache"])) if len(items) == 0: return elems = [] elems += list(self.get_change_info(ar, cw)) elems.append(E.p( _("{user} modified {what}").format(**ctx), ":")) elems.append(E.ul(*items)) # print("20170210 {}".format(tostring(E.div(*elems)))) return tostring(E.div(*elems))
def get_main_card(self, ar): ticket_obj = ar.master_instance sar = self.request_from(ar, master_instance=ticket_obj) html = ticket_obj.get_rfc_description(ar) sar = self.insert_action.request_from(sar) if sar.get_permission(): btn = sar.ar2button(None, _("Write comment"), icon_name=None) html += "<p>" + tostring(btn) + "</p>" if html: return dict( card_title="Description", main_card_body=html, # main_card_body is special keyword id="[main_card]" # needed for map key in react... ) else: return None
def cmd(parser, s): pk = s txt = None ar = parser.context['ar'] kw = dict() # dd.logger.info("20161019 %s", ar.renderer) pk = int(pk) obj = Meeting.objects.get(pk=pk) # try: # except model.DoesNotExist: # return "[{} {}]".format(name, s) if txt is None: txt = "{0}".format(obj.name) kw.update(title=obj.name) e = ar.obj2html(obj, txt, **kw) # return str(ar) return tostring(e)
def get_table_summary(cls, obj, ar): sar = cls.request_from( ar, master_instance=obj, limit=cls.preview_limit) # print "20170208", sar.limit html = "" items = [] for o in sar.sliced_data_iterator: li = cls.as_li(o, ar) if o.owner: #Catch for ownerless hackerish comments li += _(" On: ") + tostring(ar.obj2html(o.owner)) items.append("<li>{}</li>".format(li)) # html += "<p>" + tostring(btn) + "</p>" if len(items) > 0: html += "<div>{0}</div>".format(''.join(items)) return ar.html_text(html)
def as_summary_row(self, ar): """ Return a raw HTML string representing this object in a data view as a single paragraph. The string should represent a single ``<p>``. If :attr:`summary_row_template` is set, this will render this object using the named template, otherwise it will call :meth:`summary_row` and wrap the result into a paragraph. """ if self.summary_row_template: # not tested env = settings.SITE.plugins.jinja.renderer.jinja_env template = env.get_template(self.summary_row_template) context = ar.get_printable_context(obj=self) return template.render(**context) return tostring(E.p(*self.summary_row(ar)))
def get_table_summary(cls, obj, ar): sar = cls.request_from(ar, master_instance=obj, limit=cls.preview_limit) # print "20170208", sar.limit html = "" items = [] for o in sar.sliced_data_iterator: li = cls.as_li(o, ar) if o.owner: #Catch for ownerless hackerish comments li += _(" On: ") + tostring(ar.obj2html(o.owner)) items.append("<li>{}</li>".format(li)) # html += "<p>" + tostring(btn) + "</p>" if len(items) > 0: html += "<div>{0}</div>".format(''.join(items)) return ar.html_text(html)
def elem2rec_detailed(ar, elem, with_navinfo=True, **rec): """Adds additional information for this record, used only by detail views. The "navigation information" is a set of pointers to the next, previous, first and last record relative to this record in this report. (This information can be relatively expensive for records that are towards the end of the queryset. See `/blog/2010/0716`, `/blog/2010/0721`, `/blog/2010/1116`, `/blog/2010/1207`.) recno 0 means "the requested element exists but is not contained in the requested queryset". This can happen after changing the quick filter (search_change) of a detail view. """ rh = ar.ah rec = ar.elem2rec1(rh, elem, None, **rec) if ar.actor.hide_top_toolbar or ar.bound_action.action.hide_top_toolbar: rec.update(title=ar.get_detail_title(elem)) else: #~ print(ar.get_title()) #~ print(dd.obj2str(elem)) #~ print(repr(unicode(elem))) if True: # before 20131017 rec.update(title=ar.get_title() + u" » " + ar.get_detail_title(elem)) else: # todo rec.update(title=tostring(ar.href_to_request(ar)) + u" » " + ar.get_detail_title(elem)) rec.update(id=elem.pk) # rec.update(id=ar.actor.get_pk_field().value_from_object(elem)) if ar.actor.editable: rec.update(disable_delete=rh.actor.disable_delete(elem, ar)) if rh.actor.show_detail_navigator and with_navinfo: rec.update(navinfo=navinfo(ar.data_iterator, elem)) if ar.actor.parameters: rec.update(param_values=ar.actor.params_layout.params_store.pv2dict(ar, ar.param_values)) return rec
def elem2rec_detailed(ar, elem, with_navinfo=True, **rec): """Adds additional information for this record, used only by detail views. The "navigation information" is a set of pointers to the next, previous, first and last record relative to this record in this report. (This information can be relatively expensive for records that are towards the end of the queryset. See `/blog/2010/0716`, `/blog/2010/0721`, `/blog/2010/1116`, `/blog/2010/1207`.) recno 0 means "the requested element exists but is not contained in the requested queryset". This can happen after changing the quick filter (search_change) of a detail view. """ rh = ar.ah rec = ar.elem2rec1(rh, elem, **rec) if ar.actor.hide_top_toolbar or ar.bound_action.action.hide_top_toolbar: rec.update(title=ar.get_detail_title(elem)) else: #~ print(ar.get_title()) #~ print(dd.obj2str(elem)) #~ print(repr(unicode(elem))) if True: # before 20131017 rec.update(title=ar.get_title() + u" » " + ar.get_detail_title(elem)) else: # todo rec.update(title=tostring(ar.href_to_request(ar)) + u" » " + ar.get_detail_title(elem)) rec.update(id=elem.pk) # rec.update(id=ar.actor.get_pk_field().value_from_object(elem)) if ar.actor.editable: rec.update(disable_delete=rh.actor.disable_delete(elem, ar)) if rh.actor.show_detail_navigator and with_navinfo: rec.update(navinfo=navinfo(ar.data_iterator, elem)) return rec
def as_html_table(self, ar): t = xghtml.Table() ar.dump2html(t, ar.data_iterator) return xghtml.tostring(t.as_element())
def show_table(self, *args, **kwargs): return ''.join([ tostring(e) for e in self.table2story(*args, **kwargs)])
def obj2str(self, *args, **kwargs): return tostring(self.obj2html(*args, **kwargs))
def html2odf(e, ct=None, **ctargs): """ Convert a :mod:`etgen.html` element to an ODF text element. Most formats are not implemented. There's probably a better way to do this... :ct: the root element ("container"). If not specified, we create one. """ sections_counter = 1 #~ print "20120613 html2odf()", e.tag, e.text if ct is None: ct = text.P(**ctargs) #~ if e.tag in PTAGS: #~ oe = text.P(**ctargs) #~ else: #~ oe = text.P(**ctargs) #~ logger.info("20130201 %s", tostring(e)) #~ raise NotImplementedError("<%s> without container" % e.tag) if isinstance(e, six.string_types): ct.addText(e) #~ oe = text.Span() #~ oe.addText(e) #~ yield oe return ct if e.tag == 'ul': ct = text.List(stylename='podBulletedList') ctargs = dict(stylename='podBulletItem') #~ ctargs = dict() text_container = None if e.tag in ('b', 'strong'): #~ oe = text.Span(stylename='Bold Text') oe = text.Span(stylename='Strong Emphasis') elif e.tag == 'a': oe = text.Span(stylename='Strong Emphasis') #~ oe = text.Span(stylename='Bold Text') elif e.tag in ('i', 'em'): oe = text.Span(stylename='Emphasis') elif e.tag == 'span': oe = text.Span() elif e.tag == 'br': oe = text.LineBreak() elif e.tag == 'h1': """ <text:h text:style-name="Heading_20_1" text:outline-level="1"> """ oe = ct = text.H(stylename="Heading 1", outlinelevel=1) elif e.tag == 'h2': oe = ct = text.H(stylename="Heading 2", outlinelevel=2) elif e.tag == 'h3': oe = ct = text.H(stylename="Heading 3", outlinelevel=3) elif e.tag == 'div': oe = ct = text.Section(name="S" + str(sections_counter)) elif e.tag == 'img': return # ignore images elif e.tag == 'ul': oe = ct #~ elif e.tag in ('ul','ol'): #~ oe = text.List(stylename=e.tag.upper()) #~ ctargs = dict(stylename=e.tag.upper()+"_P") elif e.tag == 'li': #~ oe = ct oe = text.ListItem() text_container = text.P(**ctargs) oe.appendChild(text_container) elif e.tag in PTAGS: oe = ct #~ if ct.tagName == 'p': #~ oe = ct #~ else: #~ oe = text.P(**ctargs) else: logger.info("20130201 %s", tostring(e)) raise NotImplementedError("<%s> inside <%s>" % (e.tag, ct.tagName)) #~ oe = text.Span() if text_container is None: text_container = oe if e.text: text_container.addText(e.text) for child in e: #~ html2odf(child,oe) html2odf(child, text_container, **ctargs) #~ for oc in html2odf(child,oe): # ~ # oe.addElement(oc) #~ oe.appendChild(oc) #~ if not True: #~ if e.tail: #~ oe.addText(e.tail) if oe is not ct: ct.appendChild(oe) #~ yield oe #~ if True: if e.tail: #~ yield e.tail #~ yield text.Span(text=e.tail) #~ yield Text(e.tail) ct.addText(e.tail) return ct
def as_html_table(self, ar): t = xghtml.Table() ar.dump2html(t, ar.data_iterator, header_links=False) return xghtml.tostring(t.as_element())
def show_story(self, *args, **kwargs): """Render the story and return it as a string.""" e = super(JinjaRenderer, self).show_story(*args, **kwargs) return tostring(e)
def test_this(self): Person = rt.models.contacts.Person Link = rt.models.humanlinks.Link LinkTypes = rt.models.humanlinks.LinkTypes LinksByHuman = rt.models.humanlinks.LinksByHuman father = create( Person, first_name="John", last_name="Doe", gender="M", birth_date='1980-07-31') try: son = create( Person, first_name="Joseph", last_name="Doe", gender="M", birth_date=IncompleteDate(2009, 2, 30)) except ValidationError: pass else: self.fail("Expected ValidationError") son = create( Person, first_name="Joseph", last_name="Doe", gender="M", birth_date='2009-02-28') create(Link, parent=father, child=son, type=LinkTypes.parent) mary = create( Person, first_name="Mary", last_name="Doe", gender="F", birth_date='2010-01-30') create(Link, parent=father, child=mary, type=LinkTypes.parent) self.assertEqual(Person.objects.count(), 3) ar = LinksByHuman.request(father) s = ar.to_rst() # print(s) self.assertEquivalent(""" John is Father of *Mary* (4 years) Father of *Joseph* (5 years) """, s) # Create relationship as **Father**/**Son** **Adoptive # father**/**Adopted son** **Foster father**/**Foster son** # **Husband** **Partner** **Stepfather**/**Stepson** **Brother** # **Cousin** **Uncle**/**Nephew** **Relative** **Other** """, s) with translation.override('de'): ar = LinksByHuman.request(father) s = ar.to_rst() # print(s) self.assertEquivalent(""" John ist Vater von *Mary* (4 Jahre) Vater von *Joseph* (5 Jahre) """, s) # Beziehung erstellen als **Vater**/**Sohn** # **Adoptivvater**/**Adoptivsohn** # **Pflegevater**/**Pflegesohn** **Ehemann** **Partner** # **Stiefvater**/**Stiefsohn** **Bruder** **Vetter** # **Onkel**/**Neffe** **Verwandter** **Sonstiger** """, s) with translation.override('fr'): ar = LinksByHuman.request(father) s = ar.to_rst() # print(s) self.assertEquivalent(u""" John est Père de *Mary* (4 ans) Père de *Joseph* (5 ans) """, s) # Créer lien de parenté en tant que **Père**/**Fils** **Père # adoptif**/**Fils adoptif** **Père nourricier**/**Fils # nourricier** **Mari** **Partenaire** # **Beau-père**/**Beau-fils** **Frère** **Cousin** # **Oncle**/**Nephew** **Parent** **Autre** """, s) # Here we are just testing whether no exception is risen. The # ouptut itself is more thoroughly tested elsewhere. html = LinksByHuman.get_table_summary(father, ar) s = tostring(html) self.assertEqual(s[:5], '<div>')
def show_story(self, *args, **kwargs): e = super(MailRenderer, self).show_story(*args, **kwargs) return tostring(e)
def get(self, request, app_label=None, actor=None): ar = action_request(app_label, actor, request, request.GET, True) ar.renderer = settings.SITE.kernel.extjs_renderer rh = ar.ah fmt = request.GET.get(constants.URL_PARAM_FORMAT, ar.bound_action.action.default_format) # print(20170921, fmt) if fmt == constants.URL_FORMAT_JSON: rows = [ rh.store.row2list(ar, row) for row in ar.sliced_data_iterator ] total_count = ar.get_total_count() # raise Exception("20171208 {}".format(ar.data_iterator.query)) for row in ar.create_phantom_rows(): if ar.limit is None or len( rows) + 1 < ar.limit or ar.limit == total_count + 1: d = rh.store.row2list(ar, row) rows.append(d) total_count += 1 kw = dict(count=total_count, rows=rows, success=True, no_data_text=ar.no_data_text) if True: kw.update(title=str(ar.get_title())) else: # 20190704 work in progress. # add open_in_own_window button after title of slave panel kw.update(title=str(ar.get_title()) + " " + tostring(ar.open_in_own_window_button())) if ar.actor.parameters: kw.update( param_values=ar.actor.params_layout.params_store.pv2dict( ar, ar.param_values)) kw.update(test_version_mismatch(request)) return json_response(kw) if fmt == constants.URL_FORMAT_HTML: after_show = ar.get_status() sp = request.GET.get(constants.URL_PARAM_SHOW_PARAMS_PANEL, None) if sp is not None: # ~ after_show.update(show_params_panel=sp) after_show.update( show_params_panel=constants.parse_boolean(sp)) # if isinstance(ar.bound_action.action, actions.ShowInsert): # elem = ar.create_instance() # rec = ar.elem2rec_insert(rh, elem) # after_show.update(data_record=rec) kw = dict(on_ready=ar.renderer.action_call( ar.request, ar.bound_action, after_show)) # ~ print '20110714 on_ready', params kw.update(title=ar.get_title()) return http.HttpResponse(ar.renderer.html_page(request, **kw)) if fmt == 'csv': # ~ response = HttpResponse(mimetype='text/csv') charset = settings.SITE.csv_params.get('encoding', 'utf-8') response = http.HttpResponse(content_type='text/csv;charset="%s"' % charset) if False: response['Content-Disposition'] = \ 'attachment; filename="%s.csv"' % ar.actor else: # ~ response = HttpResponse(content_type='application/csv') response['Content-Disposition'] = \ 'inline; filename="%s.csv"' % ar.actor # ~ response['Content-Disposition'] = 'attachment; filename=%s.csv' % ar.get_base_filename() w = ucsv.UnicodeWriter(response, **settings.SITE.csv_params) w.writerow(ar.ah.store.column_names()) if True: # 20130418 : also column headers, not only internal names column_names = None fields, headers, cellwidths = ar.get_field_info(column_names) w.writerow(headers) for row in ar.data_iterator: w.writerow([str(v) for v in rh.store.row2list(ar, row)]) return response if fmt == constants.URL_FORMAT_PRINTER: if ar.get_total_count() > MAX_ROW_COUNT: raise Exception( _("List contains more than %d rows") % MAX_ROW_COUNT) response = http.HttpResponse( content_type='text/html;charset="utf-8"') doc = Document(force_text(ar.get_title())) doc.body.append(E.h1(doc.title)) t = doc.add_table() # ~ settings.SITE.kernel.ar2html(ar,t,ar.data_iterator) ar.dump2html(t, ar.data_iterator) doc.write(response, encoding='utf-8') return response return settings.SITE.kernel.run_action(ar)