def get_change_desc_html(self, f, old, new): from lino.core.choicelists import ChoiceListField if isinstance(f, models.TextField): old = old or '' new = new or '' return E.li( E.b(f.verbose_name), " : ", E.pre('\n'.join(difflib.unified_diff( old.splitlines(), new.splitlines(), fromfile="before", tofile="after", lineterm='')))) if isinstance(f, models.DateTimeField): return if isinstance(f, models.ForeignKey): if old: old = f.rel.to.objects.get(pk=old) if new: new = f.rel.to.objects.get(pk=new) elif isinstance(f, ChoiceListField): if isinstance(old, six.string_types): old = f.choicelist.get_by_value(old) if isinstance(new, six.string_types): new = f.choicelist.get_by_value(new) else: old = obj2str(old) new = obj2str(new) return E.li( E.b(f.verbose_name), " : ", u"{0} --> {1}".format(old, new))
def welcome_messages(ar): """Yield messages for the welcome page.""" Session = rt.modules.clocking.Session # Ticket = rt.modules.tickets.Ticket # TicketStates = rt.modules.tickets.TicketStates me = ar.get_user() busy_tickets = set() # your open sessions (i.e. those you are busy with) qs = Session.objects.filter(user=me, end_time__isnull=True) if qs.count() > 0: chunks = [E.b(unicode(_("You are busy with ")))] sep = None for ses in qs: if sep: chunks.append(sep) busy_tickets.add(ses.ticket.id) txt = unicode(ses.ticket) chunks.append( ar.obj2html(ses.ticket, txt, title=ses.ticket.summary)) chunks += [ ' (', ar.instance_action_button( ses.end_session, EndTicketSession.label), ')'] sep = ', ' chunks.append('. ') yield E.p(*chunks)
def welcome_html(self, ui=None): "See :meth:`ad.Site.welcome_html`." from django.utils.translation import ugettext as _ p = [] sep = '' if self.verbose_name: p.append(_("This is ")) if self.url: p.append( E.a(self.verbose_name, href=self.url, target='_blank')) else: p.append(E.b(self.verbose_name)) if self.version: p.append(' ') p.append(self.version) sep = _(' using ') for name, version, url in self.get_used_libs(html=E): p.append(sep) p.append(E.a(name, href=url, target='_blank')) p.append(' ') p.append(version) sep = ', ' return E.span(*p)
def get_slave_summary(self, obj, ar): elems = [] sar = self.request(master_instance=obj) # elems += ["Partner:", unicode(ar.master_instance)] for voucher in sar: vc = voucher.get_mti_leaf() if vc and vc.state.name == "draft": elems += [ar.obj2html(vc), " "] vtypes = [] for vt in VoucherTypes.items(): if issubclass(vt.model, VatDocument): vtypes.append(vt) actions = [] if not ar.get_user().profile.readonly: for vt in vtypes: for jnl in vt.get_journals(): sar = vt.table_class.insert_action.request_from( ar, master_instance=jnl, known_values=dict(partner=obj)) btn = sar.ar2button(label=unicode(jnl), icon_name=None) if len(actions): actions.append(', ') actions.append(btn) elems += [E.br(), _("Create voucher in journal"), " "] + actions return E.div(*elems)
def workflow_buttons(obj, ar): #~ logger.info('20120930 workflow_buttons %r', obj) l = [] if ar is not None: actor = ar.actor state = actor.get_row_state(obj) if state is not None: #~ l.append(E.b(unicode(state),style="vertical-align:middle;")) l.append(E.b(unicode(state))) #~ l.append(u" » ") #~ l.append(u" \u25b8 ") #~ l.append(u" \u2192 ") #~ sep = u" \u25b8 " sep = u" \u2192 " else: # logger.info('20150602 no state for %s in %s (%s)', # obj, actor, actor.model) sep = '' for ba in actor.get_actions(): if ba.action.show_in_workflow: if actor.get_row_permission(obj, ar, state, ba): l.append(sep) l.append(ar.action_button(ba, obj)) sep = ' ' return E.span(*l)
def collect_summary(prefix, fk_qs): parts = [] for fld, qs in fk_qs: if qs.count() > 0: parts.append("%d %s" % (qs.count(), str(fld.model._meta.verbose_name_plural))) if len(parts) != 0: items.append(E.li(", ".join(parts), " ", E.b(prefix)))
def to_rst(cls, ar, column_names=None, header_level=None, **kwargs): "Better name would be table2rst (analog to table2xhtml())" fields, headers, widths = ar.get_field_info(column_names) # ~ # in case column_names contains remote fields #~ settings.SITE.startup() #~ settings.SITE.resolve_virtual_fields() #~ grid = ar.ah.list_layout.main sums = [fld.zero for fld in fields] rows = [] recno = 0 #~ for row in ar: for row in ar.sliced_data_iterator: recno += 1 rows.append([x for x in ar.row2text(fields, row, sums)]) #~ rows.append([x for x in grid.row2html(ar,fields,row,sums)]) has_sum = False for i in sums: if i: #~ print '20120914 zero?', repr(i) has_sum = True break if has_sum: rows.append([x for x in ar.sums2html(fields, sums)]) t = RstTable(headers, **kwargs) s = t.to_rst(rows) if header_level is not None: s = E.tostring(E.h2(ar.get_title())) + s return s
def get_slave_summary(self, obj, ar): # For every child, we want to display its relationship to # every parent of this household. sar = self.request(master_instance=obj) if sar.master_household is None: return E.div(ar.no_data_text) # obj is the Person for which we display the household def format_item(m): elems = [unicode(m.role), ': '] if m.person: elems += [obj.format_family_member(ar, m.person)] hl = self.find_links(ar, m.person, obj) if len(hl): elems += [' ('] + hl + [')'] else: elems += [obj.format_family_member(ar, m)] return elems items = [] for m in sar.data_iterator: items.append(E.li(*format_item(m))) elems = [] if len(items) > 0: elems = [] elems.append(E.ul(*items)) return E.div(*elems)
def get_slave_summary(self, obj, ar): vtypes = set() for m in dd.models_by_base(vat.VatDocument): vtypes.add( VoucherTypes.get_by_value(dd.full_model_name(m))) elems = [] actions = [] def add_action(btn): if btn is None: return False actions.append(btn) return True for jnl in Journal.objects.filter(voucher_type__in=vtypes): sar = ar.spawn( InvoicesByJournal, master_instance=jnl, known_values=dict(partner=obj)) # logger.info( # "20140604 sar.requesting_panel %s", # sar.requesting_panel) if add_action(sar.insert_button(unicode(jnl), icon_name=None)): actions.append(' ') elems += [E.br(), _("Create voucher in journal ")] + actions return E.div(*elems)
def get_slave_summary(self, obj, ar): """Displays a summary of all responses for a given partner using a bullet list grouped by poll. """ if obj is None: return visible_polls = Poll.objects.filter( state__in=(PollStates.published, PollStates.closed)).order_by('ref') qs = Response.objects.filter(partner=obj).order_by('date') polls_responses = {} for resp in qs: polls_responses.setdefault(resp.poll.pk, []).append(resp) items = [] for poll in visible_polls: iar = self.insert_action.request_from(ar, obj, known_values=dict(poll=poll)) elems = [str(poll), ' : '] responses = polls_responses.get(poll.pk, []) elems += join_elems( [ar.obj2html(r, dd.fds(r.date)) for r in responses], sep=', ') if poll.state == PollStates.published: elems += [' ', iar.ar2button()] #elems += [' ', iar.insert_button()] items.append(E.li(*elems)) return E.div(E.ul(*items))
def get_change_body(self, ar, cw): """Returns the text of the notification message to emit. The default implementation returns a message of style "{object} has been modified by {user}" followed by a summary of the changes. Application code can override this. Returning None or an empty string means to suppress notification. """ if cw is None: elems = [ E.p(ar.obj2memo(self), ' ', _("has been created by {user}").format(user=ar.get_user())) ] else: items = list(cw.get_updates_html()) if len(items) == 0: return elems = [ E.p( ar.obj2memo(self), ' ', _("has been modified by {user}").format( user=ar.get_user()), ":") ] elems.append(E.ul(*items)) return E.tostring(E.div(*elems))
def href_button( self, url, text, title=None, target=None, icon_name=None, **kw): """ Returns an etree object of a "button-like" ``<a href>`` tag. """ # logger.info('20121002 href_button %s', unicode(text)) if target: kw.update(target=target) if title: # Remember that Python 2.6 doesn't like if title is a Promise kw.update(title=unicode(title)) #~ return xghtml.E.a(text,href=url,title=title) if not isinstance(text, (tuple, list)): text = (text,) if url is None: return E.b(*text) kw.update(href=url) if icon_name is not None: src = settings.SITE.build_media_url( 'lino', 'extjs', 'images', 'mjames', icon_name + '.png') img = E.img(src=src, alt=icon_name) return E.a(img, **kw) else: return E.a(*text, **kw)
def as_ul(action_spec): a = settings.SITE.modules.resolve(action_spec) ar = a.request(user=AnonymousUser.instance()) # 20150810 ar.renderer = self # ar.renderer = settings.SITE.plugins.bootstrap3.renderer return E.tostring(E.ul(*[obj.as_list_item(ar) for obj in ar]))
def href_button(self, url, text, title=None, target=None, icon_name=None, **kw): """ Returns an etree object of a "button-like" ``<a href>`` tag. """ #~ logger.info('20121002 href_button %r',unicode(text)) if target: kw.update(target=target) if title: # Remember that Python 2.6 doesn't like if title is a Promise kw.update(title=unicode(title)) #~ return xghtml.E.a(text,href=url,title=title) kw.update(href=url) #~ if icon_name: if icon_name is not None: #~ btn = xghtml.E.button(type='button',class_='x-btn-text '+icon_name) #~ btn = xghtml.E.button( #~ type='button', #~ class_='x-btn-text '+icon_name, #~ onclick='function() {console.log(20121024)}') #~ return btn #~ return xghtml.E.a(btn,**kw) #~ kw.update(class_='x-btn-text '+icon_name) img = E.img(src=settings.SITE.build_media_url( 'lino', 'extjs', 'images', 'mjames', icon_name + '.png')) return E.a(img, **kw) else: #~ return E.span('[',xghtml.E.a(text,**kw),']') #~ kw.update(style='border-width:1px; border-color:black; border-style:solid;') return E.a(text, **kw)
def build_confirmation_message(self): self.analyze() items = [] def collect_summary(prefix, fk_qs): parts = [] for fld, qs in fk_qs: if qs.count() > 0: parts.append( "%d %s" % ( qs.count(), str( fld.model._meta.verbose_name_plural))) if len(parts) != 0: items.append(E.li(', '.join(parts), ' ', E.b(prefix))) collect_summary(_("will be deleted."), self.volatiles) collect_summary(_("will get reassigned."), self.related + self.generic_related) items.append(E.li(_("%s will be deleted") % self.obj)) msg = _("Are you sure you want to merge " "%(this)s into %(merge_to)s?") % dict( this=self.obj, merge_to=self.merge_to) if len(items) != 0: # return E.div(E.p(msg), E.ul(*items), class_="htmlText") return rt.html_text(E.div(E.p(msg), E.ul(*items))) return msg
def get_change_desc_html(self, f, old, new): from lino.core.choicelists import ChoiceListField if isinstance(f, models.TextField): old = old or '' new = new or '' return E.li( E.b(f.verbose_name), " : ", E.pre('\n'.join( difflib.unified_diff(old.splitlines(), new.splitlines(), fromfile="before", tofile="after", lineterm='')))) if isinstance(f, models.DateTimeField): return if isinstance(f, models.ForeignKey): if old: old = f.rel.to.objects.get(pk=old) if new: new = f.rel.to.objects.get(pk=new) elif isinstance(f, ChoiceListField): if isinstance(old, six.string_types): old = f.choicelist.get_by_value(old) if isinstance(new, six.string_types): new = f.choicelist.get_by_value(new) else: old = obj2str(old) new = obj2str(new) return E.li(E.b(f.verbose_name), " : ", u"{0} --> {1}".format(old, new))
def href_button(self, url, text, title=None, icon_name=None, **kw): """Returns an etree object of a ``<a href>`` tag to the given URL `url`. `url` is what goes into the `href` part. If `url` is `None`, then we return just a ``<b>`` tag. `text` is what goes between the ``<a>`` and the ``</a>``. This can be either a string or a tuple (or list) of strings (or etree elements). """ # logger.info('20121002 href_button %s', unicode(text)) if title: # Remember that Python 2.6 doesn't like if title is a Promise kw.update(title=str(title)) #~ return xghtml.E.a(text,href=url,title=title) if not isinstance(text, (tuple, list)): text = (text,) if url is None: return E.b(*text) kw.update(href=url) if icon_name is not None: src = settings.SITE.build_static_url( 'images', 'mjames', icon_name + '.png') img = E.img(src=src, alt=icon_name) return E.a(img, **kw) else: return E.a(*text, **kw)
def href_button(self, url, text, title=None, target=None, icon_name=None, **kw): """ Returns an etree object of a "button-like" ``<a href>`` tag. """ # logger.info('20121002 href_button %s', unicode(text)) if target: kw.update(target=target) if title: # Remember that Python 2.6 doesn't like if title is a Promise kw.update(title=unicode(title)) #~ return xghtml.E.a(text,href=url,title=title) if not isinstance(text, (tuple, list)): text = (text, ) if url is None: return E.b(*text) kw.update(href=url) if icon_name is not None: src = settings.SITE.build_static_url('images', 'mjames', icon_name + '.png') img = E.img(src=src, alt=icon_name) return E.a(img, **kw) else: return E.a(*text, **kw)
def server_status(cls, obj, ar): body = [] body.append( E.p( _("%s pending threads") % len(settings.SITE.kernel.pending_threads))) return E.div(*body, class_='htmlText')
def get_slave_summary(self, obj, ar): elems = [] sar = self.request(master_instance=obj) # elems += ["Partner:", unicode(ar.master_instance)] for voucher in sar: vc = voucher.get_mti_leaf() if vc and vc.state.name == "draft": elems += [ar.obj2html(vc), " "] vtypes = set() for m in rt.models_by_base(vat.VatDocument): vtypes.add( VoucherTypes.get_by_value(dd.full_model_name(m))) actions = [] def add_action(btn): if btn is None: return False actions.append(btn) return True for vt in vtypes: for jnl in vt.get_journals(): sar = ar.spawn( vt.table_class, master_instance=jnl, known_values=dict(partner=obj)) if add_action(sar.insert_button(unicode(jnl), icon_name=None)): actions.append(' ') elems += [E.br(), _("Create voucher in journal ")] + actions return E.div(*elems)
def build_confirmation_message(self): self.analyze() items = [] def collect_summary(prefix, fk_qs): parts = [] for fld, qs in fk_qs: if qs.count() > 0: parts.append( "%d %s" % (qs.count(), str(fld.model._meta.verbose_name_plural))) if len(parts) != 0: items.append(E.li(', '.join(parts), ' ', E.b(prefix))) collect_summary(_("will be deleted."), self.volatiles) collect_summary(_("will get reassigned."), self.related + self.generic_related) items.append(E.li(_("%s will be deleted") % self.obj)) msg = _("Are you sure you want to merge " "%(this)s into %(merge_to)s?") % dict(this=self.obj, merge_to=self.merge_to) if len(items) != 0: # return E.div(E.p(msg), E.ul(*items), class_="htmlText") return rt.html_text(E.div(E.p(msg), E.ul(*items))) return msg
def get_name_elems(self, ar): elems = [self.get_salutation(nominative=True), E.br()] if self.title: elems += [self.title, ' '] elems += [self.first_name, ' ', E.b(self.last_name)] return elems
def to_rst(cls, ar, column_names=None, header_level=None, **kwargs): "Better name would be table2rst (analog to table2xhtml())" fields, headers, widths = ar.get_field_info(column_names) sums = [fld.zero for fld in fields] rows = [] recno = 0 for row in ar.sliced_data_iterator: recno += 1 rows.append([x for x in ar.row2text(fields, row, sums)]) has_sum = False for i in sums: if i: #~ print '20120914 zero?', repr(i) has_sum = True break if has_sum: rows.append([x for x in ar.sums2html(fields, sums)]) t = RstTable(headers, **kwargs) s = t.to_rst(rows) if header_level is not None: s = E.tostring(E.h2(ar.get_title())) + s return s
def word2html(cls, w): hfr = w.text if w.haspire: hfr = "*" + hfr if Verbe.is_of_this_type(w) and w.form is not None: pronom = PRONOMS[w.form] if pronom[-1] == 'e' and cls.starts_with_vowel(w): pronom = pronom[:-1] #~ return u"%s'<b>%s</b>" % (pronom,hfr) yield pronom yield "'" yield E.b(hfr) return #~ return u"%s <b>%s</b>" % (pronom,hfr) yield pronom yield " " yield E.b(hfr) return if w.type and w.gender: #~ return u"<b>%s</b> (%s%s.)" % (hfr,w.type.text,w.gender) yield E.b(hfr) yield " (%s%s.)" % (w.type.text, w.gender) return if w.type and w.type.text: #~ return u"<b>%s</b> (%s)" % (hfr,w.type.text) yield E.b(hfr) yield " (%s)" % w.type.text return #~ return u"<b>%s</b>" % hfr yield E.b(hfr)
def on_update(sender=None, watcher=None, request=None, **kw): """ Log a Change if there is a `change_watcher_spec`. """ master = get_master(watcher.watched) if master is None: # No master, nothing to log return cs = watcher.watched.change_watcher_spec if False: # html version changes = list(watcher.get_updates_html(cs.ignored_fields)) if len(changes) == 0: msg = '(no changes)' elif len(changes) == 1: msg = E.tostring(changes[0]) else: msg = E.tostring(E.ul(*changes)) else: changes = [] for k, old, new in watcher.get_updates(cs.ignored_fields): 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)
def get_notify_message(self, ar, cw): """Returns the text of the notification message to emit. The default implementation returns a message of style "{object} has been modified by {user}" followed by a summary of the changes. Application code can override this. Returning None or an empty string means to suppress notification. """ if cw is None: return items = list(cw.get_updates_html()) if len(items) == 0: return elems = [E.p( ar.obj2html(self), ' ', _("has been modified by {user}").format( user=ar.get_user()), ":")] elems.append(E.ul(*items)) if False: elems.append(E.p(_( "Subsequent changes to {obj} will not be notified " "until you visit {url} and mark this notification " "as seen.").format( url=settings.SITE.server_url or "Lino", obj=self.get_notify_owner(ar)))) return E.tostring(E.div(*elems))
def welcome_html(self, ui=None): """ Return a HTML version of the "This is APPLICATION version VERSION using ..." text. to be displayed in the About dialog, in the plain html footer, and maybe at other places. """ from django.utils.translation import ugettext as _ p = [] sep = '' if self.verbose_name: p.append(_("This is ")) if self.url: p.append( E.a(self.verbose_name, href=self.url, target='_blank')) else: p.append(E.b(self.verbose_name)) if self.version: p.append(' ') p.append(self.version) sep = _(' using ') for name, version, url in self.get_used_libs(html=E): p.append(sep) p.append(E.a(name, href=url, target='_blank')) p.append(' ') p.append(version) sep = ', ' return E.span(*p)
def get_slave_summary(self, obj, ar): """Displays a summary of all responses for a given partner using a bullet list grouped by poll. """ if obj is None: return visible_polls = Poll.objects.filter(state__in=(PollStates.published, PollStates.closed)).order_by("ref") qs = Response.objects.filter(partner=obj).order_by("date") polls_responses = {} for resp in qs: polls_responses.setdefault(resp.poll.pk, []).append(resp) items = [] for poll in visible_polls: iar = self.insert_action.request_from(ar, obj, known_values=dict(poll=poll)) elems = [unicode(poll), " : "] responses = polls_responses.get(poll.pk, []) elems += join_elems([ar.obj2html(r, dd.fds(r.date)) for r in responses], sep=", ") if poll.state == PollStates.published: elems += [" ", iar.ar2button()] # elems += [' ', iar.insert_button()] items.append(E.li(*elems)) return E.div(E.ul(*items))
def get_slave_summary(self, response, ar): """Presents this response as a table with one row per question and one column for each response of the same poll. The answers for this response are editable if this response is not registered. The answers of other responses are never editable. """ if response is None: return if response.poll_id is None: return AnswerRemarks = rt.modules.polls.AnswerRemarksByAnswer all_responses = rt.modules.polls.Response.objects.filter(poll=response.poll).order_by("date") if response.partner: all_responses = all_responses.filter(partner=response.partner) ht = xghtml.Table() ht.attrib.update(cellspacing="5px", bgcolor="#ffffff", width="100%") cellattrs = dict(align="left", valign="top", bgcolor="#eeeeee") headers = [_("Question")] for r in all_responses: if r == response: headers.append(dd.fds(r.date)) else: headers.append(ar.obj2html(r, dd.fds(r.date))) ht.add_header_row(*headers, **cellattrs) ar.master_instance = response # must set it because # get_data_rows() needs it. editable = Responses.update_action.request_from(ar).get_permission(response) kv = dict(response=response) insert = AnswerRemarks.insert_action.request_from(ar, known_values=kv) detail = AnswerRemarks.detail_action.request_from(ar) # editable = insert.get_permission(response) for answer in self.get_data_rows(ar): cells = [self.question.value_from_object(answer, ar)] for r in all_responses: if editable and r == response: insert.known_values.update(question=answer.question) detail.known_values.update(question=answer.question) items = [self.answer_buttons.value_from_object(answer, ar)] if answer.remark.remark: items += [E.br(), answer.remark.remark] if answer.remark.pk: items += [" ", detail.ar2button(answer.remark, _("Remark"), icon_name=None)] # ar.obj2html(answer.remark, _("Remark"))] else: btn = insert.ar2button(answer.remark, _("Remark"), icon_name=None) # sar = RemarksByAnswer.request_from(ar, answer) # btn = sar.insert_button(_("Remark"), icon_name=None) items += [" (", btn, ")"] else: other_answer = AnswersByResponseRow(r, answer.question) items = [unicode(other_answer)] if other_answer.remark.remark: items += [E.br(), answer.remark.remark] cells.append(E.p(*items)) ht.add_body_row(*cells, **cellattrs) return E.div(ht.as_element(), class_="htmlText")
def get_poll_result(self): #~ yield E.h1(self.title) for cs in ChoiceSet.objects.all(): questions = self.questions.filter(choiceset=cs) if questions.count() > 0: yield E.h2(unicode(cs)) for question in questions: yield E.p(question.text)
def table2xhtml(self, header_level=None, **kw): t = xghtml.Table() self.dump2html(t, self.sliced_data_iterator, **kw) e = t.as_element() if header_level is not None: # return E.div(E.h2(self.get_title()), e) return E.div(E.h2(self.actor.label), e) return e
def get_poll_result(self): # ~ yield E.h1(self.title) for cs in ChoiceSet.objects.all(): questions = self.questions.filter(choiceset=cs) if questions.count() > 0: yield E.h2(unicode(cs)) for question in questions: yield E.p(question.text)
def what(self, obj, ar): chunks = [] if obj.name: chunks += [E.b(str(obj)), E.br()] chunks += sepjoin(obj.features.all()) #~ if obj.url: #~ chunks += [E.br(),E.a(_("More"),href=obj.url)] return E.p(*chunks)
def what(self, obj, ar): chunks = [] if obj.name: chunks += [E.b(unicode(obj)), E.br()] chunks += sepjoin(obj.features.all()) #~ if obj.url: #~ chunks += [E.br(),E.a(_("More"),href=obj.url)] return E.p(*chunks)
def ar2workbook(ar, column_names=None): from openpyxl import Workbook from openpyxl.styles import Font # local import to avoid the following traceback: # Error in sys.exitfunc: # Traceback (most recent call last): # File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs # func(*targs, **kargs) # File "/openpyxl/writer/write_only.py", line 38, in _openpyxl_shutdown # for path in ALL_TEMP_FILES: # TypeError: 'NoneType' object is not iterable # workbook = Workbook(guess_types=True) # removed `guess_types=True` because it caused trouble in openpyxl # 3.4.0 and because I don't know whether it is needed. workbook = Workbook() sheet = workbook.active sheet.title = sheet_name(ar.get_title()) bold_font = Font( name='Calibri', size=11, bold=True, ) fields, headers, widths = ar.get_field_info(column_names) for c, column in enumerate(fields): sheet.cell(row=1, column=c + 1).value = str(headers[c]) sheet.cell(row=1, column=c + 1).font = bold_font # sheet.col(c).width = min(256 * widths[c] / 7, 65535) # 256 == 1 character width, max width=65535 for c, column in enumerate(fields): for r, row in enumerate(ar.data_iterator, start=1): sf = column.field._lino_atomizer value = sf.full_value_from_object(row, ar) if type(value) == bool: value = value and 1 or 0 elif isinstance(value, (Duration, Choice)): value = str(value) elif E.iselement(value): value = E.to_rst(value) # dd.logger.info("20160716 %s", value) elif isinstance(value, Promise): value = str(value) elif isinstance(value, IncompleteDate): if value.is_complete(): value = value.as_date() else: value = str(value) elif isinstance(value, Model): value = str(value) sheet.cell(row=r + 1, column=c + 1).value = value return workbook
def obj2html(self, ar, obj, text=None, **kwargs): if text is None: text = (force_unicode(obj), ) elif isinstance(text, basestring): text = (text, ) url = self.instance_handler(ar, obj) if url is not None: return E.a(*text, href=url, **kwargs) return E.em(*text)
def obj2html(self, ar, obj, text=None, **kwargs): if text is None: text = (force_unicode(obj),) elif isinstance(text, basestring): text = (text,) url = self.instance_handler(ar, obj) if url is not None: return E.a(*text, href=url, **kwargs) return E.em(*text)
def job_desc(self, obj, ar): chunks = [ar.obj2html(obj, unicode(obj.function))] chunks.append(pgettext("(place)", " at ")) chunks.append(ar.obj2html(obj.provider)) chunks.append(" (%d)" % obj.capacity) if obj.remark: chunks.append(" ") chunks.append(E.i(obj.remark)) return E.p(*chunks)
def as_list_item(self, ar): if settings.SITE.is_demo_site: p = "'{0}', '{1}'".format(self.username, '1234') else: p = "'{0}'".format(self.username) url = "javascript:Lino.show_login_window(null, {0})".format(p) return E.li(E.a(self.username, href=url), ' : ', str(self), ', ', str(self.profile), ', ', E.strong(settings.SITE.LANGUAGE_DICT.get(self.language)))
def collect_summary(prefix, fk_qs): parts = [] for fld, qs in fk_qs: if qs.count() > 0: parts.append( "%d %s" % (qs.count(), str(fld.model._meta.verbose_name_plural))) if len(parts) != 0: items.append(E.li(', '.join(parts), ' ', E.b(prefix)))
def get_slave_summary(self, obj, ar): sar = self.request(master_instance=obj) links = [] for lnk in sar: if lnk.child.id == obj.id: i = (lnk.type.as_child(obj), lnk.parent) else: i = (lnk.type.as_parent(obj), lnk.child) links.append(i) def by_age(a, b): return cmp(b[1].birth_date.as_date(), a[1].birth_date.as_date()) try: links.sort(by_age) except AttributeError: # 'str' object has no attribute 'as_date' # possible when incomplete or empty birth_date pass items = [] for type, other in links: items.append(E.li( unicode(type), _(" of "), obj.format_family_member(ar, other), " (%s)" % other.age() )) elems = [] if len(items) > 0: elems += [_("%s is") % obj.first_name] elems.append(E.ul(*items)) else: elems.append(_("No relationships.")) actions = [] def add_action(btn): if btn is None: return False actions.append(btn) return True for lt in addable_link_types: sar = ar.spawn(Links, known_values=dict(type=lt, parent=obj)) if add_action(sar.insert_button( lt.as_parent(obj), icon_name=None)): if not lt.symmetric: actions.append('/') sar = ar.spawn( Links, known_values=dict(type=lt, child=obj)) add_action(sar.insert_button( lt.as_child(obj), icon_name=None)) actions.append(' ') elems += [E.br(), _("Create relationship as ")] + actions return E.div(*elems)
def f(obj, ar): if obj is None or ar is None: return E.div() try: utype = UploadType.objects.get(shortcut=i) except UploadType.DoesNotExist: return E.div() items = [] target = sender.modules.resolve(i.target) sar = ar.spawn_request(actor=target, master_instance=obj, known_values=dict(type=utype)) # param_values=dict(pupload_type=et)) n = sar.get_total_count() if n == 0: iar = target.insert_action.request_from(sar, master_instance=obj) btn = iar.ar2button( None, _("Upload"), icon_name="page_add", title=_("Upload a file from your PC to the server.")) items.append(btn) elif n == 1: after_show = ar.get_status() obj = sar.data_iterator[0] items.append( sar.renderer.href_button(dd.build_media_url(obj.file.name), _("show"), target='_blank', icon_name='page_go', style="vertical-align:-30%;", title=_( "Open the uploaded file in a " "new browser window"))) after_show.update(record_id=obj.pk) items.append( sar.window_action_button( sar.ah.actor.detail_action, after_show, _("Edit"), icon_name='application_form', title=_("Edit metadata of the uploaded file."))) else: obj = sar.sliced_data_iterator[0] items.append( ar.obj2html(obj, pgettext("uploaded file", "Last"))) btn = sar.renderer.action_button(obj, sar, sar.bound_action, _("All {0} files").format(n), icon_name=None) items.append(btn) return E.div(*join_elems(items, ', '))
def obj2html(self, ar, obj, text=None): if text is None: text = (force_unicode(obj),) elif isinstance(text, basestring): text = (text,) if self.is_interactive: url = self.instance_handler(ar, obj) if url is not None: return E.a(*text, href=url) return E.b(*text)
def table2html(ar, as_main=True): """This is not a docstring.""" as_main = True t = xghtml.Table() t.attrib.update(class_="table table-striped table-hover") if ar.limit is None: ar.limit = PLAIN_PAGE_LENGTH pglen = ar.limit if ar.offset is None: page = 1 else: """ (assuming pglen is 5) offset page 0 1 5 2 """ page = int(ar.offset / pglen) + 1 ar.dump2html(t, ar.sliced_data_iterator) if not as_main: url = ar.get_request_url() # open in own window return E.div(E.a(ar.get_title(), href=url), t.as_element()) buttons = [] kw = dict() kw = {} if pglen != PLAIN_PAGE_LENGTH: kw[constants.URL_PARAM_LIMIT] = pglen if page > 1: kw[constants.URL_PARAM_START] = pglen * (page - 2) prev_url = ar.get_request_url(**kw) kw[constants.URL_PARAM_START] = 0 first_url = ar.get_request_url(**kw) else: prev_url = None first_url = None buttons.append(('<<', _("First page"), first_url)) buttons.append(('<', _("Previous page"), prev_url)) next_start = pglen * page if next_start < ar.get_total_count(): kw[constants.URL_PARAM_START] = next_start next_url = ar.get_request_url(**kw) last_page = int((ar.get_total_count() - 1) / pglen) kw[constants.URL_PARAM_START] = pglen * last_page last_url = ar.get_request_url(**kw) else: next_url = None last_url = None buttons.append(('>', _("Next page"), next_url)) buttons.append(('>>', _("Last page"), last_url)) return E.div(buttons2pager(buttons), t.as_element())
def table2xhtml(self, header_level=None, **kw): """ Return an HTML representation of this table request. """ t = xghtml.Table() self.dump2html(t, self.sliced_data_iterator, **kw) e = t.as_element() # print "20150822 table2xhtml", E.tostring(e) if header_level is not None: return E.div(E.h2(self.actor.label), e) return e
def remote_html(self, ar): elems = [] elems += [self.remote_account, " "] elems += ["(BIC:", self.remote_bic, ")"] elems.append(E.br()) elems += [E.b(self.remote_owner), ", "] elems.append(E.br()) elems += [" / ".join(self.remote_owner_address.splitlines()), ", "] elems += [self.remote_owner_postalcode, " "] elems += [self.remote_owner_city, " "] elems += [self.remote_owner_country_code] return E.div(*elems)
def get_story(cls, self, ar): """Yield a sequence of story items. These can be (1) ElementTree elements or (2) AbstractTable or (3) action requests. """ if cls.report_items is None: raise Exception("{0} has no report_items".format(cls)) for A in cls.report_items: yield E.h2(unicode(A.label)) if A.help_text: yield E.p(unicode(A.help_text)) yield A
def question(self, obj, ar): if obj.question.number: txt = obj.question.NUMBERED_TITLE_FORMAT % (obj.question.number, obj.question.title) else: txt = obj.question.title attrs = dict(class_="htmlText") if obj.question.details: attrs.update(title=obj.question.details) if obj.question.is_heading: txt = E.b(txt, **attrs) return E.span(txt, **attrs)
def obj2html(self, ar, obj, text=None, **kwargs): """Return a html representation of a pointer to the given database object. """ if text is None: text = (force_text(obj),) elif isinstance(text, six.string_types) or E.iselement(text): text = (text,) url = self.obj2url(ar, obj) if url is None: return E.em(*text) return self.href_button(url, text, **kwargs)
def about_html(cls): body = [] body.append(settings.SITE.welcome_html()) if settings.SITE.languages: body.append(E.p(str(_("Languages")) + ": " + ', '.join([ lng.django_code for lng in settings.SITE.languages]))) # print "20121112 startup_time", settings.SITE.startup_time.date() def dtfmt(dt): if isinstance(dt, float): dt = datetime.datetime.fromtimestamp(dt) # raise ValueError("Expected float, go %r" % dt) return str(_("%(date)s at %(time)s")) % dict( date=dd.fds(dt.date()), time=settings.SITE.strftime(dt.time())) value = settings.SITE.startup_time label = _("Server uptime") body.append(E.p( str(label), ' : ', E.b(dtfmt(value)), ' ({})'.format(settings.TIME_ZONE))) if settings.SITE.is_demo_site: s = str(_("This is a Lino demo site.")) body.append(E.p(s)) if settings.SITE.the_demo_date: s = _("We are running with simulated date set to {0}.").format( dd.fdf(settings.SITE.the_demo_date)) body.append(E.p(s)) body.append(E.p(str(_("Source timestamps:")))) items = [] times = [] packages = set(['lino', 'django', 'atelier']) for p in settings.SITE.installed_plugins: packages.add(p.app_name.split('.')[0]) for src in packages: label = src value = codetime('%s.*' % src) if value is not None: times.append((label, value)) times.sort(key=lambda x: x[1]) for label, value in times: items.append(E.li(str(label), ' : ', E.b(dtfmt(value)))) body.append(E.ul(*items)) # return E.div(*body, class_='htmlText') return rt.html_text(E.div(*body))
def present_word2html(cls, w, book): """ Format word for "presentation" (usually the first column in a table of new words). """ hfr = w.text if w.haspire: hfr = "*" + hfr if Nom.is_of_this_type(w): if w.gender == 'pl': #~ return u"les <b>%s</b> (%s)" % (hfr,w.gender) yield "les " yield E.b(hfr) return #~ if w.defini and (w.text[0].lower() in u'aeiouyàéœ' or (w.text[0].lower() == 'h' and not w.haspire)): if w.defini and cls.starts_with_vowel(w): #~ return u"l'<b>%s</b> (%s)" % (hfr,w.gender) yield "l'" yield E.b(hfr) yield " (%s)" % w.gender return #~ art = w.get_article() #~ def get_article(self): if w.defini: articles = ['le', 'la'] else: articles = ['un', 'une'] if w.gender == 'm': #~ return u"%s <b>%s</b>" % (articles[0],hfr) yield articles[0] yield ' ' yield E.b(hfr) return if w.gender == 'f': #~ return u"%s <b>%s</b>" % (articles[1],hfr) yield articles[1] yield ' ' yield E.b(hfr) return #~ return u"%s <b>%s</b>" % (articles[0],hfr) #~ raise Exception("Unknown gender for Nom %s" % w) yield articles[0] yield ' ' yield E.b(hfr) return for e in cls.word2html(w): yield e
def body_subject_to_elems(ar, title, description): """Convert the given `title` and `description` to a list of HTML elements. Used by :mod:`lino.modlib.notify` and by :mod:`lino_cosi.lib.sales` """ if description: elems = [E.p(E.b(title), E.br())] elems += rich_text_to_elems(ar, description) else: elems = [E.b(title)] # return E.span(self.title) return elems
def http_response(ar, tplname, context): "Deserves a docstring" u = ar.get_user() lang = get_language() k = (u.profile, lang) menu = MENUS.get(k, None) if menu is None: menu = settings.SITE.get_site_menu(None, u.profile) 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 = E.tostring(e) MENUS[k] = menu context.update(menu=menu) context = ar.get_printable_context(**context) context['ar'] = ar context['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 fmt(obj): s = E.tostring(ar.action_button(ba, obj)) s += fds(obj.created) + " " + obj.created.strftime( settings.SITE.time_format_strftime) + " " s += ar.parse_memo(obj.body) # s += obj.body return "<li>{}</li>".format(s)