def revisions(request, id, post_type = None): assert post_type in ('question', 'answer') post = get_object_or_404(models.Post, post_type=post_type, id=id) if post.deleted: if request.user.is_anonymous() \ or not request.user.is_administrator_or_moderator(): raise Http404 revisions = list(models.PostRevision.objects.filter(post=post)) revisions.reverse() for i, revision in enumerate(revisions): if i == 0: revision.diff = sanitize_html(revisions[i].html) revision.summary = _('initial version') else: revision.diff = htmldiff( sanitize_html(revisions[i-1].html), sanitize_html(revision.html) ) data = { 'page_class':'revisions-page', 'active_tab':'questions', 'post': post, 'revisions': revisions, } return render(request, 'revisions.html', data)
def parse_and_save_post(post, author=None, **kwargs): """generic method to use with posts to be used prior to saving post edit or addition """ assert (author is not None) last_revision = post.html data = post.parse() post.html = data['html'] newly_mentioned_users = set(data['newly_mentioned_users']) - set([author]) removed_mentions = data['removed_mentions'] #a hack allowing to save denormalized .summary field for questions if hasattr(post, 'summary'): post.summary = strip_tags(post.html)[:120] #delete removed mentions for rm in removed_mentions: rm.delete() created = post.pk is None #this save must precede saving the mention activity #because generic relation needs primary key of the related object super(post.__class__, post).save(**kwargs) if last_revision: diff = htmldiff(last_revision, post.html) else: diff = post.get_snippet() timestamp = post.get_time_of_last_edit() #create new mentions for u in newly_mentioned_users: from askbot.models.user import Activity Activity.objects.create_new_mention(mentioned_whom=u, mentioned_in=post, mentioned_by=author, mentioned_at=timestamp) #todo: this is handled in signal because models for posts #are too spread out from askbot.models import signals signals.post_updated.send(post=post, updated_by=author, newly_mentioned_users=newly_mentioned_users, timestamp=timestamp, created=created, diff=diff, sender=post.__class__) try: from askbot.conf import settings as askbot_settings if askbot_settings.GOOGLE_SITEMAP_CODE != '': ping_google() except Exception: logging.debug('cannot ping google - did you register with them?')
def parse_and_save_post(post, author=None, **kwargs): """generic method to use with posts to be used prior to saving post edit or addition """ assert author is not None last_revision = post.html data = post.parse() post.html = data["html"] newly_mentioned_users = set(data["newly_mentioned_users"]) - set([author]) removed_mentions = data["removed_mentions"] # a hack allowing to save denormalized .summary field for questions if hasattr(post, "summary"): post.summary = strip_tags(post.html)[:120] # delete removed mentions for rm in removed_mentions: rm.delete() created = post.pk is None # this save must precede saving the mention activity # because generic relation needs primary key of the related object super(post.__class__, post).save(**kwargs) if last_revision: diff = htmldiff(last_revision, post.html) else: diff = post.get_snippet() timestamp = post.get_time_of_last_edit() # todo: this is handled in signal because models for posts # are too spread out from askbot.models import signals signals.post_updated.send( post=post, updated_by=author, newly_mentioned_users=newly_mentioned_users, timestamp=timestamp, created=created, diff=diff, sender=post.__class__, ) try: from askbot.conf import settings as askbot_settings if askbot_settings.GOOGLE_SITEMAP_CODE != "": ping_google() except Exception: logging.debug("cannot ping google - did you register with them?")
def revisions(request, id, post_type=None): assert post_type in ("question", "answer") post = get_object_or_404(models.Post, post_type=post_type, id=id) revisions = list(models.PostRevision.objects.filter(post=post)) revisions.reverse() for i, revision in enumerate(revisions): if i == 0: revision.diff = sanitize_html(revisions[i].html) revision.summary = _("initial version") else: revision.diff = htmldiff(sanitize_html(revisions[i - 1].html), sanitize_html(revision.html)) data = {"page_class": "revisions-page", "active_tab": "questions", "post": post, "revisions": revisions} return render_into_skin("revisions.html", data, request)
def revisions(request, id, object_name=None): assert object_name in ("Question", "Answer") post = get_object_or_404(models.get_model(object_name), id=id) revisions = list(post.revisions.all()) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _("initial version") else: revision.diff = htmldiff(revisions[i - 1].html, revision.html) data = {"page_class": "revisions-page", "active_tab": "questions", "post": post, "revisions": revisions} return render_into_skin("revisions.html", data, request)
def revisions(request, id, object_name=None): if object_name == "Question": post = get_object_or_404(models.Post, post_type="question", id=id) else: post = get_object_or_404(models.Post, post_type="answer", id=id) revisions = list(models.PostRevision.objects.filter(post=post)) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _("initial version") else: revision.diff = htmldiff(revisions[i - 1].html, revision.html) data = {"page_class": "revisions-page", "active_tab": "questions", "post": post, "revisions": revisions} return render_into_skin("revisions.html", data, request)
def revisions(request, id, post_type = None): assert post_type in ('question', 'answer') post = get_object_or_404(models.Post, post_type=post_type, id=id) revisions = list(models.PostRevision.objects.filter(post=post)) revisions.reverse() for i, revision in enumerate(revisions): if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i-1].html, revision.html) data = { 'page_class':'revisions-page', 'active_tab':'questions', 'post': post, 'revisions': revisions, } return render_into_skin('revisions.html', data, request)
def revisions(request, id, post_type=None): assert post_type in ('question', 'answer') post = get_object_or_404(models.Post, post_type=post_type, id=id) revisions = list(models.PostRevision.objects.filter(post=post)) revisions.reverse() for i, revision in enumerate(revisions): if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i - 1].html, revision.html) data = { 'page_class': 'revisions-page', 'active_tab': 'questions', 'post': post, 'revisions': revisions, } return render_into_skin('revisions.html', data, request)
def revisions(request, id, object_name=None): assert(object_name in ('Question', 'Answer')) post = get_object_or_404(models.get_model(object_name), id=id) revisions = list(post.revisions.all()) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i-1].html, revision.html) data = { 'page_class':'revisions-page', 'active_tab':'questions', 'post': post, 'revisions': revisions, } return render_into_skin('revisions.html', data, request)
def revisions(request, id, object_name=None): assert (object_name in ('Question', 'Answer')) post = get_object_or_404(models.get_model(object_name), id=id) revisions = list(post.revisions.all()) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i - 1].html, revision.html) data = { 'page_class': 'revisions-page', 'active_tab': 'questions', 'post': post, 'revisions': revisions, } return render_into_skin('revisions.html', data, request)
def revisions(request, id, object_name=None): assert(object_name in ('Question', 'Answer')) post = get_object_or_404(models.get_model(object_name), id=id) revisions = list(post.revisions.all()) revisions.reverse() for i, revision in enumerate(revisions): revision.html = revision.as_html() if i == 0: revision.diff = revisions[i].html revision.summary = _('initial version') else: revision.diff = htmldiff(revisions[i-1].html, revision.html) data = { 'view_name':'answer_revisions', 'active_tab':'questions', 'post': post, 'revisions': revisions, } context = RequestContext(request, data) template = ENV.get_template('revisions.html') return HttpResponse(template.render(context))
def process_context(self, context): to_user = context.get('to_user') from_user = context.get('from_user') post = context.get('post') update_activity = context.get('update_activity') update_type = self.get_update_type(update_activity) origin_post = post.get_origin_post() from askbot.models import Post if update_type == 'question_comment': assert(isinstance(post, Post) and post.is_comment()) assert(post.parent and post.parent.is_question()) elif update_type == 'answer_comment': assert(isinstance(post, Post) and post.is_comment()) assert(post.parent and post.parent.is_answer()) elif update_type == 'answer_update': assert(isinstance(post, Post) and post.is_answer()) elif update_type == 'new_answer': assert(isinstance(post, Post) and post.is_answer()) elif update_type == 'question_update': assert(isinstance(post, Post) and post.is_question()) elif update_type == 'new_question': assert(isinstance(post, Post) and post.is_question()) elif update_type == 'post_shared': pass else: raise ValueError('unexpected update_type %s' % update_type) if update_type.endswith('update'): assert('comment' not in update_type) revisions = post.revisions.all()[:2] assert(len(revisions) == 2) content_preview = htmldiff( sanitize_html(revisions[1].html), sanitize_html(revisions[0].html), ins_start = '<b><u style="background-color:#cfc">', ins_end = '</u></b>', del_start = '<del style="color:#600;background-color:#fcc">', del_end = '</del>' ) #todo: remove hardcoded style else: content_preview = post.format_for_email(is_leaf_post=True, recipient=to_user) #add indented summaries for the parent posts content_preview += post.format_for_email_as_parent_thread_summary(recipient=to_user) #content_preview += '<p>======= Full thread summary =======</p>' #content_preview += post.thread.format_for_email(recipient=to_user) if update_type == 'post_shared': user_action = _('%(user)s shared a %(post_link)s.') elif post.is_comment(): if update_type.endswith('update'): user_action = _('%(user)s edited a %(post_link)s.') else: user_action = _('%(user)s posted a %(post_link)s') elif post.is_answer(): if update_type.endswith('update'): user_action = _('%(user)s edited an %(post_link)s.') else: user_action = _('%(user)s posted an %(post_link)s.') elif post.is_question(): if update_type.endswith('update'): user_action = _('%(user)s edited a %(post_link)s.') else: user_action = _('%(user)s posted a %(post_link)s.') else: raise ValueError('unrecognized post type') post_url = site_url(post.get_absolute_url()) user_url = site_url(from_user.get_absolute_url()) if to_user.is_administrator_or_moderator() and askbot_settings.SHOW_ADMINS_PRIVATE_USER_DATA: user_link_fmt = '<a href="%(profile_url)s">%(username)s</a> (<a href="mailto:%(email)s">%(email)s</a>)' user_link = user_link_fmt % { 'profile_url': user_url, 'username': from_user.username, 'email': from_user.email } elif post.is_anonymous: user_link = from_user.get_name_of_anonymous_user() else: user_link = '<a href="%s">%s</a>' % (user_url, from_user.username) user_action = user_action % { 'user': user_link, 'post_link': '<a href="%s">%s</a>' % (post_url, _(post.post_type)) } can_reply = to_user.can_post_by_email() from askbot.models import get_reply_to_addresses reply_address, alt_reply_address = get_reply_to_addresses(to_user, post) if can_reply: reply_separator = const.SIMPLE_REPLY_SEPARATOR_TEMPLATE % \ _('To reply, PLEASE WRITE ABOVE THIS LINE.') if post.post_type == 'question' and alt_reply_address: data = { 'addr': alt_reply_address, 'subject': urllib.quote( ('Re: ' + post.thread.title).encode('utf-8') ) } reply_separator += '<p>' + const.REPLY_WITH_COMMENT_TEMPLATE % data reply_separator += '</p>' else: reply_separator = '<p>%s</p>' % reply_separator reply_separator += user_action else: reply_separator = user_action return { 'admin_email': askbot_settings.ADMIN_EMAIL, 'recipient_user': to_user, 'update_author_name': from_user.username, 'receiving_user_name': to_user.username, 'receiving_user_karma': to_user.reputation, 'reply_by_email_karma_threshold': askbot_settings.MIN_REP_TO_POST_BY_EMAIL, 'can_reply': can_reply, 'content_preview': content_preview, 'update_type': update_type, 'update_activity': update_activity, 'post': post, 'post_url': post_url, 'origin_post': origin_post, 'thread_title': origin_post.thread.title, 'reply_separator': reply_separator, 'reply_address': reply_address, 'is_multilingual': getattr(django_settings, 'ASKBOT_MULTILINGUAL', False) }
def process_context(self, context): to_user = context.get('to_user') from_user = context.get('from_user') post = context.get('post') update_activity = context.get('update_activity') update_type = self.get_update_type(update_activity) origin_post = post.get_origin_post() from askbot.models import Post if update_type == 'question_comment': assert (isinstance(post, Post) and post.is_comment()) assert (post.parent and post.parent.is_question()) elif update_type == 'answer_comment': assert (isinstance(post, Post) and post.is_comment()) assert (post.parent and post.parent.is_answer()) elif update_type == 'answer_update': assert (isinstance(post, Post) and post.is_answer()) elif update_type == 'new_answer': assert (isinstance(post, Post) and post.is_answer()) elif update_type == 'question_update': assert (isinstance(post, Post) and post.is_question()) elif update_type == 'new_question': assert (isinstance(post, Post) and post.is_question()) elif update_type == 'post_shared': pass else: raise ValueError('unexpected update_type %s' % update_type) if update_type.endswith('update'): assert ('comment' not in update_type) revisions = post.revisions.all()[:2] assert (len(revisions) == 2) content_preview = htmldiff( sanitize_html(revisions[1].html), sanitize_html(revisions[0].html), ins_start='<b><u style="background-color:#cfc">', ins_end='</u></b>', del_start='<del style="color:#600;background-color:#fcc">', del_end='</del>') #todo: remove hardcoded style else: content_preview = post.format_for_email(is_leaf_post=True, recipient=to_user) #add indented summaries for the parent posts content_preview += post.format_for_email_as_parent_thread_summary( recipient=to_user) #content_preview += '<p>======= Full thread summary =======</p>' #content_preview += post.thread.format_for_email(recipient=to_user) if update_type == 'post_shared': user_action = _('%(user)s shared a %(post_link)s.') elif post.is_comment(): if update_type.endswith('update'): user_action = _('%(user)s edited a %(post_link)s.') else: user_action = _('%(user)s posted a %(post_link)s') elif post.is_answer(): if update_type.endswith('update'): user_action = _('%(user)s edited an %(post_link)s.') else: user_action = _('%(user)s posted an %(post_link)s.') elif post.is_question(): if update_type.endswith('update'): user_action = _('%(user)s edited a %(post_link)s.') else: user_action = _('%(user)s posted a %(post_link)s.') else: raise ValueError('unrecognized post type') post_url = site_url(post.get_absolute_url()) user_url = site_url(from_user.get_absolute_url()) if to_user.is_administrator_or_moderator( ) and askbot_settings.SHOW_ADMINS_PRIVATE_USER_DATA: user_link_fmt = '<a href="%(profile_url)s">%(username)s</a> (<a href="mailto:%(email)s">%(email)s</a>)' user_link = user_link_fmt % { 'profile_url': user_url, 'username': from_user.username, 'email': from_user.email } elif post.is_anonymous: user_link = from_user.get_name_of_anonymous_user() else: user_link = '<a href="%s">%s</a>' % (user_url, from_user.username) user_action = user_action % { 'user': user_link, 'post_link': '<a href="%s">%s</a>' % (post_url, _(post.post_type)) } can_reply = to_user.can_post_by_email() from askbot.models import get_reply_to_addresses reply_address, alt_reply_address = get_reply_to_addresses( to_user, post) if can_reply: reply_separator = const.SIMPLE_REPLY_SEPARATOR_TEMPLATE % \ _('To reply, PLEASE WRITE ABOVE THIS LINE.') if post.post_type == 'question' and alt_reply_address: data = { 'addr': alt_reply_address, 'subject': urllib.quote(('Re: ' + post.thread.title).encode('utf-8')) } reply_separator += '<p>' + const.REPLY_WITH_COMMENT_TEMPLATE % data reply_separator += '</p>' else: reply_separator = '<p>%s</p>' % reply_separator reply_separator += user_action else: reply_separator = user_action return { 'admin_email': askbot_settings.ADMIN_EMAIL, 'recipient_user': to_user, 'update_author_name': from_user.username, 'receiving_user_name': to_user.username, 'receiving_user_karma': to_user.reputation, 'reply_by_email_karma_threshold': askbot_settings.MIN_REP_TO_POST_BY_EMAIL, 'can_reply': can_reply, 'content_preview': content_preview, 'update_type': update_type, 'update_activity': update_activity, 'post': post, 'post_url': post_url, 'origin_post': origin_post, 'thread_title': origin_post.thread.title, 'reply_separator': reply_separator, 'reply_address': reply_address, 'is_multilingual': getattr(django_settings, 'ASKBOT_MULTILINGUAL', False) }