def generate_html(self): avatar_size = '30s' max_num_faces = 5 li_fn = lambda user: html.li(class_='yui3-u', title=user.username, *[ html.a(href=smart_reverse(self.request, 'user_detail_view', args=[user.username]), class_='avatar facepile-size', style={'background-image': 'url(%s)' % user.avatar_image.get(avatar_size, '')}) ]) tree = html.ul( *[li_fn(user) for user in self.starred_by[:max_num_faces]] ) return tree
def generate_html(self): avatar_size = '30s' max_num_faces = 5 li_fn = lambda user: html.li( class_='yui3-u', title=user.username, *[ html.a(href=smart_reverse( self.request, 'user_detail_view', args=[user.username]), class_='avatar facepile-size', style={ 'background-image': 'url(%s)' % user.avatar_image.get(avatar_size, '') }) ]) tree = html.ul( *[li_fn(user) for user in self.starred_by[:max_num_faces]]) return tree
def generate_post_header(self): username_block = html.span(class_='username') if self.post_a.user: username_block = html.span(class_='username p-author h-card', *[ html.a(href=self.user_detail_url, data=self.click_data, class_='p-nickname u-url', *[ self.post_a.user.username ]) ]) header_items = [] # star this post if self.is_authenticated: if self.show_star_button: star_presenter = StarPresenter.from_data(self.request, self.post_a) star_html = star_presenter.generate_html() header_items.append( html.li(class_='yui3-u', *[ star_html ]) ) if self.show_repost_button: repost_button = RepostButtonPresenter.from_data(self.request, self.post_a) repost_button_html = repost_button.generate_html() if repost_button_html != '': header_items.append( html.li(class_='yui3-u repost', *[ repost_button_html ]) ) return html.div(class_='post-header', *[ username_block, html.ul(class_='ul-horizontal unstyled yui3-u fixed-right ta-right', *header_items) ]) return username_block
def generate_post_footer(self): if self.post_a.get('is_deleted'): return '' footer_top_row = [] # repost # N.B. if you change this html (reposts), make sure to change the ajax handler for repost, # which duplicates this html to provide client-side feedback viewer_has_reposted = self.post_a.get('you_reposted') if self.repost or viewer_has_reposted: # yes, there is a priority order of reposter info - viewer trumps everyone else if viewer_has_reposted: reposter_username = self.request.user.username reposter_display = 'you' elif self.repost: reposter_username = self.repost.user.username reposter_display = '@' + reposter_username footer_top_row.append( html.div(class_='post-reposted-by yui3-u', *[ html.span( class_='reposted-by-text', *[ html.i(class_='icon-repost'), html.span( ' Reposted by ', *[ html.a(href=smart_reverse( self.request, 'user_detail_view', args=[reposter_username]), data=self.click_data, *[reposter_display]), ]) ]) ])) # place place_annotation = get_place_annotation( self.post_a.get('annotations', [])) if place_annotation: if place_annotation['value'].get('address'): place_pretty = u'%s \u2014 %s' % ( place_annotation['value']['name'], place_annotation['value']['address']) else: place_pretty = u'%s' % place_annotation['value']['name'] tags_html = [] if place_annotation.get('type') == 'net.app.core.checkin': factual_url = urljoin('http://factual.com/', place_annotation['value']['factual_id']) tags_html.append(html.meta(name="factual", content=factual_url)) tags_html.append( html.span(class_='posted-from-text', *[ html.i(class_='icon-pushpin'), html.span(' at %s' % place_pretty), ])) footer_top_row.append( html.div(class_='post-posted-from-place yui3-u', *tags_html)) footer_bottom_row = [] # timestamp timezone_str = self.request.user.adn_user.timezone if self.is_authenticated else 'America/Los_Angeles' viewers_timezone = pytz.timezone(timezone_str) non_relative_timestamp = pytz.utc.localize( self.post_a.created_at).astimezone(viewers_timezone) datetime_formatted = non_relative_timestamp.strftime( "%I:%M %p - %d %b %Y") footer_bottom_row.append( html.li( html.a(href=self.post_detail_url, data=self.click_data, class_='timestamp u-url', title=datetime_formatted, *[ html.time(class_='dt-published', datetime=datetime_formatted, *[ html.i(class_='icon-time yui3-u'), " " + naturaldate(self.post_a.created_at), ]) ])), ) is_reply = hasattr(self.post_a, 'reply_to') and self.post_a.reply_to reply_to_hash = "#" + str(self.post_a.reply_to) if is_reply else '' # conversation active? if is_reply or (self.post_a.num_replies > 0 and not self.single_post): footer_bottom_row.append( html.li(class_='in-reply-to yui3-u', *[ html.a(href=self.post_detail_url + reply_to_hash, data=self.click_data, title='In Reply To...', *[ html.i( class_='icon-comments', **{'aria-label': 'In Reply To...'}) ]) ])) # reply if self.is_authenticated and self.show_reply_button: footer_bottom_row.append(self.reply_button()) if self.show_stream_marker: data = {'set-stream-marker': ''} footer_bottom_row.append( html.li(class_='show-on-hover yui3-u stream-marker-button', *[ html.a(href='#', data=data, *[html.i(class_='icon-bookmark'), ""]) ])) if self.post_a.source and self.show_via_attribution: source_link = getattr(self.post_a.source, 'link', None) source_name = getattr(self.post_a.source, 'name', None) if source_link and source_name: footer_bottom_row.append( html.li(class_='show-on-hover post-source yui3-u', *[ html.a(href=self.post_a.source.link, rel='nofollow', target='_blank', *[ html.i(class_='icon-share'), ' via ' + source_name ]) ])) # crosspost annotations = self.post_a.get('annotations', []) cp_url = None for a in annotations: annotation_type = a.get('type') if annotation_type == "net.app.core.crosspost": cp_url = a.get('value', {}).get('canonical_url') if cp_url and not re.match('^https?://', cp_url, re.IGNORECASE): cp_url = "http://" + cp_url if cp_url: cp_url_display = urlparse(cp_url).netloc if cp_url_display.startswith('www.'): cp_url_display = cp_url_display[4:] footer_bottom_row.append( html.li(class_='show-on-hover crossposted-from yui3-u', *[ html.a(href=cp_url, target='_blank', *[ html.i(class_='icon-random'), ' from ' + cp_url_display ]) ])) # report this post to app.net if self.show_report_button: if self.is_authenticated and self.request.user.adn_user.id != self.post_a.user.id: footer_bottom_row.append( html.li( class_='show-on-hover last pull-right yui3-u', *[ html.a( href='#report', data={'post-report': ''}, *[ html.i(class_='icon-flag'), html.span( class_='t-yui3-u-none m-yui3-u-none', *[' Report']), ]) ])) # mute this user--it's not really an if/else with the delete case so I'm not combining the conditions if self.show_mute_button: if self.is_authenticated and self.request.user.adn_user.id != self.post_a.user.id and not self.post_a.user.you_muted: footer_bottom_row.append( html.li( class_='show-on-hover pull-right yui3-u', *[ html.a( href='#mute-user', data={'post-mute-user': ''}, *[ html.i(class_='icon-minus-sign'), html.span( class_='t-yui3-u-none m-yui3-u-none', *[' Mute user']), ]) ])) # delete this post if self.show_delete_button: if self.is_authenticated and self.request.user.adn_user.id == self.post_a.user.id: footer_bottom_row.append( html.li( class_='show-on-hover last pull-right yui3-u', *[ html.a( href='#delete', data={'post-delete': ''}, *[ html.i(class_='icon-remove'), html.span( class_='t-yui3-u-none m-yui3-u-none', *[' Delete']), ]) ])) tree = html.div(class_='post-footer', *[ html.ul(class_='ul-horizontal unstyled footer-top', *footer_top_row), html.ul( class_='ul-horizontal unstyled footer-bottom', *footer_bottom_row) ]) return tree
def generate_post_footer(self): if self.post_a.get('is_deleted'): return '' footer_top_row = [] # repost # N.B. if you change this html (reposts), make sure to change the ajax handler for repost, # which duplicates this html to provide client-side feedback viewer_has_reposted = self.post_a.get('you_reposted') if self.repost or viewer_has_reposted: # yes, there is a priority order of reposter info - viewer trumps everyone else if viewer_has_reposted: reposter_username = self.request.user.username reposter_display = 'you' elif self.repost: reposter_username = self.repost.user.username reposter_display = '@' + reposter_username footer_top_row.append( html.div(class_='post-reposted-by yui3-u', *[ html.span(class_='reposted-by-text', *[ html.i(class_='icon-repost'), html.span(' Reposted by ', *[ html.a(href=smart_reverse(self.request, 'user_detail_view', args=[reposter_username]), data=self.click_data, *[reposter_display]), ]) ]) ]) ) # place place_annotation = get_place_annotation(self.post_a.get('annotations', [])) if place_annotation: if place_annotation['value'].get('address'): place_pretty = u'%s \u2014 %s' % (place_annotation['value']['name'], place_annotation['value']['address']) else: place_pretty = u'%s' % place_annotation['value']['name'] tags_html = [] if place_annotation.get('type') == 'net.app.core.checkin': factual_url = urljoin('http://factual.com/', place_annotation['value']['factual_id']) tags_html.append(html.meta(name="factual", content=factual_url)) tags_html.append(html.span(class_='posted-from-text', *[ html.i(class_='icon-pushpin'), html.span(' at %s' % place_pretty), ])) footer_top_row.append(html.div(class_='post-posted-from-place yui3-u', *tags_html)) footer_bottom_row = [] # timestamp timezone_str = self.request.user.adn_user.timezone if self.is_authenticated else 'America/Los_Angeles' viewers_timezone = pytz.timezone(timezone_str) non_relative_timestamp = pytz.utc.localize(self.post_a.created_at).astimezone(viewers_timezone) datetime_formatted = non_relative_timestamp.strftime("%I:%M %p - %d %b %Y") footer_bottom_row.append(html.li( html.a(href=self.post_detail_url, data=self.click_data, class_='timestamp u-url', title=datetime_formatted, *[ html.time(class_='dt-published', datetime=datetime_formatted, *[ html.i(class_='icon-time yui3-u'), " " + naturaldate(self.post_a.created_at), ]) ])), ) is_reply = hasattr(self.post_a, 'reply_to') and self.post_a.reply_to reply_to_hash = "#" + str(self.post_a.reply_to) if is_reply else '' # conversation active? if is_reply or (self.post_a.num_replies > 0 and not self.single_post): footer_bottom_row.append( html.li(class_='in-reply-to yui3-u', *[ html.a(href=self.post_detail_url + reply_to_hash, data=self.click_data, title='In Reply To...', *[ html.i(class_='icon-comments', **{'aria-label': 'In Reply To...'}) ]) ]) ) # reply if self.is_authenticated and self.show_reply_button: footer_bottom_row.append(self.reply_button()) if self.show_stream_marker: data = { 'set-stream-marker': '' } footer_bottom_row.append( html.li(class_='show-on-hover yui3-u stream-marker-button', *[ html.a(href='#', data=data, *[ html.i(class_='icon-bookmark'), "" ]) ]) ) if self.post_a.source and self.show_via_attribution: source_link = getattr(self.post_a.source, 'link', None) source_name = getattr(self.post_a.source, 'name', None) if source_link and source_name: footer_bottom_row.append( html.li(class_='show-on-hover post-source yui3-u', *[ html.a(href=self.post_a.source.link, rel='nofollow', target='_blank', *[ html.i(class_='icon-share'), ' via ' + source_name ]) ]) ) # crosspost annotations = self.post_a.get('annotations', []) cp_url = None for a in annotations: annotation_type = a.get('type') if annotation_type == "net.app.core.crosspost": cp_url = a.get('value', {}).get('canonical_url') if cp_url and not re.match('^https?://', cp_url, re.IGNORECASE): cp_url = "http://" + cp_url if cp_url: cp_url_display = urlparse(cp_url).netloc if cp_url_display.startswith('www.'): cp_url_display = cp_url_display[4:] footer_bottom_row.append( html.li(class_='show-on-hover crossposted-from yui3-u', *[ html.a(href=cp_url, target='_blank', *[ html.i(class_='icon-random'), ' from ' + cp_url_display ]) ]) ) # report this post to app.net if self.show_report_button: if self.is_authenticated and self.request.user.adn_user.id != self.post_a.user.id: footer_bottom_row.append( html.li(class_='show-on-hover last pull-right yui3-u', *[ html.a(href='#report', data={'post-report': ''}, *[ html.i(class_='icon-flag'), html.span(class_='t-yui3-u-none m-yui3-u-none', *[' Report']), ]) ]) ) # mute this user--it's not really an if/else with the delete case so I'm not combining the conditions if self.show_mute_button: if self.is_authenticated and self.request.user.adn_user.id != self.post_a.user.id and not self.post_a.user.you_muted: footer_bottom_row.append( html.li(class_='show-on-hover pull-right yui3-u', *[ html.a(href='#mute-user', data={'post-mute-user': ''}, *[ html.i(class_='icon-minus-sign'), html.span(class_='t-yui3-u-none m-yui3-u-none', *[' Mute user']), ]) ]) ) # delete this post if self.show_delete_button: if self.is_authenticated and self.request.user.adn_user.id == self.post_a.user.id: footer_bottom_row.append( html.li(class_='show-on-hover last pull-right yui3-u', *[ html.a(href='#delete', data={'post-delete': ''}, *[ html.i(class_='icon-remove'), html.span(class_='t-yui3-u-none m-yui3-u-none', *[' Delete']), ]) ]) ) tree = html.div(class_='post-footer', *[ html.ul(class_='ul-horizontal unstyled footer-top', *footer_top_row), html.ul(class_='ul-horizontal unstyled footer-bottom', *footer_bottom_row) ]) return tree