def test_format_datetime_with_format(): i18n.set_locale(i18n.Locale('en', 'US', timezone='America/Los_Angeles')) d = datetime.datetime(2007, 4, 1, 15, 30) assert i18n.format_datetime(d, format="yyyy.MM.dd G 'at' HH:mm:ss zzz") == "2007.04.01 AD at 16:30:00 PDT" d = datetime.datetime(2007, 4, 1, 15, 30, tzinfo=pytz.timezone('Europe/Paris')) assert i18n.format_datetime(d, format="yyyy.MM.dd G 'at' HH:mm:ss zzz") == "2007.04.01 AD at 08:21:00 PDT"
def test_format_datetime_with_format(self): i18n.set_locale(i18n.Locale('en', 'US', timezone='Pacific/Pitcairn')) d = datetime.datetime(2007, 4, 1, 15, 30) self.assertEqual(i18n.format_datetime(d, format="yyyy.MM.dd G 'at' HH:mm:ss zzz"), '2007.04.01 AD at 15:30:00 -0800') tz = pytz.timezone('Africa/Niamey') d = tz.localize(datetime.datetime(2007, 4, 1, 15, 30)) self.assertEqual(i18n.format_datetime(d, format="yyyy.MM.dd G 'at' HH:mm:ss zzz"), '2007.04.01 AD at 06:30:00 -0800')
def test_format_datetime(): i18n.set_locale(i18n.Locale('fr', 'FR', timezone='Europe/Paris')) d = datetime.datetime(2007, 4, 1, 15, 30, tzinfo=pytz.timezone('America/Los_Angeles')) assert i18n.format_datetime(d, format='full') == 'lundi 2 avril 2007 01:30:00 HEC' assert i18n.format_datetime(d, format='long') == '2 avril 2007 01:30:00 HAEC' assert i18n.format_datetime(d, format='medium') == '2 avr. 2007 01:30:00' assert i18n.format_datetime(d) == '2 avr. 2007 01:30:00' assert i18n.format_datetime(d, format='short') == '02/04/07 01:30'
def test_format_datetime(self): i18n.set_locale(i18n.Locale('fr', 'FR', timezone='Africa/Niamey')) tz = pytz.timezone('Pacific/Pitcairn') d = tz.localize(datetime.datetime(2007, 4, 1, 15, 30)) self.assertEqual(i18n.format_datetime(d, format='full'), u'lundi 2 avril 2007 à 00:30:00 heure normale d’Afrique de l’Ouest') self.assertEqual(i18n.format_datetime(d, format='long'), u'2 avril 2007 à 00:30:00 +0100') self.assertEqual(i18n.format_datetime(d, format='medium'), u'2 avr. 2007 à 00:30:00') self.assertEqual(i18n.format_datetime(d), u'2 avr. 2007 à 00:30:00') self.assertEqual(i18n.format_datetime(d, format='short'), '02/04/2007 00:30')
def test_format_datetime_with_format(): i18n.set_locale(i18n.Locale('en', 'US', timezone='Pacific/Pitcairn')) d = datetime.datetime(2007, 4, 1, 15, 30) assert i18n.format_datetime(d, format="yyyy.MM.dd G 'at' HH:mm:ss zzz" ) == '2007.04.01 AD at 15:30:00 -0800' tz = pytz.timezone('Africa/Niamey') d = tz.localize(datetime.datetime(2007, 4, 1, 15, 30)) assert i18n.format_datetime(d, format="yyyy.MM.dd G 'at' HH:mm:ss zzz" ) == '2007.04.01 AD at 06:30:00 -0800'
def test_format_datetime(): i18n.set_locale(i18n.Locale('fr', 'FR', timezone='Africa/Niamey')) tz = pytz.timezone('Pacific/Pitcairn') d = tz.localize(datetime.datetime(2007, 4, 1, 15, 30)) assert i18n.format_datetime( d, format='full' ) == u'lundi 2 avril 2007 à 00:30:00 heure normale d’Afrique de l’Ouest' assert i18n.format_datetime( d, format='long') == u'2 avril 2007 à 00:30:00 +0100' assert i18n.format_datetime(d, format='medium') == u'2 avr. 2007 à 00:30:00' assert i18n.format_datetime(d) == u'2 avr. 2007 à 00:30:00' assert i18n.format_datetime(d, format='short') == '02/04/2007 00:30'
def render_comment(self, h, comp, model, *args): with h.div(class_='comment'): with h.div(class_='left'): h << self.author.render(h, model='avatar') with h.div(class_='right'): h << self.author.render(h, model='fullname') h << ' ' << _('wrote') << ' ' h << h.span(_(u'on'), ' ', format_datetime(self.creation_date), class_="date") if security.has_permissions('delete_comment', self): onclick = ( u"if (confirm(%(message)s)){%(action)s;}return false" % { 'action': h.a.action(comp.answer, comp).get('onclick'), 'message': ajax.py2js( _(u'Your comment will be deleted. Are you sure?')). decode('UTF-8') }) h << h.a(h.i(class_='icon-cross'), title=_('Delete'), class_="comment-delete", onclick=onclick, href='') h << self.comment_label.render(h.AsyncRenderer()) return h.root
def render_article_list_item(self, h, comp, *args): limit = 500 date = format_datetime(self.article.creation_date, format='short') if len(self.article.content) > limit: if self.display_full_description(): content = html(h, self.article.content) else: content = html(h, self.article.content, limit) display_more = True else: content = html(h, self.article.content) display_more = False with h.li: with h.h1: h << h.a(self.article.title, href=self.url) h << h.span(self.article.topic.label or '', class_='thematic') h << h.span(date, class_='date') with h.div: h << content if display_more and not self.display_full_description(): h << h.a(_(u'Read more'), class_='more').action( lambda: self.display_full_description(True)) elif display_more and self.display_full_description(): h << h.a(_(u'Read less'), class_='more').action( lambda: self.display_full_description(False)) return h.root
def render_idea_wf_comment_table_row(self, h, comp, *args): with h.td(class_='date'): h << format_datetime(self.data.submission_date, format='short') with h.td(class_='change'): h << _(self.data.from_state.label) h << h.div(u" ⬇ ") h << _(self.data.to_state.label) with h.td(class_='author'): # FIXME: we should use a specific "di" view to render the author name author = self.data.created_by di = self.data.idea_wf.assignated_di if author is not di or security.has_permissions('view_di', self): h << author.fullname else: h << _(u'Expert') with h.td(class_='comment'): if security.has_permissions('edit_comment', self): h << self.content_editor.render(h.AsyncRenderer()) else: h << self.data.content return h.root
def render_article_list_item(self, h, comp, *args): limit = 500 date = format_datetime(self.article.creation_date, format='short') if len(self.article.content) > limit: if self.display_full_description(): content = html(h, self.article.content) else: content = html(h, self.article.content, limit) display_more = True else: content = html(h, self.article.content) display_more = False with h.li: with h.h1: h << h.a(self.article.title, href=self.url) h << h.span(self.article.topic.label or '', class_='thematic') h << h.span(date, class_='date') with h.div: h << content if display_more and not self.display_full_description(): h << h.a(_(u'Read more'), class_='more').action(lambda: self.display_full_description(True)) elif display_more and self.display_full_description(): h << h.a(_(u'Read less'), class_='more').action(lambda: self.display_full_description(False)) return h.root
def render_ActionLog_history(self, h, *_args): h << h.h2(_('Action log')) log = self.get_history() users = set(event.user for event in log) cards = set(event.card for event in log) with h.div(id='action-log'): with h.form: with h.select(onchange=ajax.Update(action=self.user_id)): h << h.option(_('all users'), value='') for member in sorted(users, key=lambda u: u.fullname): h << h.option(member.fullname, value=member.username).selected( self.user_id()) with h.select(onchange=ajax.Update( action=lambda x: self.card_id(int(x)))): h << h.option(_('all cards'), value=0) for card in sorted(cards, key=lambda c: c.title): h << h.option(card.title, value=card.id).selected( self.card_id()) with h.div(class_='history'): with h.table(class_='table table-striped table-hover'): with h.body: for event in self.get_history(): with h.tr: h << h.th(format_datetime(event.when, 'short')) h << h.td(event.to_string()) return h.root
def render_comment(self, h, comp, model, *args): with h.div(class_='comment'): with h.div(class_='left'): h << self.author.render(h, model='avatar') with h.div(class_='right'): h << self.author.render(h, model='fullname') h << ' ' << _('wrote') << ' ' h << h.span( _(u'on'), ' ', format_datetime(self.creation_date), class_="date") if security.has_permissions('delete_comment', self): onclick = ( u"if (confirm(%(message)s)){%(action)s;}return false" % { 'action': h.a.action( comp.answer, comp ).get('onclick'), 'message': ajax.py2js( _(u'Your comment will be deleted. Are you sure?') ).decode('UTF-8') } ) h << h.a(h.i(class_='icon-cross'), title=_('Delete'), class_="comment-delete", onclick=onclick, href='') h << self.comment_label.render(h.AsyncRenderer()) return h.root
def render_ActionLog_history(self, h, *_args): h << h.h2(_('Action log')) log = self.get_history() users = set(event.user for event in log) cards = set(event.card for event in log) with h.div(id='action-log'): with h.form: with h.select(onchange=ajax.Update(action=self.user_id)): h << h.option(_('all users'), value='') for member in sorted(users, key=lambda u: u.fullname): h << h.option(member.fullname, value=member.username).selected( self.user_id()) with h.select(onchange=ajax.Update(action=lambda x: self.card_id(int(x)))): h << h.option(_('all cards'), value=0) for card in sorted(cards, key=lambda c: c.title): h << h.option(card.title, value=card.id).selected( self.card_id()) with h.div(class_='history'): with h.table(class_='table table-striped table-hover'): with h.body: for event in self.get_history(): with h.tr: h << h.th(format_datetime(event.when, 'short')) h << h.td(event.to_string()) return h.root
def render_ideas_progress_datatable(self, h, comp, *args): state_changed_ideas = self.find_state_changed_ideas() if state_changed_ideas: url = h.a.action(self.export_xls).get('onclick').replace( 'return nagare_getAndEval("', '').replace('")', '') with h.p(class_='xls-export'): h << h.a(h.img(src='style/desktop/icons/xls.gif'), _(u'Export to Excel'), href=url, title=_(u'Export all filtered ideas')) with h.table(class_='datatable'): # data with h.tbody: if state_changed_ideas: for (from_state, to_state), ideas in state_changed_ideas: if len(ideas) > 1: row_class = lambda i: { 0: 'inner-row-first', len(ideas) - 1: 'inner-row-last' }.get(i, 'inner-row') else: row_class = lambda i: '' for idx, (idea, date) in enumerate(ideas): with h.tr(class_=row_class(idx)): if idx == 0: with h.td(class_='state', rowspan=len(ideas)): h << _(from_state.label) h << h.div(u'⬇') h << _(to_state.label) h << ' (%d)' % len(ideas) with h.td: c = idea.challenge h << (h.span('#%d' % c.id, title=c.title) if c else '') with h.td: formatted_date = format_datetime(date) with h.span(title=_(u'State changed on %s') % formatted_date): h << component.Component( Idea(self, idea), model='short_link') else: with h.td(colspan=3, class_='warning'): h << _(u'No idea found') # column headings with h.thead: with h.tr: h << h.th(_(u"State changes")) h << h.th(_(u'Challenge')) h << h.th(_(u'Ideas')) return h.root
def render_comment(self, h, comp, *args): voters = self.voters voters_uids = [voter.uid for voter in voters] pager = UserPager(self, lambda uids=voters_uids: UserRepository().get_by_uids(uids)) relevant_comment_users_dialog = component.Component(ModalBox(AsyncWrapper(component.Component(pager, model='minimal')), title=_(u'Users finding this comment relevant'), visible=False)) with h.li: h << h.a(name='comment%s' % self.id) # so we can navigate to comments sync = h.SyncRenderer() h << relevant_comment_users_dialog.render(sync) with h.div(class_='user'): # creator avatar h << component.Component(User(self, self.comment.created_by)).render(sync, model='avatar100') if voters: with h.div(class_='alert'): nb_voters = len(voters_uids) if nb_voters > 1: message = _(u"%s people find this comment relevant") % nb_voters else: message = _(u"One people find this comment relevant") h << h.a(message, title=message, href='javascript:' + relevant_comment_users_dialog().show_js(), class_='votes') with h.div(class_='author'): # author h << _(u"From") << " " h << comp.render(sync, model='author') << " " # date if self.comment.submission_date: # deal with missing dates in the database h << _(u'on') << " " with h.span(class_='date'): h << format_datetime(self.comment.submission_date) h << " " h << h.p(text_to_html_elements(h, self.comment.content)) # attachment if self.comment.attachment: with h.p: h << component.Component(Attachment(self.comment.attachment)).render(h) with h.div(class_='links'): h << comp.render(h, model='actions') # delete form h << comp.render(h, model='delete_form') return h.root
def test_format_datetime(): set_locale(Locale('en', 'US')) dt = datetime.datetime(2007, 4, 1, 15, 30) assert i18n.format_datetime(dt) == 'Apr 1, 2007, 3:30:00 PM' set_locale( Locale('fr', 'FR', timezone=pytz.timezone('Europe/Paris'), default_timezone=pytz.UTC)) dt = datetime.datetime(2007, 4, 1, 15, 30) assert i18n.format_datetime( dt, 'full' ) == u'dimanche 1 avril 2007 à 17:30:00 heure d’été d’Europe centrale' set_locale( Locale('en', timezone=pytz.timezone('US/Eastern'), default_timezone=pytz.UTC)) assert i18n.format_datetime( dt, "yyyy.MM.dd G 'at' HH:mm:ss zzz") == '2007.04.01 AD at 11:30:00 EDT'
def render_profile_box_tracked_ideas(self, h, comp, *args): with h.div(class_='tracking-details'): with h.div(class_='events'): with h.h2: h << _(u"Latest events") if self.new_events_count(): h << h.a(_(u'Mark everything as read'), class_="consume_link", href="").action(lambda: self.read_all_events()) with h.ul: for i, event in enumerate(self.events()): idea = event.idea css_class = ' '.join((['odd', 'even'][i % 2], ('read' if event.status == EventStatus.Read else 'unread'))) event_date = format_datetime(event.date) event_type_display = { EventType.CommentAdded: ('comment', "style/desktop/icons/comment_delete.png"), EventType.StateChanged: ('worflow', "style/desktop/icons/chart_bar_delete.png") } css_specific_class, icon_src = event_type_display[event.label] with h.li(class_=css_specific_class + " " + css_class): with h.a(title=_(u'Remove the event'), class_='remove-event').action(lambda event_id=event.id: self.hide_event(event_id)): h << h.img(title=_(u'Remove the event'), alt=_(u'Remove the event'), src=icon_src) h << h.a(_(u'New comment for the idea %s') % idea.title, href="idea/%d" % idea.id, title=event_date).action(lambda event_id=event.id: self.read_event(event_id)) with h.div(class_='ideas rounded'): with h.h2: h << _(u"My Tracked Ideas") with h.ul: for i, idea in enumerate(self.tracked_ideas()): with h.li(class_=['odd', 'even'][i % 2]): h << h.a(_(u'Remove tracking'), title=_(u'Remove tracking'), class_='remove-tracking').action(lambda id=idea.id: self.remove_tracked_idea(id)) h << ' ' h << h.a(idea.title, title=_(u"View the idea"), href="idea/%d" % idea.id).action(lambda id=idea.id: self.view_idea(id)) return h.root
def render_comment(self, h, comp, model, *args): with h.div(class_='comment'): with h.div(class_='left'): h << self.author.render(h, model='avatar') with h.div(class_='right'): h << self.author.render(h, model='fullname') h << _(' wrote ') h << h.span( _(u'on'), ' ', format_datetime(self.creation_date), class_="date") if security.has_permissions('delete_comment', self): h << h.a(_('Delete'), class_="comment-delete").action(lambda: comp.answer(comp)) h << self.comment_label.render(h.AsyncRenderer()) return h.root
def render(self, r, date=datetime.now(), max_results=None): title = _("Most Liked Comments") with r.sheet(title): # title r << r.row() with r.row: r << r.cell(title, colspan=5, style=r.Style.Heading1) r << r.row() # column headings with r.row: style = (r.Border.TopMedium + r.Border.BottomMedium + r.Border.Left + r.Border.Right + r.Style.ColumnHeading + r.Style.Wrap + r.Background.LightYellow) r << r.cell( _("Score"), width=100, style=style + r.Border.LeftMedium) r << r.cell(_("Comment"), width=1400, style=style) r << r.cell(_("Author"), width=300, style=style) r << r.cell(_("Date"), width=200, style=style) r << r.cell( _("Idea"), width=100, style=style + r.Border.RightMedium) # data for idx, (comment, score) in enumerate( self.comments_and_scores(date, max_results)): style = (r.Style.VerticalAlignCenter + r.Border.All + r.Style.Wrap) # odd rows style if idx % 2: style += r.Background.PaleBlue with r.row: r << r.cell(score, style=style + r.Border.LeftMedium) r << r.cell(comment.content, style=style) r << r.cell(comment.created_by.fullname, style=style) r << r.cell(format_datetime(comment.submission_date, format='short'), style=style) r << r.cell(comment.idea.id, style=style + r.Border.RightMedium) with r.row: r << r.cell(colspan=5, style=r.Border.TopMedium)
def render_ideas_progress_datatable(self, h, comp, *args): state_changed_ideas = self.find_state_changed_ideas() if state_changed_ideas: url = h.a.action(self.export_xls).get('onclick').replace('return nagare_getAndEval("', '').replace('")', '') with h.p(class_='xls-export'): h << h.a(h.img(src='style/desktop/icons/xls.gif'), _(u'Export to Excel'), href=url, title=_(u'Export all filtered ideas')) with h.table(class_='datatable'): # data with h.tbody: if state_changed_ideas: for (from_state, to_state), ideas in state_changed_ideas: if len(ideas) > 1: row_class = lambda i: {0: 'inner-row-first', len(ideas) - 1: 'inner-row-last'}.get(i, 'inner-row') else: row_class = lambda i: '' for idx, (idea, date) in enumerate(ideas): with h.tr(class_=row_class(idx)): if idx == 0: with h.td(class_='state', rowspan=len(ideas)): h << _(from_state.label) h << h.div(u'⬇') h << _(to_state.label) h << ' (%d)' % len(ideas) with h.td: c = idea.challenge h << (h.span('#%d' % c.id, title=c.title) if c else '') with h.td: formatted_date = format_datetime(date) with h.span(title=_(u'State changed on %s') % formatted_date): h << component.Component(Idea(self, idea), model='short_link') else: with h.td(colspan=3, class_='warning'): h << _(u'No idea found') # column headings with h.thead: with h.tr: h << h.th(_(u"State changes")) h << h.th(_(u'Challenge')) h << h.th(_(u'Ideas')) return h.root
def render(self, r, date=datetime.now(), max_results=None): title = _("Most Liked Comments") with r.sheet(title): # title r << r.row() with r.row: r << r.cell(title, colspan=5, style=r.Style.Heading1) r << r.row() # column headings with r.row: style = (r.Border.TopMedium + r.Border.BottomMedium + r.Border.Left + r.Border.Right + r.Style.ColumnHeading + r.Style.Wrap + r.Background.LightYellow) r << r.cell(_("Score"), width=100, style=style + r.Border.LeftMedium) r << r.cell(_("Comment"), width=1400, style=style) r << r.cell(_("Author"), width=300, style=style) r << r.cell(_("Date"), width=200, style=style) r << r.cell(_("Idea"), width=100, style=style + r.Border.RightMedium) # data for idx, (comment, score) in enumerate(self.comments_and_scores(date, max_results)): style = (r.Style.VerticalAlignCenter + r.Border.All + r.Style.Wrap) # odd rows style if idx % 2: style += r.Background.PaleBlue with r.row: r << r.cell(score, style=style + r.Border.LeftMedium) r << r.cell(comment.content, style=style) r << r.cell(comment.created_by.fullname, style=style) r << r.cell(format_datetime(comment.submission_date, format='short'), style=style) r << r.cell(comment.idea.id, style=style + r.Border.RightMedium) with r.row: r << r.cell(colspan=5, style=r.Border.TopMedium)
def render_history(self, h, *_args): h << h.h2(_('Action log')) board = self.board.data with h.select(onchange=ajax.Update(action=self.user_id)): h << h.option(_('all users'), value='') for member in board.members: h << h.option(member.fullname, value=member.username).selected( self.user_id()) with h.select(onchange=ajax.Update(action=lambda x: self.card_id(int(x)))): h << h.option(_('all cards'), value=0) for col in board.columns: for card in col.cards: h << h.option(card.title, value=card.id).selected( self.card_id()) with h.div(class_='history row-fluid'): with h.table(class_='table table-striped table-hover'): with h.body: for event in get_history(board, cardid=self.card_id(), username=self.user_id()): with h.tr: h << h.th(format_datetime(event.when, 'short')) h << h.td(render_event(event)) return h.root
def render_aggregated_email(self, h, comp, *args): # head h.head << h.head.title(self.title) # h.head << h.head.meta({'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8'}) # body with h.body: h << h.style(EMAIL_CSS, type='text/css') for idx, message in enumerate(self.user.pending_email_messages): if idx > 0: h << h.hr with h.div(class_='title'): h << message.subject with h.div(class_='date'): h << format_datetime(message.creation_date) content = h.parse_htmlstring(message.content) h << content.xpath('/html/body/*') return h.root
def render_history(self, h, *_args): h << h.h2(_('Action log')) board = self.board.data with h.select(onchange=ajax.Update(action=self.user_id)): h << h.option(_('all users'), value='') for member in board.members: h << h.option(member.fullname, value=member.username).selected( self.user_id()) with h.select(onchange=ajax.Update(action=lambda x: self.card_id(int(x)))): h << h.option(_('all cards'), value=0) for col in board.columns: for card in col.cards: h << h.option(card.title, value=card.id).selected( self.card_id()) with h.div(class_='history'): with h.table(class_='table table-striped table-hover'): with h.body: for event in get_history(board, cardid=self.card_id(), username=self.user_id()): with h.tr: h << h.th(format_datetime(event.when, 'short')) h << h.td(render_event(event)) return h.root
def render_profile_box_tracked_ideas(self, h, comp, *args): with h.div(class_='tracking-details'): with h.div(class_='events'): with h.h2: h << _(u"Latest events") if self.new_events_count(): h << h.a(_(u'Mark everything as read'), class_="consume_link", href="").action(lambda: self.read_all_events()) with h.ul: for i, event in enumerate(self.events()): idea = event.idea css_class = ' '.join( (['odd', 'even'][i % 2], ('read' if event.status == EventStatus.Read else 'unread'))) event_date = format_datetime(event.date) event_type_display = { EventType.CommentAdded: ('comment', "style/desktop/icons/comment_delete.png"), EventType.StateChanged: ('worflow', "style/desktop/icons/chart_bar_delete.png") } css_specific_class, icon_src = event_type_display[ event.label] with h.li(class_=css_specific_class + " " + css_class): with h.a(title=_(u'Remove the event'), class_='remove-event').action( lambda event_id=event.id: self.hide_event( event_id)): h << h.img(title=_(u'Remove the event'), alt=_(u'Remove the event'), src=icon_src) h << h.a( _(u'New comment for the idea %s') % idea.title, href="idea/%d" % idea.id, title=event_date).action(lambda event_id=event.id: self.read_event(event_id)) with h.div(class_='ideas rounded'): with h.h2: h << _(u"My Tracked Ideas") with h.ul: for i, idea in enumerate(self.tracked_ideas()): with h.li(class_=['odd', 'even'][i % 2]): h << h.a(_(u'Remove tracking'), title=_(u'Remove tracking'), class_='remove-tracking').action( lambda id=idea.id: self. remove_tracked_idea(id)) h << ' ' h << h.a(idea.title, title=_(u"View the idea"), href="idea/%d" % idea.id).action( lambda id=idea.id: self.view_idea(id)) return h.root
def render_eval_comment_table_row(self, h, comp, *args): h << h.td(format_datetime(self.data.submission_date)) h << h.td(self.data.created_by.fullname) h << h.td(self.data.expert.fullname) h << h.td(self.data.content) return h.root
def render_article_date(self, h, comp, *args): if self.article.creation_date: with h.div(class_='date'): h << format_datetime(self.article.creation_date, format='short') return h.root
def render_point_items(self, h, comp, category, points): # configuration of the view reason_title = _(u"Reason") subject_title = _(u"Subject") if category == PointCategory.REMOVE_COMMENT: subject_title = _(u'Deleted comment') elif category == PointCategory.ADD_COMMENT: subject_title = _(u'Added comment') show_reason = any(p.reason for p in points) show_subject = any(p.subject_as_string() for p in points) show_delete = (category in get_manual_point_categories() ) and security.has_permissions('edit_points', self) categories_to_highlight = (PointCategory.PUBLISH_IDEA, PointCategory.PUBLISH_CHALLENGE_FIRST_IDEA, PointCategory.APPROVAL, PointCategory.SELECTED_IDEA) must_highlight = category in categories_to_highlight points_sum = sum([p.nb_points for p in points]) # title with h.div(class_='title ' + ('highlight' if must_highlight else '')): if security.has_permissions('view_points_detail', self): h << h.a(class_="toggle on", onclick='toggleCollapseExpand(this);') h << h.a(class_="toggle off", onclick='toggleCollapseExpand(this);') else: h << h.a(class_="toggle off", style='display:block;') h << h.span(_(category), class_='label') h << _(u': ') h << h.span(_(u'%d point(s)') % points_sum, class_='nb_points') # expandable details points.sort(key=operator.attrgetter('date'), reverse=True) if security.has_permissions('view_points_detail', self): with h.table(class_='items'): with h.thead: with h.colgroup: h << h.col(class_='date') << h.col(class_='points') if show_subject: h << h.col(class_='subject') if show_reason: h.col(class_='reason') if show_delete: h.col(class_='action') with h.tbody: with h.tr: h << h.th(_(u'Date')) << h.th(_(u'Points')) if show_subject: h << h.th(subject_title) if show_reason: h << h.th(reason_title) if show_delete: h << h.th for idx, p in enumerate(points): with h.tr(class_='odd' if idx % 2 == 0 else 'even'): formatted_date = format_datetime(p.date, format='short') h << h.td(formatted_date, class_='date') h << h.td(p.nb_points or '-', class_='nb_points') if show_subject: subj = p.subject_as_string() h << h.td(ellipsize(subj, 60), title=subj) if show_reason: reason = p.reason or '' h << h.td(ellipsize(reason, 50), title=reason, class_='reason') if show_delete: js = 'return yuiConfirm(this.href, "%s", "%s")' % ( _(u'Confirm delete?'), _(u'This point item will be deleted permanently: are you sure?' )) h << h.td( h.a(_(u'Delete'), title=_(u'Delete'), class_='delete', onclick=js).action( lambda id=p.id: self.remove_point(id)))
def render_point_items(self, h, comp, category, points): # configuration of the view reason_title = _(u"Reason") subject_title = _(u"Subject") if category == PointCategory.REMOVE_COMMENT: subject_title = _(u'Deleted comment') elif category == PointCategory.ADD_COMMENT: subject_title = _(u'Added comment') show_reason = any(p.reason for p in points) show_subject = any(p.subject_as_string() for p in points) show_delete = (category in get_manual_point_categories()) and security.has_permissions('edit_points', self) categories_to_highlight = (PointCategory.PUBLISH_IDEA, PointCategory.PUBLISH_CHALLENGE_FIRST_IDEA, PointCategory.APPROVAL, PointCategory.SELECTED_IDEA) must_highlight = category in categories_to_highlight points_sum = sum([p.nb_points for p in points]) # title with h.div(class_='title ' + ('highlight' if must_highlight else '')): if security.has_permissions('view_points_detail', self): h << h.a(class_="toggle on", onclick='toggleCollapseExpand(this);') h << h.a(class_="toggle off", onclick='toggleCollapseExpand(this);') else: h << h.a(class_="toggle off", style='display:block;') h << h.span(_(category), class_='label') h << _(u': ') h << h.span(_(u'%d point(s)') % points_sum, class_='nb_points') # expandable details points.sort(key=operator.attrgetter('date'), reverse=True) if security.has_permissions('view_points_detail', self): with h.table(class_='items'): with h.thead: with h.colgroup: h << h.col(class_='date') << h.col(class_='points') if show_subject: h << h.col(class_='subject') if show_reason: h.col(class_='reason') if show_delete: h.col(class_='action') with h.tbody: with h.tr: h << h.th(_(u'Date')) << h.th(_(u'Points')) if show_subject: h << h.th(subject_title) if show_reason: h << h.th(reason_title) if show_delete: h << h.th for idx, p in enumerate(points): with h.tr(class_='odd' if idx % 2 == 0 else 'even'): formatted_date = format_datetime(p.date, format='short') h << h.td(formatted_date, class_='date') h << h.td(p.nb_points or '-', class_='nb_points') if show_subject: subj = p.subject_as_string() h << h.td(ellipsize(subj, 60), title=subj) if show_reason: reason = p.reason or '' h << h.td(ellipsize(reason, 50), title=reason, class_='reason') if show_delete: js = 'return yuiConfirm(this.href, "%s", "%s")' % (_(u'Confirm delete?'), _(u'This point item will be deleted permanently: are you sure?')) h << h.td(h.a(_(u'Delete'), title=_(u'Delete'), class_='delete', onclick=js).action(lambda id=p.id: self.remove_point(id)))