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 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 about_html(cls): body = [] body.append(settings.SITE.welcome_html()) #~ 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 unicode(_("%(date)s at %(time)s")) % dict( date=dd.fdf(dt.date()), time=dt.time()) items = [] times = [] value = settings.SITE.startup_time label = _("Server uptime") body.append(E.p(unicode(label), ' : ', E.b(dtfmt(value)))) body.append(E.p(unicode(_("Source timestamps:")))) for src in ("lino", "lino_welfare", 'django', 'atelier'): label = src value = codetime('%s.*' % src) if value is not None: times.append((label, value)) def mycmp(a, b): return cmp(b[1], a[1]) times.sort(mycmp) for label, value in times: items.append(E.li(unicode(label), ' : ', E.b(dtfmt(value)))) body.append(E.ul(*items)) return E.div(*body, class_='htmlText')
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 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 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_report(ar, today=None, weeksback=1, weeksforth=0, datefmt=dd.fds): if not ar.user.profile.has_required_roles([SiteUser]): return E.p() if today is None: today = dd.today() start_date = today - ONE_DAY * today.weekday() - weeksback * SEVEN_DAYS numweeks = weeksback + weeksforth + 1 days = dict() cd = start_date numdays = numweeks * 7 for i in range(numdays): days[cd] = [] cd += ONE_DAY end_date = cd for r in REPORTERS: r(days, ar, start_date, end_date) headers = [E.th(Weekdays.choices[i][1], **ar.cellattrs) for i in range(7)] rows = [E.tr(*headers)] cd = start_date for week in range(numweeks): week = [] for weekday in range(7): chunks = days[cd] chunks.insert(0, datefmt(cd)) week.append(E.td(*chunks, **ar.cellattrs)) cd += ONE_DAY rows.append(E.tr(*week)) # print 20150420, rows return E.table(*rows, **ar.tableattrs)
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 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, 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 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 partners(self, ar): if ar is None: return '' elems = [] qs = rt.modules.sepa.Account.objects.filter(iban=self.iban) for obj in qs: elems.append(ar.obj2html(obj.partner)) return E.p(*join_elems(elems, ', '))
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 get_overview_elems(self, ar): elems = super(AddressOwner, self).get_overview_elems(ar) sar = ar.spawn('addresses.AddressesByPartner', master_instance=self) # btn = sar.as_button(_("Manage addresses"), icon_name="wrench") btn = sar.as_button(_("Manage addresses")) # elems.append(E.p(btn, align="right")) elems.append(E.p(btn)) return elems
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 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 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 quick_links(cls, self, ar): quicklinks = settings.SITE.get_quicklinks(ar) if quicklinks.items: chunks = [] for mi in quicklinks.items: chunks.append(' ') chunks.append(ar.window_action_button(mi.bound_action)) return E.p('Quick Links:', *chunks)
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.fdf(dt.date()), time=dt.time()) items = [] times = [] value = settings.SITE.startup_time label = _("Server uptime") body.append(E.p(str(label), ' : ', E.b(dtfmt(value)))) 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:")))) for src in ("lino", "lino_welfare", 'django', 'atelier'): label = src value = codetime('%s.*' % src) if value is not None: times.append((label, value)) def mycmp(a, b): return cmp(b[1], a[1]) times.sort(mycmp) 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')
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 pupil_info(self, ar): if ar is None: return '' elems = [ ar.obj2html(self.pupil, self.pupil.get_full_name(nominative=True)) ] elems += [', '] elems += join_elems(list(self.pupil.address_location_lines()), sep=', ') return E.p(*elems)
def pupil_info(self, ar): if ar is None: return '' elems = [ar.obj2html(self.pupil, self.pupil.get_full_name(nominative=True))] elems += [', '] elems += join_elems( list(self.pupil.address_location_lines()), sep=', ') return E.p(*elems)
def get_slave_summary(self, obj, ar): chunks = [] for other in ar.spawn(self, master_instance=obj): chunks.append(ar.obj2html(other)) if len(chunks): s = getattr(obj, obj.dupable_words_field) words = ', '.join(obj.get_dupable_words(s)) chunks.append(_("Phonetic words: {0}").format(words)) return E.p(*join_elems(chunks)) return ''
def get(self, request, app_label=None, actor=None, pk=None): ar = action_request(app_label, actor, request, request.GET, False) ar.renderer = dd.plugins.bootstrap3.renderer navigator = None if pk and pk != '-99999' and pk != '-99998': elem = ar.get_row_by_pk(pk) if elem is None: raise http.Http404("%s has no row with primary key %r" % (ar.actor, pk)) #~ raise Exception("20120327 %s.get_row_by_pk(%r)" % (rpt,pk)) if ar.actor.show_detail_navigator: ni = navinfo(ar.data_iterator, elem) if ni: # m = elem.__class__ buttons = [] #~ buttons.append( ('*',_("Home"), '/' )) buttons.append( ('<<', _("First page"), ar.pk2url(ni['first']))) buttons.append( ('<', _("Previous page"), ar.pk2url(ni['prev']))) buttons.append( ('>', _("Next page"), ar.pk2url(ni['next']))) buttons.append( ('>>', _("Last page"), ar.pk2url(ni['last']))) navigator = buttons2pager(buttons) else: navigator = E.p("No navinfo") else: elem = None main = layout2html(ar, elem) # The `method="html"` argument isn't available in Python 2.6, # only 2.7. It is useful to avoid side effects in case of # empty elements: the default method (xml) writes an empty # E.div() as "<div/>" while in HTML5 it must be "<div></div>" # (and the ending / is ignored). #~ return E.tostring(main, method="html") #~ return E.tostring(main) # return main context = dict( title=ar.get_action_title(), obj=elem, form=main, navigator=navigator, ) #~ template = web.jinja_env.get_template('detail.html') context.update(ar=ar) return http_response(ar, ar.actor.detail_html_template, context)
def UL(items): # ~ return E.ul(*[E.li(i) for i in items]) newitems = [] first = True for i in items: if first: first = False else: newitems.append(E.br()) newitems.append(i) return E.p(*newitems)
def answer_buttons(self,obj,ar): l = [] if obj.question.get_multiple_choices(): l.append("MC not yet implemented") else: kw = dict(title=_("Select this value")) for c in obj.question.get_choiceset().choices.all(): l.append(unicode(c)) #~ l.append(ar.put_button(obj.question,unicode(c),dict(choice=c),**kw)) #~ l.append(self.select_choice.as_button_elem(ar.request,unicode(c))) return E.p(*join_elems(l))
def get_slave_summary(self, obj, ar): """Displays the uploads related to this controller as a list grouped by uploads type. Note that this also works on :class:`lino_welfare.modlib.uploads.models.UploadsByClient` and their subclasses for the different `_upload_area`. """ UploadType = rt.modules.uploads.UploadType # Upload = rt.modules.uploads.Upload elems = [] types = [] for ut in UploadType.objects.filter( upload_area=self._upload_area): sar = ar.spawn( self, master_instance=obj, known_values=dict(type_id=ut.id)) # logger.info("20140430 %s", sar.data_iterator.query) files = [] for m in sar: text = self.format_row_in_slave_summary(ar, m) if text is None: continue edit = ar.obj2html( m, text, # _("Edit"), # icon_name='application_form', title=_("Edit metadata of the uploaded file.")) if m.file.name: show = ar.renderer.href_button( settings.SITE.build_media_url(m.file.name), _(" [show]"), # fmt(m), target='_blank', icon_name='../xsite/link', # icon_name='page_go', # style="vertical-align:-30%;", title=_("Open the uploaded file in a new browser window")) # logger.info("20140430 %s", E.tostring(e)) files.append(E.span(edit, ' ', show)) else: files.append(edit) if ut.wanted and ( ut.max_number < 0 or len(files) < ut.max_number): files.append(sar.insert_button()) if len(files) > 0: e = E.p(unicode(ut), ': ', *join_elems(files, ', ')) types.append(e) # logger.info("20140430 %s", [E.tostring(e) for e in types]) if len(types) == 0: elems.append(E.ul(E.li(ar.no_data_text))) else: elems.append(E.ul(*[E.li(e) for e in types])) return E.div(*elems)
def get(self, request, app_label=None, actor=None, pk=None): ar = action_request(app_label, actor, request, request.GET, False) ar.renderer = dd.plugins.bootstrap3.renderer navigator = None if pk and pk != '-99999' and pk != '-99998': elem = ar.get_row_by_pk(pk) if elem is None: raise http.Http404("%s has no row with primary key %r" % (ar.actor, pk)) #~ raise Exception("20120327 %s.get_row_by_pk(%r)" % (rpt,pk)) if ar.actor.show_detail_navigator: ni = navinfo(ar.data_iterator, elem) if ni: buttons = [] #~ buttons.append( ('*',_("Home"), '/' )) buttons.append( ('<<', _("First page"), ar.pk2url(ni['first']))) buttons.append( ('<', _("Previous page"), ar.pk2url(ni['prev']))) buttons.append( ('>', _("Next page"), ar.pk2url(ni['next']))) buttons.append( ('>>', _("Last page"), ar.pk2url(ni['last']))) navigator = buttons2pager(buttons) else: navigator = E.p("No navinfo") else: elem = None main = layout2html(ar, elem) # The `method="html"` argument isn't available in Python 2.6, # only 2.7. It is useful to avoid side effects in case of # empty elements: the default method (xml) writes an empty # E.div() as "<div/>" while in HTML5 it must be "<div></div>" # (and the ending / is ignored). #~ return E.tostring(main, method="html") #~ return E.tostring(main) # return main context = dict( title=ar.get_action_title(), obj=elem, form=main, navigator=navigator, ) #~ template = web.jinja_env.get_template('detail.html') context.update(ar=ar) return http_response(ar, ar.actor.detail_html_template, context)
def move_buttons(obj, ar): if ar is None: return '' actor = ar.actor l = [] state = None # TODO: support a possible state? for n in obj.move_action_names: ba = actor.get_action_by_name(n) if ba.get_row_permission(ar, obj, state): l.append(ar.renderer.action_button(obj, ar, ba)) l.append(' ') return E.p(*l)
def move_buttons(obj, ar): if ar is None: return '' actor = ar.actor l = [] state = None # TODO: support a possible state? for n in ('move_up', 'move_down', 'duplicate'): ba = actor.get_action_by_name(n) if ba.get_row_permission(ar, obj, state): l.append(ar.renderer.action_button(obj, ar, ba)) l.append(' ') return E.p(*l)
def move_buttons(obj, ar): """ Displays the buttons for this row and this user. """ actor = ar.actor l = [] state = None # TODO: support a possible state? for n in ('move_up', 'move_down'): ba = actor.get_action_by_name(n) if ba.get_bound_action_permission(ar, obj, state): l.append(ar.renderer.action_button(obj, ar, ba)) l.append(' ') return E.p(*l)
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(str(A.label)) if A.help_text: yield E.p(str(A.help_text)) yield A
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 welcome(cls, self, ar): #~ MAXITEMS = 2 u = ar.get_user() story = [] if u.profile.authenticated: intro = [_("Hi, %(user)s!") % dict(user=u.first_name)] story.append(E.p(*intro)) warnings = [] #~ for T in (MySuggestedCoachings,cal.MyTasksToDo): for table, text in settings.SITE.get_todo_tables(ar): if table.get_view_permission(u.profile): r = table.request(user=u) #~ r = T.request(subst_user=u) #~ r = ar.spawn(T) if r.get_total_count() != 0: warnings.append(E.li( ar.href_to_request(r, text % r.get_total_count()))) #~ _("You have %d entries in ") % r.get_total_count(), #~ ar.href_to_request(r,label))) #~ warnings.append(E.li("Test 1")) #~ warnings.append(E.li("Second test")) if len(warnings): #~ story.append(E.h3(_("Warnings"))) story.append(E.h3(_("You have"))) story.append(E.ul(*warnings)) else: story.append( E.p(_("Congratulatons: you have no warnings."))) #~ else: # story.append(E.p("Please log in")) #~ story.append(settings.SITE.get_guest_greeting()) return E.div(*story, class_="htmlText", style="margin:5px")
def get_slave_summary(self, obj, ar): if ar is None: return '' elems = [] # Active sessions: active_sessions = [] qs = rt.modules.clocking.Session.objects.filter(ticket=obj) tot = Duration() for ses in qs: d = ses.get_duration() if d is not None: tot += d if ses.end_time is None: txt = "{0} since {1}".format(ses.user, ses.start_time) lnk = ar.obj2html(ses, txt) sar = ses.end_session.request_from(ar) if sar.get_permission(): lnk = E.span(lnk, " ", sar.ar2button(ses)) active_sessions.append(lnk) # elems.append(E.p(_("Total {0} hours.").format(tot))) elems.append(E.p(_("Total %s hours.") % tot)) if len(active_sessions) > 0: elems.append(E.p( ensureUtf(_("Active sessions")), ": ", *join_elems(active_sessions, ', '))) # Button for starting a session from ticket sar = obj.start_session.request_from(ar) # if ar.renderer.is_interactive and sar.get_permission(): if sar.get_permission(): btn = sar.ar2button(obj) elems += [E.p(btn)] return E.div(*elems)
def get_overview_elems(self, ar): if ar is None: return [] elems = super(Client, self).get_overview_elems(ar) # elems.append(E.br()) elems.append(ar.get_data_value(self, 'eid_info')) notes = [] for note in rt.modules.notes.Note.objects.filter( project=self, important=True): notes.append(E.b(ar.obj2html(note, note.subject))) if len(notes): notes = join_elems(notes, " / ") elems += E.p(*notes, class_="lino-info-red") return elems
def description(cls, self, ar): if ar is None: return '' elems = [] elems.append(ar.obj2html(self.account)) voucher = self.voucher.get_mti_leaf() if voucher.narration: elems.append(voucher.narration) p = voucher.get_partner() if p is not None: elems.append(ar.obj2html(p)) if self.partner and self.partner != p: elems.append(ar.obj2html(self.partner)) return E.p(*join_elems(elems, " / "))
def description(cls, self, ar): if ar is None: return '' elems = [] elems.append(ar.obj2html(self.account)) if self.voucher.narration: elems.append(self.voucher.narration) voucher = self.voucher.get_mti_leaf() p = voucher.get_partner() if p is not None and p != ar.master_instance: elems.append(ar.obj2html(p)) if self.project: elems.append(ar.obj2html(self.project)) return E.p(*join_elems(elems, " / "))
def get_overview_elems(self, ar): elems = [] buttons = self.get_mti_buttons(ar) buttons = join_elems(buttons, ', ') elems.append(E.p(unicode(_("See as ")), *buttons, style="font-size:8px;text-align:right;padding:3pt;")) elems += self.get_name_elems(ar) elems.append(E.br()) elems += join_elems(list(self.address_location_lines()), sep=E.br) elems = [ E.div(*elems, style="font-size:18px;font-weigth:bold;" "vertical-align:bottom;text-align:middle")] return elems
def get_story(cls,self,ar): #~ yield E.h2(_("Introduction")) #~ yield E.p("Ceci est un ",E.b("rapport"),""", #~ càd un document complet généré par Lino, contenant des #~ sections, des tables et du texte libre. #~ Dans la version écran cliquer sur un chiffre pour voir d'où #~ il vient. #~ """) #~ yield E.h1(isip.Contract._meta.verbose_name_plural) for A in (GeneralAccountsBalance,ClientAccountsBalance,SupplierAccountsBalance): yield E.h2(A.label) if A.help_text: yield E.p(unicode(A.help_text)) yield A
def move_buttons(obj, ar): """ Displays the buttons for this row and this user. """ if ar is None: return '' actor = ar.actor l = [] state = None # TODO: support a possible state? for n in ('move_up', 'move_down'): ba = actor.get_action_by_name(n) if ba.get_bound_action_permission(ar, obj, state): l.append(ar.renderer.action_button(obj, ar, ba)) l.append(' ') return E.p(*l)
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 quick_add_buttons(self, ar): """Returns a HTML chunk that displays "quick add buttons" for the given :class:`action request <lino.core.dbtables.TableRequest>`: a button :guilabel:`[New]` followed possibly (if the request has rows) by a :guilabel:`[Show last]` and a :guilabel:`[Show all]` button. See also :srcref:`docs/tickets/56`. """ buttons = [] # btn = ar.insert_button(_("New")) # if btn is not None: sar = ar.actor.insert_action.request_from(ar) if sar.get_permission(): btn = sar.ar2button(None, _("New")) buttons.append(btn) buttons.append(' ') #~ after_show = ar.get_status() n = ar.get_total_count() #~ print 20120702, [o for o in ar] if n > 0: obj = ar.data_iterator[n - 1] st = ar.get_status() st.update(record_id=obj.pk) #~ a = ar.actor.get_url_action('detail_action') a = ar.actor.detail_action buttons.append( self.window_action_button( ar.request, a, st, _("Show Last"), icon_name='application_form', title=_("Show the last record in a detail window"))) buttons.append(' ') #~ s += ' ' + self.window_action_button( #~ ar.ah.actor.detail_action,after_show,_("Show Last")) #~ s += ' ' + self.href_to_request(ar,"[%s]" % unicode(_("Show All"))) buttons.append( self.href_to_request( None, ar, _("Show All"), icon_name='application_view_list', title=_("Show all records in a table window"))) #~ return '<p>%s</p>' % s return E.p(*buttons)
def get_overview_elems(self, ar): elems = [] buttons = self.get_mti_buttons(ar) # buttons = join_elems(buttons, ', ') elems.append( E.p(str(_("See as ")), *buttons, style="font-size:8px;text-align:right;padding:3pt;")) elems += self.get_name_elems(ar) elems.append(E.br()) elems += join_elems(list(self.address_location_lines()), sep=E.br) elems = [ E.div(*elems, style="font-size:18px;font-weigth:bold;" "vertical-align:bottom;text-align:middle") ] return elems
def qs2summary(ar, objects, separator=comma, max_items=5, **kw): """Render a collection of objects as a single paragraph. :param max_items: don't include more than the specified number of items. """ elems = [] n = 0 for i in objects: if n: elems.append(separator()) n += 1 elems += list(ar.summary_row(i, **kw)) if n >= max_items: elems += [separator(), '...'] break return E.p(*elems)
def show_menu(self, ar, mnu, level=1): """ Render the given menu as an HTML element. Used for writing test cases. """ if not isinstance(mnu, Menu): assert isinstance(mnu, MenuItem) if mnu.bound_action: sr = mnu.bound_action.actor.request( action=mnu.bound_action, user=ar.user, subst_user=ar.subst_user, requesting_panel=ar.requesting_panel, renderer=self, **mnu.params) url = sr.get_request_url() else: url = mnu.href assert mnu.label is not None if url is None: return E.p() # spacer return E.li(E.a(mnu.label, href=url, tabindex="-1")) items = [self.show_menu(ar, mi, level + 1) for mi in mnu.items] #~ print 20120901, items if level == 1: return E.ul(*items, class_='nav navbar-nav') if mnu.label is None: raise Exception("%s has no label" % mnu) if level == 2: cl = 'dropdown' menu_title = E.a(unicode(mnu.label), E.b(' ', class_="caret"), href="#", class_='dropdown-toggle', data_toggle="dropdown") elif level == 3: menu_title = E.a(unicode(mnu.label), href="#") cl = 'dropdown-submenu' else: raise Exception("Menu with more than three levels") return E.li(menu_title, E.ul(*items, class_='dropdown-menu'), class_=cl)
def get_slave_summary(self, obj, ar): """The :meth:`summary view <lino.core.actors.Actor.get_slave_summary>` for this table. """ sar = self.request_from(ar, master_instance=obj) html = [] items = [sar.obj2html(o) for o in sar] sar = self.insert_action.request_from(sar) if sar.get_permission(): btn = sar.ar2button() items.append(btn) if len(items) > 0: html += join_elems(items, sep=', ') return E.p(*html)
def base_classes(self, obj, ar): if obj is None: return "" chunks = [] def add(cl): for b in cl.__bases__: add(b) # : if issubclass(cl, dd.Model) and cl is not dd.Model \ and cl._meta.managed: if getattr(cl, '_meta', False) and not cl._meta.abstract: #~ logger.info("20120205 adding(%r)",cl) ct = ContentType.objects.get_for_model(cl) chunks.append(ar.obj2html(ct, str(cl._meta.verbose_name))) #~ add(obj.model_class()) cl = obj.model_class() # e.g. if database is nor synchronized if cl is not None: for b in cl.__bases__: add(b) return E.p(*join_elems(chunks, sep=', '))
def where(self, obj, ar): if obj.place is not None: return E.p(str(obj.place), ' ', E.b(str(obj.place.city))) # remember: "von Ans nach Eupen und nicht andersrum" return E.p(*sepjoin(obj.stages.order_by('seqno'), ' -- '))
def children_summary(self, ar): if ar is None: return '' elems = [ar.obj2html(ch) for ch in self.children.all()] elems = join_elems(elems, sep=', ') return E.p(*elems)
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. # 20151211 # editable = Responses.update_action.request_from(ar).get_permission( # response) sar = Responses.update_action.request_from(ar) sar.selected_rows = [response] editable = sar.get_permission() 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 = [str(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 ar.html_text(ht.as_element())
def offered_by(self, ar): if ar is None: return '' items = [ar.obj2html(o) for o in self.suppliers.all()] items = join_elems(items, sep=', ') return E.p(*items)
def demanded_by(self, ar): if ar is None: return '' items = [ar.obj2html(o) for o in self.customers.all()] items = join_elems(items, sep=', ') return E.p(*items)