def handle(self, *args, **options): # pylint: disable=too-many-locals """Does the job of the command""" translation.activate(django_settings.LANGUAGE_CODE) uid, file_name = self.get_params(options) try: user = User.objects.get(pk=uid) except User.DoesNotExist: # pylint: disable=no-member raise CommandError('User with id {} does not exist'.format(uid)) lang_data = dict() for profile in user.localized_askbot_profiles.all(): lang = profile.language_code profile_url = user.get_absolute_url(language_code=lang) profile_data = { 'about': profile.about, 'profile_url': site_url(profile_url) } lang_data[lang] = profile_data user_profile = { 'localized_profiles': lang_data, 'date_of_birth': str(user.date_of_birth), 'username': user.username, 'profile_url': site_url(user.get_absolute_url()), 'email': user.email } data = {'user_profile': user_profile} question_data = self.get_question_data(user) data['questions'] = list(question_data.values()) answer_data = self.get_post_data(user, 'answer') data['answers'] = list(answer_data.values()) comment_data = self.get_post_data(user, 'comment') data['comments'] = list(comment_data.values()) upfiles = self.get_upfiles(data) temp_dir = tempfile.mkdtemp() self.backup_upfiles_and_avatar(upfiles, user, temp_dir) self.save_json_file(data, temp_dir) self.zip_tempdir(temp_dir, file_name) shutil.rmtree(temp_dir)
def get_question_data(thread): """returns data dictionary for a given thread""" question_post = thread._question_post() #pylint: disable=protected-access datum = { 'added_at': get_epoch_str(thread.added_at), 'id': question_post.id, 'answer_count': thread.answer_count, 'answer_ids': thread.get_answer_ids(), 'accepted_answer_id': thread.accepted_answer_id, 'view_count': thread.view_count, 'score': thread.score, 'last_activity_at': get_epoch_str(thread.last_activity_at), 'title': thread.title, 'summary': question_post.summary, 'tags': thread.tagnames.strip().split(), 'url': site_url(thread.get_absolute_url()), } if question_post.last_edited_at: datum['last_edited_at'] = get_epoch_str(question_post.last_edited_at) if question_post.last_edited_by: datum['last_edited_by'] = get_user_id_info( question_post.last_edited_by) if thread.closed: datum['closed'] = True datum['closed_by'] = get_user_id_info(thread.closed_by) datum['closed_at'] = get_epoch_str(thread.closed_at) datum['closed_reason'] = thread.get_close_reason_display() datum['author'] = get_user_id_info(question_post.author) datum['last_activity_by'] = get_user_id_info(thread.last_activity_by) return datum
def get_post_data(cls, user, post_type): """Returns a dictionary valued with with question data, keyed by question objects.""" posts = user.posts.filter(post_type=post_type) # prune threadless posts and parentless have_threads = [post for post in posts if post.thread_id] if post_type == 'question': exportable = have_threads elif post_type == 'comment': exportable = [post for post in posts if post.parent_id] elif post_type == 'answer': exportable = posts # collect data per post: data = dict() for post in exportable: datum = { 'text': post.text, 'added_at': str(post.added_at), 'last_edited_at': str(post.last_edited_at), 'url': site_url(post.get_absolute_url()) } data[post] = datum return data
def akismet_check_spam(text, request): """Returns True if spam found, false if not, May raise exceptions if something is not right with the Akismet account/service/setup""" if not askbot_settings.USE_AKISMET: return False try: if askbot_settings.USE_AKISMET and askbot_settings.AKISMET_API_KEY == "": raise ImproperlyConfigured("You have not set AKISMET_API_KEY") data = { "user_ip": request.META.get("REMOTE_ADDR"), "user_agent": request.environ["HTTP_USER_AGENT"], "comment_author": smart_str(request.user.username), } if request.user.is_authenticated(): data.update({"comment_author_email": request.user.email}) api = Akismet( askbot_settings.AKISMET_API_KEY, smart_str(site_url(reverse("questions"))), "Askbot/%s" % get_version() ) return api.comment_check(text, data, build_data=False) except APIKeyError: logging.critical("Akismet Key is missing") except AkismetError: logging.critical("Akismet error: Invalid Akismet key or Akismet account issue!") except Exception, e: logging.critical((u"Akismet error: %s" % unicode(e)).encode("utf-8"))
def start(self, callback_url = None): """starts the OAuth protocol communication and saves request token as :attr:`request_token`""" if callback_url is None: callback_url = self.callback_url client = oauth.Client(self.consumer) request_url = self.parameters['request_token_url'] if callback_url: callback_url = site_url(callback_url) request_body = urllib.urlencode(dict(oauth_callback=callback_url)) self.request_token = self.send_request( client = client, url = request_url, method = 'POST', body = request_body ) else: self.request_token = self.send_request( client, request_url, 'GET' )
def akismet_check_spam(text, request): """Returns True if spam found, false if not, May raise exceptions if something is not right with the Akismet account/service/setup""" try: if askbot_settings.USE_AKISMET and askbot_settings.AKISMET_API_KEY == "": raise ImproperlyConfigured('You have not set AKISMET_API_KEY') data = {'user_ip': request.META.get('REMOTE_ADDR'), 'user_agent': request.environ['HTTP_USER_AGENT'], 'comment_author': smart_str(request.user.username) } if request.user.is_authenticated(): data.update({'comment_author_email': request.user.email}) api = Akismet( askbot_settings.AKISMET_API_KEY, smart_str(site_url(reverse('questions'))), "Askbot/%s" % get_version() ) return api.comment_check(text, data, build_data=False) except APIKeyError: logging.critical('Akismet Key is missing') except AkismetError: logging.critical('Akismet error: Invalid Akismet key or Akismet account issue!') except Exception, e: logging.critical((u'Akismet error: %s' % unicode(e)).encode('utf-8'))
def get_question_data(thread): """returns data dictionary for a given thread""" question_post = thread._question_post() datum = { 'added_at': get_epoch_str(thread.added_at), 'id': question_post.id, 'answer_count': thread.answer_count, 'answer_ids': thread.get_answer_ids(), 'view_count': thread.view_count, 'score': thread.score, 'last_activity_at': get_epoch_str(thread.last_activity_at), 'title': thread.title, 'summary': question_post.summary, 'tags': thread.tagnames.strip().split(), 'url': site_url(thread.get_absolute_url()), } datum['author'] = { 'id': thread._question_post().author.id, 'username': thread._question_post().author.username } datum['last_activity_by'] = { 'id': thread.last_activity_by.id, 'username': thread.last_activity_by.username } return datum
def wrapper(request, *args, **kwargs): if askbot_settings.USE_AKISMET and askbot_settings.AKISMET_API_KEY == "": raise ImproperlyConfigured('You have not set AKISMET_API_KEY') if askbot_settings.USE_AKISMET and request.method == "POST": comment = smart_str(request.POST[field]) data = { 'user_ip': request.META.get('REMOTE_ADDR'), 'user_agent': request.environ['HTTP_USER_AGENT'], 'comment_author': smart_str(request.user.username), } if request.user.is_authenticated(): data.update({'comment_author_email': request.user.email}) from akismet import Akismet api = Akismet(askbot_settings.AKISMET_API_KEY, smart_str(site_url(reverse('questions'))), "Askbot/%s" % get_version()) if api.comment_check(comment, data, build_data=False): logging.debug('Spam detected in %s post at: %s', request.user.username, datetime.datetime.now()) spam_message = _('Spam was detected on your post, sorry ' 'for if this is a mistake') if request.is_ajax(): return HttpResponseForbidden( spam_message, mimetype="application/json") else: request.user.message_set.create(message=spam_message) return HttpResponseRedirect(reverse('index')) return view_func(request, *args, **kwargs)
def wrapper(request, *args, **kwargs): if askbot_settings.USE_AKISMET and askbot_settings.AKISMET_API_KEY == "": raise ImproperlyConfigured('You have not set AKISMET_API_KEY') if askbot_settings.USE_AKISMET and request.method == "POST": comment = smart_str(request.POST[field]) data = {'user_ip': request.META.get('REMOTE_ADDR'), 'user_agent': request.environ['HTTP_USER_AGENT'], 'comment_author': smart_str(request.user.username), } if request.user.is_authenticated(): data.update({'comment_author_email': request.user.email}) from akismet import Akismet api = Akismet( askbot_settings.AKISMET_API_KEY, smart_str(site_url(reverse('questions'))), "Askbot/%s" % get_version() ) if api.comment_check(comment, data, build_data=False): logging.debug('Spam detected in %s post at: %s', request.user.username, timezone.now()) spam_message = _( 'Spam was detected on your post, sorry ' 'for if this is a mistake' ) if request.is_ajax(): return HttpResponseForbidden(spam_message, mimetype="application/json") else: # request.user.message_set.create(message=spam_message) django_messages.info(request, spam_message) return redirect('index') return view_func(request, *args, **kwargs)
def akismet_check_spam(text, request): """Returns True if spam found, false if not, May raise exceptions if something is not right with the Akismet account/service/setup""" if not askbot_settings.USE_AKISMET: return False try: if askbot_settings.USE_AKISMET and askbot_settings.AKISMET_API_KEY == "": raise ImproperlyConfigured('You have not set AKISMET_API_KEY') data = {'user_ip': request.META.get('REMOTE_ADDR'), 'user_agent': request.environ['HTTP_USER_AGENT'], 'comment_author': smart_str(request.user.username) } if request.user.is_authenticated(): data.update({'comment_author_email': request.user.email}) api = Akismet( askbot_settings.AKISMET_API_KEY, smart_str(site_url(reverse('questions'))), "Askbot/%s" % get_version() ) return api.comment_check(text, data, build_data=False) except APIKeyError: logging.critical('Akismet Key is missing') except AkismetError: logging.critical('Akismet error: Invalid Akismet key or Akismet account issue!') except Exception as e: logging.critical((u'Akismet error: %s' % unicode(e)).encode('utf-8')) return False
def get_question_data(thread): """returns data dictionary for a given thread""" question_post = thread._question_post() datum = { 'added_at': get_epoch_str(thread.added_at), 'id': question_post.id, 'answer_count': thread.answer_count, 'answer_ids': thread.get_answer_ids(), 'accepted_answer_id': thread.accepted_answer_id, 'view_count': thread.view_count, 'score': thread.score, 'last_activity_at': get_epoch_str(thread.last_activity_at), 'title': thread.title, 'summary': question_post.summary, 'tags': thread.tagnames.strip().split(), 'url': site_url(thread.get_absolute_url()), } datum['author'] = { 'id': thread._question_post().author.id, 'username': thread._question_post().author.username } datum['last_activity_by'] = { 'id': thread.last_activity_by.id, 'username': thread.last_activity_by.username } return datum
def get_sso_login_url(request, success_url): """Returns the redirect url for the discourse SSO login""" # Generate a random nonce. nonce = generate_random_key() # Save it temporarily so that you can verify it with returned nonce value discourse_login_data = { 'nonce': nonce, 'timestamp': time.time(), 'success_url': success_url } request.session['discourse_login'] = discourse_login_data # Create a new payload with nonce and return url # (where the Discourse will redirect user after verification). # Payload should look like: nonce=NONCE&return_sso_url=RETURN_URL return_url = site_url(reverse('user_complete_discourse_signin')) payload = 'nonce={}&return_sso_url={}'.format(nonce, return_url) # Base64 encode the above raw payload. -> BASE64_PAYLOAD base64_payload = base64.b64encode(payload) # URL encode the above BASE64_PAYLOAD. url_encoded_payload = urllib.quote(base64_payload) # Generate a HMAC-SHA256 signature from BASE64_PAYLOAD, lower case it -> HEX_SIGNATURE hex_signature = sign_payload(base64_payload) # Redirect the user to DISCOURSE_ROOT_URL/session/sso_provider?sso=URL_ENCODED_PAYLOAD&sig=HEX_SIGNATURE url_template = '{}/session/sso_provider?sso={}&sig={}' return url_template.format(askbot_settings.DISCOURSE_SITE_URL, url_encoded_payload, hex_signature)
def notify_admins_about_new_tags(tags=None, thread=None, user=None): thread_url = thread.get_absolute_url() return { 'thread_url': html_utils.site_url(thread_url), 'tags': tags, 'user': user }
def get_question_data(thread): """returns data dictionary for a given thread""" if thread.accepted_answer is not None: accepted = True else: accepted = False datum = { 'added_at': thread.added_at.strftime('%s'), 'id': thread._question_post().id, 'answer_count': thread.answer_count, 'view_count': thread.view_count, 'score': thread.score, 'last_activity_at': thread.last_activity_at.strftime('%s'), 'title': thread.title, 'tags': thread.tagnames.strip().split(), 'url': site_url(thread.get_absolute_url()), 'closed': thread.closed, 'accepted': accepted, } datum['author'] = { 'id': thread._question_post().author.id, 'username': thread._question_post().author.username } datum['last_activity_by'] = { 'id': thread.last_activity_by.id, 'username': thread.last_activity_by.username } return datum
def process_context(self, context): url_name = context['handler_url_name'] context.update({ 'site_name': askbot_settings.APP_SHORT_NAME, 'recipient_user': None, # needed for the Django template 'validation_link': site_url(reverse(url_name)) + '?validation_code=' + context['key'], }) return context
def process_context(self, context): context.update({ 'site_name': askbot_settings.APP_SHORT_NAME, 'recipient_user': None,#needed for the Django template 'validation_link': site_url(reverse('user_account_recover')) + \ '?validation_code=' + context['key'] }) return 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) #unhandled update_type 'post_shared' #user_action = _('%(user)s shared a %(post_link)s.') origin_post = post.get_origin_post() post_url = site_url(post.get_absolute_url()) 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) alt_reply_subject = urllib.quote( ('Re: ' + post.thread.title).encode('utf-8')) 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, '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_address': reply_address, 'alt_reply_address': alt_reply_address, 'alt_reply_subject': alt_reply_subject, 'is_multilingual': getattr(django_settings, 'ASKBOT_MULTILINGUAL', False), 'reply_sep_tpl': const.SIMPLE_REPLY_SEPARATOR_TEMPLATE }
def notify_admins_about_new_tags( tags = None, thread = None, user = None ): thread_url = thread.get_absolute_url() return { 'thread_url': html_utils.site_url(thread_url), 'tags': tags, 'user': user }
def send_email_alerts(self, user): #does not change the database, only sends the email #todo: move this to template user.add_missing_askbot_subscriptions() #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: return num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: threads = Thread.objects.filter(id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) question_count = len(q_list.keys()) items_added = 0 items_unreported = 0 questions_data = list() for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok break else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'], act_list) format_action_count('%(num)d ans', meta_data['new_ans'], act_list) format_action_count('%(num)d ans rev', meta_data['ans_rev'], act_list) questions_data.append({ 'url': site_url(q.get_absolute_url()), 'info': ', '.join(act_list), 'title': q.thread.title }) activate_language(user.get_primary_language()) email = BatchEmailAlert({ 'questions': questions_data, 'question_count': question_count, 'tag_summary': tag_summary, 'user': user }) if DEBUG_THIS_COMMAND == True: recipient_email = askbot_settings.ADMIN_EMAIL else: recipient_email = user.email email.send([recipient_email,])
def PROCESS(parts=None, reply_address_object=None, subject_line=None, from_address=None, **kwargs): """handler to process the emailed message and make a post to askbot based on the contents of the email, including the text body and the file attachments""" #1) get actual email content # todo: factor this out into the process_reply decorator reply_code = reply_address_object.address body_text, stored_files, signature = mail.process_parts( parts, reply_code, from_address) #2) process body text and email signature user = reply_address_object.user if signature != user.email_signature: user.email_signature = signature #3) validate email address and save user along with maybe new signature user.email_isvalid = True user.save() #todo: actually, saving is not necessary, if nothing changed #here we might be in danger of chomping off some of the #message is body text ends with a legitimate text coinciding with #the user's email signature body_text = user.strip_email_signature(body_text) #4) actually make an edit in the forum robj = reply_address_object add_post_actions = ('post_comment', 'post_answer', 'auto_answer_or_comment') if robj.reply_action == 'replace_content': robj.edit_post(body_text, title=subject_line) elif robj.reply_action == 'append_content': robj.edit_post(body_text) #in this case we don't touch the title elif robj.reply_action in add_post_actions: if robj.was_used: robj.edit_post(body_text, edit_response=True) else: robj.create_reply(body_text) elif robj.reply_action == 'validate_email': #todo: this is copy-paste - factor it out to askbot.mail.messages data = { 'site_name': askbot_settings.APP_SHORT_NAME, 'site_url': site_url(reverse('questions')), 'ask_address': 'ask@' + askbot_settings.REPLY_BY_EMAIL_HOSTNAME } template = get_template('email/re_welcome_lamson_on.html') mail.send_mail( subject_line=_('Re: %s') % subject_line, body_text=template.render(Context(data)), #todo: set lang recipient_list=[ from_address, ])
def handle(self, *args, **options): # pylint: disable=too-many-locals """Does the job of the command""" translation.activate(django_settings.LANGUAGE_CODE) uid, file_name = self.get_params(options) try: user = User.objects.get(pk=uid) except User.DoesNotExist: # pylint: disable=no-member raise CommandError('User with id {} does not exist'.format(uid)) lang_data = dict() for profile in user.localized_askbot_profiles.all(): lang = profile.language_code profile_url = user.get_absolute_url(language_code=lang) profile_data = {'about': profile.about, 'profile_url': site_url(profile_url)} lang_data[lang] = profile_data user_profile = {'localized_profiles': lang_data, 'date_of_birth': str(user.date_of_birth), 'username': user.username, 'profile_url': site_url(user.get_absolute_url()), 'email': user.email} data = {'user_profile': user_profile} question_data = self.get_question_data(user) data['questions'] = question_data.values() answer_data = self.get_post_data(user, 'answer') data['answers'] = answer_data.values() comment_data = self.get_post_data(user, 'comment') data['comments'] = comment_data.values() upfiles = self.get_upfiles(data) temp_dir = tempfile.mkdtemp() self.backup_upfiles_and_avatar(upfiles, user, temp_dir) self.save_json_file(data, temp_dir) self.zip_tempdir(temp_dir, file_name) shutil.rmtree(temp_dir)
def handle_noargs(self, **options): if askbot_settings.ENABLE_EMAIL_ALERTS == False: return if askbot_settings.ENABLE_ACCEPT_ANSWER_REMINDERS == False: return #get questions without answers, excluding closed and deleted #order it by descending added_at date schedule = ReminderSchedule( askbot_settings.DAYS_BEFORE_SENDING_ACCEPT_ANSWER_REMINDER, askbot_settings.ACCEPT_ANSWER_REMINDER_FREQUENCY, askbot_settings.MAX_ACCEPT_ANSWER_REMINDERS) questions = models.Post.objects.get_questions().exclude( deleted=True).added_between( start=schedule.start_cutoff_date, end=schedule.end_cutoff_date ).filter(thread__answer_count__gt=0).filter( thread__accepted_answer__isnull=True #answer_accepted = False ).order_by('-added_at') #for all users, excluding blocked #for each user, select a tag filtered subset #format the email reminder and send it for user in models.User.objects.exclude(status='b'): user_questions = questions.filter(author=user) final_question_list = user_questions.get_questions_needing_reminder( activity_type=const.TYPE_ACTIVITY_ACCEPT_ANSWER_REMINDER_SENT, user=user, recurrence_delay=schedule.recurrence_delay) #todo: rewrite using query set filter #may be a lot more efficient question_count = len(final_question_list) if question_count == 0: continue reminder_phrase = _('Please select the best responses to:') data = { 'site_url': site_url(''), #here we need only the domain name 'questions': final_question_list, 'reminder_phrase': reminder_phrase, 'recipient_user': user } template = get_template('email/accept_answer_reminder.html') body_text = template.render(Context(data)) #todo: set lang subject_line = askbot_settings.WORDS_ACCEPT_BEST_ANSWERS_FOR_YOUR_QUESTIONS if DEBUG_THIS_COMMAND: print "User: %s<br>\nSubject:%s<br>\nText: %s<br>\n" % \ (user.email, subject_line, body_text) else: mail.send_mail(subject_line=subject_line, body_text=body_text, recipient_list=(user.email, ))
def PROCESS( parts = None, reply_address_object = None, subject_line = None, from_address = None, **kwargs ): """handler to process the emailed message and make a post to askbot based on the contents of the email, including the text body and the file attachments""" #1) get actual email content # todo: factor this out into the process_reply decorator reply_code = reply_address_object.address body_text, stored_files, signature = mail.process_parts(parts, reply_code) #2) process body text and email signature user = reply_address_object.user if signature != user.email_signature: user.email_signature = signature #3) validate email address and save user along with maybe new signature user.email_isvalid = True user.save()#todo: actually, saving is not necessary, if nothing changed #here we might be in danger of chomping off some of the #message is body text ends with a legitimate text coinciding with #the user's email signature body_text = user.strip_email_signature(body_text) #4) actually make an edit in the forum robj = reply_address_object add_post_actions = ('post_comment', 'post_answer', 'auto_answer_or_comment') if robj.reply_action == 'replace_content': robj.edit_post(body_text, title = subject_line) elif robj.reply_action == 'append_content': robj.edit_post(body_text)#in this case we don't touch the title elif robj.reply_action in add_post_actions: if robj.was_used: robj.edit_post(body_text, edit_response = True) else: robj.create_reply(body_text) elif robj.reply_action == 'validate_email': #todo: this is copy-paste - factor it out to askbot.mail.messages data = { 'site_name': askbot_settings.APP_SHORT_NAME, 'site_url': site_url(reverse('questions')), 'ask_address': 'ask@' + askbot_settings.REPLY_BY_EMAIL_HOSTNAME } template = get_template('email/re_welcome_lamson_on.html') mail.send_mail( subject_line = _('Re: %s') % subject_line, body_text = template.render(Context(data)),#todo: set lang recipient_list = [from_address,] )
def create_topic_follow_action(thread, **kwargs): action = Action() action.text = "Follow the Topic : " + thread.title action.link = site_url(thread.get_absolute_url()) if "user" in kwargs: action.user = kwargs["user"] if "invite" in kwargs: action.invite = kwargs["invite"] action.save() return action
def process_context(self, context): user = context['recipient_user'] extra_data = { 'ask_address': 'ask@' + askbot_settings.REPLY_BY_EMAIL_HOSTNAME, 'can_post_by_email': user.can_post_by_email(), 'site_name': askbot_settings.APP_SHORT_NAME, 'site_url': site_url(reverse('questions')), } extra_data.update(context) return extra_data
def process_context(self, context): url_name = context["handler_url_name"] context.update( { "site_name": askbot_settings.APP_SHORT_NAME, "recipient_user": None, # needed for the Django template "validation_link": site_url(reverse(url_name)) + "?validation_code=" + context["key"], } ) return context
def get_oauth2_starter_url(provider_name, csrf_token): """returns redirect url for the oauth2 protocol for a given provider""" from sanction.client import Client providers = get_enabled_login_providers() params = providers[provider_name] client_id = getattr(askbot_settings, provider_name.replace("-", "_").upper() + "_KEY") redirect_uri = site_url(reverse("user_complete_oauth2_signin")) client = Client(auth_endpoint=params["auth_endpoint"], client_id=client_id, redirect_uri=redirect_uri) return client.auth_uri(state=csrf_token, **params.get("extra_auth_params", {}))
def process_context(self, context): user = context["recipient_user"] extra_data = { "ask_address": "ask@" + askbot_settings.REPLY_BY_EMAIL_HOSTNAME, "can_post_by_email": user.can_post_by_email(), "site_name": askbot_settings.APP_SHORT_NAME, "site_url": site_url(reverse("questions")), } extra_data.update(context) return extra_data
def get_oauth2_starter_url(provider_name, csrf_token): """returns redirect url for the oauth2 protocol for a given provider""" from requests_oauthlib.oauth2_session import OAuth2Session providers = get_enabled_login_providers() params = providers[provider_name] client_id = getattr(askbot_settings, format_setting_name(provider_name) + '_KEY') redirect_uri = site_url(reverse('user_complete_oauth2_signin')) session = OAuth2Session(client_id, redirect_uri=redirect_uri, state=csrf_token) url, csrf = session.authorization_url(params['auth_endpoint'], **params.get('extra_auth_params', {})) return url.encode('utf-8')
def get_oauth2_starter_url(provider_name, csrf_token): """returns redirect url for the oauth2 protocol for a given provider""" from sanction.client import Client providers = get_enabled_login_providers() params = providers[provider_name] client_id = getattr(askbot_settings, provider_name.upper() + '_KEY') redirect_uri = site_url(reverse('user_complete_oauth2_signin')) client = Client(auth_endpoint=params['auth_endpoint'], client_id=client_id, redirect_uri=redirect_uri) return client.auth_uri(state=csrf_token)
def test_api_v1_answer(self): user = self.create_user('user') question = self.post_question(user=user) answer = self.post_answer(user=user, question=question) response = self.client.get(reverse('api_v1_answer', kwargs={'answer_id': answer.id})) data = simplejson.loads(response.content) self.assertEqual(data['author']['id'], user.id) self.assertEqual(data['author']['username'], user.username) self.assertEqual(data['url'], site_url(answer.get_absolute_url())) self.assertEqual(data['added_at'], get_epoch_str(answer.added_at)) self.assertEqual(data['score'], answer.score) self.assertEqual(data['id'], answer.id) self.assertEqual(data['summary'], answer.summary)
def send_email_key(email, key, handler_url_name="user_account_recover"): """private function. sends email containing validation key to user's email address """ subject = _("Recover your %(site)s account") % {"site": askbot_settings.APP_SHORT_NAME} data = { "site_name": askbot_settings.APP_SHORT_NAME, "validation_link": site_url(reverse(handler_url_name)) + "?validation_code=" + key, } template = get_template("authopenid/email_validation.html") message = template.render(data) # todo: inject language preference send_mail(subject, message, django_settings.DEFAULT_FROM_EMAIL, [email])
def get_user_data(user): """get common data about the user""" avatar_url = user.get_avatar_url() if not ('gravatar.com' in avatar_url): avatar_url = site_url(avatar_url) return { 'id': user.id, 'avatar': avatar_url, 'username': user.username, 'joined_at': get_epoch_str(user.date_joined), 'last_seen_at': get_epoch_str(user.last_seen), 'reputation': user.reputation, }
def get_user_data(user): """get common data about the user""" avatar_url = user.get_avatar_url() if not ("gravatar.com" in avatar_url): avatar_url = site_url(avatar_url) return { "id": user.id, "avatar": avatar_url, "username": user.username, "joined_at": user.date_joined.strftime("%s"), "last_seen_at": user.last_seen.strftime("%s"), "reputation": user.reputation, }
def get_oauth2_starter_url(provider_name, csrf_token): """returns redirect url for the oauth2 protocol for a given provider""" from sanction.client import Client providers = get_enabled_login_providers() params = providers[provider_name] client_id = getattr(askbot_settings, format_setting_name(provider_name) + '_KEY') redirect_uri = site_url(reverse('user_complete_oauth2_signin')) client = Client( auth_endpoint=params['auth_endpoint'], client_id=client_id, redirect_uri=redirect_uri ) return client.auth_uri(state=csrf_token, **params.get('extra_auth_params', {}))
def VALIDATE_EMAIL( parts = None, reply_address_object = None, from_address = None, **kwargs ): """process the validation email and save the email signature todo: go a step further and """ reply_code = reply_address_object.address if DEBUG_EMAIL: msg = u'Received email validation from %s\n' % from_address sys.stderr.write(msg.encode('utf-8')) try: content, stored_files, signature = mail.process_parts(parts, reply_code) user = reply_address_object.user if signature != user.email_signature: user.email_signature = signature user.email_isvalid = True user.save() data = { 'ask_address': 'ask@' + askbot_settings.REPLY_BY_EMAIL_HOSTNAME, 'can_post_by_email': user.can_post_by_email(), 'recipient_user': user, 'site_name': askbot_settings.APP_SHORT_NAME, 'site_url': site_url(reverse('questions')), } template = get_template('email/re_welcome_lamson_on.html') mail.send_mail( subject_line = _('Re: Welcome to %(site_name)s') % data, body_text = template.render(Context(data)),#todo: set lang recipient_list = [from_address,] ) except ValueError: raise ValueError( _( 'Please reply to the welcome email ' 'without editing it' ) )
def get_question_data(thread): """returns data dictionary for a given thread""" datum = { "added_at": thread.added_at.strftime("%s"), "id": thread._question_post().id, "answer_count": thread.answer_count, "view_count": thread.view_count, "score": thread.score, "last_activity_at": thread.last_activity_at.strftime("%s"), "title": thread.title, "tags": thread.tagnames.strip().split(), "url": site_url(thread.get_absolute_url()), } datum["author"] = {"id": thread._question_post().author.id, "username": thread._question_post().author.username} datum["last_activity_by"] = {"id": thread.last_activity_by.id, "username": thread.last_activity_by.username} return datum
def VALIDATE_EMAIL( parts = None, reply_address_object = None, from_address = None, **kwargs ): """process the validation email and save the email signature todo: go a step further and """ reply_code = reply_address_object.address if DEBUG_EMAIL: msg = u'Received email validation from %s\n' % from_address sys.stderr.write(msg.encode('utf-8')) try: content, stored_files, signature = mail.process_parts(parts, reply_code) user = reply_address_object.user if signature != user.email_signature: user.email_signature = signature user.email_isvalid = True user.save() data = { 'site_name': askbot_settings.APP_SHORT_NAME, 'site_url': site_url(reverse('questions')), 'ask_address': 'ask@' + askbot_settings.REPLY_BY_EMAIL_HOSTNAME, 'can_post_by_email': user.can_post_by_email() } template = get_template('email/re_welcome_lamson_on.html') mail.send_mail( subject_line = _('Re: Welcome to %(site_name)s') % data, body_text = template.render(Context(data)),#todo: set lang recipient_list = [from_address,] ) except ValueError: raise ValueError( _( 'Please reply to the welcome email ' 'without editing it' ) )
def complete_oauth2_signin(request): if "next_url" in request.session: next_url = request.session["next_url"] del request.session["next_url"] else: next_url = reverse("index") if "error" in request.GET: return HttpResponseRedirect(reverse("index")) csrf_token = request.GET.get("state", None) if csrf_token is None or csrf_token != request.session.pop("oauth2_csrf_token"): return HttpResponseBadRequest() providers = util.get_enabled_login_providers() provider_name = request.session.pop("provider_name") params = providers[provider_name] assert params["type"] == "oauth2" client_id = getattr(askbot_settings, provider_name.upper() + "_KEY") client_secret = getattr(askbot_settings, provider_name.upper() + "_SECRET") client = OAuth2Client( token_endpoint=params["token_endpoint"], resource_endpoint=params["resource_endpoint"], redirect_uri=site_url(reverse("user_complete_oauth2_signin")), client_id=client_id, client_secret=client_secret, ) client.request_token(code=request.GET["code"], parser=params["response_parser"]) # todo: possibly set additional parameters here user_id = params["get_user_id_function"](client) user = authenticate(oauth_user_id=user_id, provider_name=provider_name, method="oauth") logging.debug("finalizing oauth signin") request.session["email"] = "" # todo: pull from profile request.session["username"] = "" # todo: pull from profile return finalize_generic_signin( request=request, user=user, user_identifier=user_id, login_provider_name=provider_name, redirect_url=next_url )
def get_oauth2_starter_url(provider_name, csrf_token): """returns redirect url for the oauth2 protocol for a given provider""" from sanction.client import Client providers = get_enabled_login_providers() params = providers[provider_name] client_id = getattr(askbot_settings, provider_name.upper() + '_KEY') redirect_uri = site_url(reverse('user_complete_oauth2_signin')) #qq = redirect_uri.split(':') #nurl = qq[0]+':'+qq[1]+qq[2][qq[2].find('/'):] #redirect_uri=nurl client = Client( auth_endpoint=params['auth_endpoint'], client_id=client_id, redirect_uri=redirect_uri ) return client.auth_uri(state=csrf_token)
def get_user_data(user_obj): """get common data about the user""" avatar_url = user_obj.get_avatar_url() if 'gravatar.com' not in avatar_url: avatar_url = site_url(avatar_url) return { 'id': user_obj.id, 'avatar': avatar_url, 'username': user_obj.username, 'joined_at': get_epoch_str(user_obj.date_joined), 'last_seen_at': get_epoch_str(user_obj.last_seen), 'reputation': user_obj.reputation, 'gold': user_obj.gold, 'silver': user_obj.silver, 'bronze': user_obj.bronze, }
def start(self, callback_url=None): """starts the OAuth protocol communication and saves request token as :attr:`request_token`""" client = oauth.Client(self.consumer) request_url = self.parameters['request_token_url'] params = dict() if self.parameters.get('callback_is_oob', False): params['oauth_callback'] = 'oob' #callback_url else: params['oauth_callback'] = site_url(callback_url) self.request_token = self.send_request(client=client, url=request_url, method='POST', params=params)
def get_answer_data(post): """returns data dictionary for a given answer post""" datum = { 'added_at': get_epoch_str(post.added_at), 'id': post.id, 'score': post.score, 'summary': post.summary, 'url': site_url(post.get_absolute_url()), } datum['author'] = get_user_id_info(post.author) if post.last_edited_at: datum['last_edited_at'] = get_epoch_str(post.last_edited_at) if post.last_edited_by: datum['last_edited_by'] = get_user_id_info(post.last_edited_by) return datum
def add_email_to_topic(request): data = json.loads(request.body) try: post = models.Post.objects.filter( post_type='question', id=data["threadId"] ).select_related('thread')[0] except IndexError: # Handle URL mapping - from old Q/A/C/ URLs to the new one try: post = models.Post.objects.filter( post_type='question', old_question_id=data["threadId"] ).select_related('thread')[0] except IndexError: raise Http404 try: user = User.objects.get(email=data['email']) except User.DoesNotExist: user = None if user: action = Action.create_topic_follow_action(post.thread, user=user) from askbot.mail.messages import ActionEmail email = ActionEmail({ 'action_text': action.text, 'user': user, "link": action.link }) email.send([user.email, ]) return HttpResponse() invite = Invite.create_invite(data['email']) action = Action.create_topic_follow_action(post.thread, invite=invite) from askbot.mail.messages import InviteUserEmail email = InviteUserEmail({ 'action_text': action.text, 'user': user, "invite_url": site_url("/account/signup/?invite_code=" + invite.invite_code) }) email.send([invite.email, ]) return HttpResponse()
def start(self, callback_url=None): """starts the OAuth protocol communication and saves request token as :attr:`request_token`""" client = oauth.Client(self.consumer) request_url = self.parameters['request_token_url'] params = dict() if self.parameters.get('callback_is_oob', False): params['oauth_callback'] = 'oob' #callback_url else: params['oauth_callback'] = site_url(callback_url) self.request_token = self.send_request( client=client, url=request_url, method='POST', params=params )
def call_akismet(text, request=None, author=None, ip_addr=None, user_agent=None, command='check_spam'): """Calls akismet apy with a command. Supports commands 'check_spam', 'submit_spam' and 'submit_ham' """ if not askbot_settings.USE_AKISMET: return False try: if askbot_settings.AKISMET_API_KEY.strip() == "": raise ImproperlyConfigured('You have not set AKISMET_API_KEY') data = {'comment_content': text} user = get_user(author, request) username = get_user_param(user, 'username') if username: data['comment_author'] = smart_str(username) email = get_user_param(user, 'email') if email: data['comment_author_email'] = email api = Akismet(key=askbot_settings.AKISMET_API_KEY, blog_url=smart_str(site_url(reverse('questions')))) user_ip = ip_addr or request.META.get('REMOTE_ADDR') user_agent = user_agent or request.environ['HTTP_USER_AGENT'] if command == 'check_spam': return api.comment_check(user_ip, user_agent, **data) elif command == 'submit_spam': return api.submit_spam(user_ip, user_agent, **data) elif command == 'submit_ham': return api.submit_ham(user_ip, user_agent, **data) else: raise RuntimeError('unknown akismet method: "{}"'.format(command)) return api.comment_check(user_ip, user_agent, **data) except APIKeyError: logging.critical('Akismet Key is missing') except AkismetError: logging.critical('Akismet error: Invalid Akismet key or Akismet account issue!') except Exception as e: logging.critical((u'Akismet error: %s' % unicode(e)).encode('utf-8')) return False
def test_command(self): # create user today = date.today() # create user & fill out profile user = User.objects.create(username='******', email='*****@*****.**') profile = UserProfile(auth_user_ptr=user, date_of_birth=today) profile.save() lang1 = 'en' lang2 = 'es' localized_profile1 = LocalizedUserProfile(auth_user=user, language_code=lang1, about='about me') localized_profile1.save() localized_profile2 = LocalizedUserProfile(auth_user=user, language_code=lang2, about='sobre mi') localized_profile2.save() # put three upfiles in place paths = list() for idx in range(1, 4): path = self.put_upfile('file{}.txt'.format(idx)) paths.append(path) # post question with an image text_tpl = 'hello there ![image]({} "Image {}")' url = self.get_upfile_url_from_path(paths[0]) question_text = text_tpl.format(url, 1) question = user.post_question(title='question', body_text=question_text, tags='one two') # post answer with an image url = self.get_upfile_url_from_path(paths[1]) answer_text = text_tpl.format(url, 2) answer = user.post_answer(question, answer_text) # post comment with an image url = self.get_upfile_url_from_path(paths[2]) comment_text = text_tpl.format(url, 3) comment = user.post_comment(answer, comment_text) # run extract data command into a temp dir askbot_dir = askbot.get_install_directory() test_dir = os.path.join(askbot_dir, 'tests', 'temp_export_user_data') if os.path.isdir(test_dir): shutil.rmtree(test_dir) os.makedirs(test_dir) backup_file = os.path.join(test_dir, 'backup.zip') management.call_command('askbot_export_user_data', user_id=user.pk, file_name=backup_file) # test: unzip the file zip_file = zipfile.ZipFile(backup_file, 'r') extract_dir = os.path.join(test_dir, 'extracted') zip_file.extractall(extract_dir) json_file = os.path.join(extract_dir, 'data.json') self.assertTrue(os.path.isfile(json_file)) # test: load json with open(json_file) as f: json_data = json.loads(f.read()) # test: validate question q_data = json_data['questions'][0] thread = question.thread self.assertEqual(q_data['title'], thread.title) self.assertEqual(q_data['tags'], thread.tagnames) self.assertEqual(q_data['text'], question.text) self.assertEqual(q_data['added_at'], str(question.added_at)) self.assertEqual(q_data['last_edited_at'], str(question.last_edited_at)) question_url = site_url(question.get_absolute_url()) self.assertEqual(q_data['url'], question_url) # test: validate answer, just check it's there self.assertEqual(len(json_data['answers']), 1) # test: validate comment self.assertEqual(len(json_data['comments']), 1) # test: validate user profile data user_data = json_data['user_profile'] self.assertEqual(user_data['username'], user.username) lang_data = user_data['localized_profiles'] profile_url_tpl = site_url('/{}/users/{}/bob/') self.assertEqual(lang_data[lang1]['about'], 'about me') lang1_url = profile_url_tpl.format('en', user.pk) self.assertEqual(lang_data[lang1]['profile_url'], lang1_url) self.assertEqual(lang_data[lang2]['about'], 'sobre mi') lang2_url = profile_url_tpl.format('es', user.pk) self.assertEqual(lang_data[lang2]['profile_url'], lang2_url) self.assertEqual(user_data['email'], user.email) self.assertEqual(user_data['date_of_birth'], str(today)) # test: verify that uploaded files are there upfile_names = [os.path.basename(path) for path in paths] for name in upfile_names: extracted_path = os.path.join(extract_dir, 'upfiles', name) self.assertTrue(os.path.isfile(extracted_path)) shutil.rmtree(test_dir)
def link(self): return site_url(reverse('questions'))
def item_link(self, item): """get full url to the item """ return site_url(item.get_absolute_url())
def item_guid(self, item): """returns url without the slug because the slug can change """ return site_url(item.get_absolute_url(no_slug=True))