Source code for openassembly.oa_verification.templatetags.verificationtags

from django import template
from django import forms
from django.http import HttpResponseRedirect
import datetime
from django.contrib.contenttypes.models import ContentType

from oa_verification.models import EmailVerification
import datetime, random, sha
from django.core.mail import send_mail

from oa_verification.models import ActionTaken

from pirate_topics.models import MyGroup

from settings import DOMAIN_NAME, EMAIL_HOST_USER

from pirate_permissions.models import PermissionsGroup, Permission

from pirate_core import HttpRedirectException, namespace_get, FormMixin

from pirate_signals.models import aso_rep_event, notification_send, relationship_event


from django.contrib.auth.models import User
from pirate_sources.models import IMGSource
from oa_verification.models import arpv, PhotoVerificationTask, PhotoUserVerifications, Referral
from oa_verification.forms import arpvForm, ReferralForm
from pirate_core.widgets import HorizRadioRenderer
from collections import defaultdict

from customtags.decorators import block_decorator
register = template.Library()
block = block_decorator(register)

get_namespace = namespace_get('oa_ver')


[docs]class ActionTakenForm(forms.ModelForm):
[docs] def save(self, commit=True): new_source = super(ActionTakenForm, self).save(commit=commit) return new_source
[docs] class Meta: model = ActionTaken exclude = ('user', 'content_object','object_pk','content_type')
form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_actiontaken_form")
@block
[docs]def oa_actiontaken_form(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) POST = kwargs.get('POST', None) obj = kwargs.get('object', None) user = kwargs.get('user', None) content_type = ContentType.objects.get_for_model(obj) path = 'detail.html' + "?_t=" + str(content_type.pk) + "&_o=" + str(obj.pk) if POST: form = ActionTakenForm(POST) if form.is_valid(): newobj = form.save(commit=False) newobj.user = user newobj.content_type = content_type newobj.object_pk = obj.pk newobj.save() notification_send.send(sender=newobj, obj=newobj, reply_to=obj) relationship_event.send(sender=newobj, obj=newobj, parent=obj) #raise HttpRedirectException(HttpResponseRedirect(path)) else: namespace['errors'] = form.errors form = ActionTakenForm() namespace['form'] = form output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_get_actiontaken(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) obj = kwargs.get('object', None) try: obj = ActionTaken.objects.get(object_pk=obj.pk) action_taken = True namespace['url'] = obj.url try: namespace['verb'] = obj.verb except: namespace['verb'] = "Action Taken" except: action_taken = False namespace['has_action_taken'] = action_taken output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_get_verifications(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) user = kwargs.get('user', None) try: obj = PhotoUserVerifications.objects.get(user=user) namespace['count'] = obj.verifications except: namespace['count'] = 0 try: ref = Referral.objects.get(accepted_user=user) namespace['count'] += 1 except: pass output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_get_referral(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) key = kwargs.get('key', None) try: ref = Referral.objects.get(key=key) except: ref = None namespace['referral'] = ref output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_activate_referral(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) key = kwargs.get('key', None) user = kwargs.get('user', None) try: ref = Referral.objects.get(key=key) if ref.email == user.email or user.email.lower() == ref.email.lower(): ref.referred_user = user ref.accepted_dt = datetime.datetime.now() ref.accepted = True ref.save() if ref.topic is not None: myg = MyGroup.objects.get_or_create(topic=ref.topic, user=user) else: namespace['errors'] = 'Email not associated with this account. <br> Log into account associated with <i>' + str(ref.email) + ' </i>and try again.' except: ref = None namespace['referral'] = ref output = nodelist.render(context) context.pop() return output
[docs]class FacilitatorsForm(forms.Form): form_id = forms.CharField(widget=forms.HiddenInput(), initial="oa_facilitators_form") username = forms.CharField(max_length=300)
@block
[docs]def oa_facilitators_form(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) new_topic = kwargs.get('object', None) POST = kwargs.get('POST', None) if POST is not None and POST.get("form_id") == "oa_facilitators_form": form = FacilitatorsForm(POST) if form.is_valid(): try: user = User.objects.get(username=form.cleaned_data['username']) ctype = ContentType.objects.get_for_model(new_topic) #create Facilitator permissions for group creator perm_group, is_new = PermissionsGroup.objects.get_or_create(name="Facilitator", description="Permission group for Facilitation of Online Working Groups") perm, newperm = Permission.objects.get_or_create(user=user, name='facilitator-permission', content_type=ctype, object_pk=new_topic.pk, permissions_group=perm_group, component_membership_required=True) mg, newgr = MyGroup.objects.get_or_create(topic=new_topic, user=user) if is_new: namespace['done'] = form.cleaned_data['username'] + ' added' else: namespace['done'] = form.cleaned_data['username'] + ' already facilitator' except: namespace['error'] = 'Account with login name "' + str(form.cleaned_data['username']) + '" not Found' else: namespace['errors'] = form.errors else: form = FacilitatorsForm() namespace['form'] = form output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_referral_form(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) user = kwargs.get('user', None) POST = kwargs.get('POST', None) obj = kwargs.get('object', None) namespace['errors'] = [] sent = 0 if POST and POST.get("form_id") == "oa_referral_form": form = ReferralForm(POST) if form.is_valid(): email = form.cleaned_data['email'] email_list = email.replace(' ', '').split(',') for email in email_list: try: ref = Referral.objects.get(email=email, topic=obj) namespace['errors'].append('Referral Key Already Used for this group and email: ' + str(email)) except: #create referral salt = sha.new(str(random.random())).hexdigest()[:5] activation_key = sha.new(salt + user.username).hexdigest() ref = Referral(topic=obj, user=user, created_dt=datetime.datetime.now(), key=activation_key, email=email, accepted=False) ref.save() #send referral email email_subject = 'OpenAssembly Referral' if obj: email_subject += " to Group " + str(obj.shortname) email_body = "You've been referred to OpenAssembly by %s. \n\nTo join as a verified user:\n\n%sp/register/d-%s" % ( user.username, DOMAIN_NAME, ref.key) send_mail(email_subject, email_body, 'fragro@gmail.com', [email]) sent += 1 namespace['errors'].append("Mail sent to " + str(sent) + " recipients") else: namespace['errors'].append(form.errors) else: form = ReferralForm() namespace['form'] = form output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_ver_form(context, nodelist, *args, **kwargs): '''form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_arpv_form") This block tag creates instances of anonymous photo verification tags, and makes sure that the users exist, they are not the same, and Usage is as follows: {% pp_arpv_form POST=request.POST user=request.user%} Do stuff with {{ pp_arpv.form }}. {% endpp_arpv_form%} ''' context.push() namespace = get_namespace(context) user = kwargs.get('user', None) POST = kwargs.get('POST', None) FILE = kwargs.get('FILE', None) ctype = ContentType.objects.get_for_model(user) if POST: form = arpvForm(POST, FILE) if form.is_valid(): try: userobj1 = User.objects.get(username=form.cleaned_data.get('user1')) test1 = True except: test1 = False try: userobj2 = User.objects.get(username=form.cleaned_data.get('user2')) test2 = True except: test2 = False if userobj1 == userobj2: namespace['errors'] = 'The users are the same' elif not test1: namespace['errors'] = 'User1 does not Exist' elif not test2: namespace['errors'] = 'User2 does not Exist' elif not test1 and not test2: namespace['errors'] = 'Neither User Exists' else: photo = form.cleaned_data['photo'] temp = arpv(user1=userobj1, user2=userobj2, photo=photo) temp.submit_user = user #if the submit user is one of the photo users, this should be normal if temp.submit_user == userobj1: temp.user1Confirm = True elif temp.submit_user == userobj2: temp.user2Confirm = True temp.created_dt = datetime.datetime.now() temp.save() #now that we have saved the arpv, send out notifications for confirmation if not temp.user1Confirm: link = temp.get_absolute_url() text = 'Click Here to Confirm a Photo of You from ' + str(user.username) notification_send.send(sender=temp, obj=user, reply_to=userobj1, link=link, text=text) if not temp.user2Confirm: link = temp.get_absolute_url() text = 'Click Here to Confirm a Photo of You from ' + str(user.username) notification_send.send(sender=temp, obj=user, reply_to=userobj2, link=link, text=text) #raise HttpRedirectException(HttpResponseRedirect(returnurl)) form = arpvForm() if user is not None: arpvs = arpv.objects.filter(submit_user=user) namespace['photo_ids'] = [i.photo.pk for i in arpvs] form.fields['photo'].queryset = IMGSource.objects.filter(object_pk=user.pk, content_type=ctype) namespace['arpvs'] = arpvs namespace['form'] = form else: namespace['errors'] = 'Invalid Entry. Make Sure You Have Selected a Photo and 2 Users' form = arpvForm() form.fields['photo'].queryset = IMGSource.objects.filter(object_pk=user.pk, content_type=ctype) else: #if user is not None: form = arpvForm() form.fields['photo'].queryset = IMGSource.objects.filter(object_pk=user.pk, content_type=ctype) namespace['form'] = form output = nodelist.render(context) context.pop() return output
CHOICES = ( (1, 'YES'), (0, 'NO') )
[docs]class ARPVConfirmForm(forms.Form): choose = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
@block
[docs]def oa_ver_confirm_form(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) user = kwargs.get('user', None) val = kwargs.get('arpv', None) POST = kwargs.get('POST', None) if POST is not None and POST.get("form_id") == "oa_arpv_task_form": form = ARPVConfirmForm(POST) if form.is_valid(): #set the appropriate user as confirmed choice = form.cleaned_data['choose'] if choice == '1': if user == val.user1: val.user1Confirm = True elif user == val.user2: val.user2Confirm = True val.save() if val.user1Confirm and val.user2Confirm: create_task(val, val.user1) create_task(val, val.user2) raise HttpRedirectException(HttpResponseRedirect('arpv_thanks.html')) elif choice == '0': raise HttpRedirectException(HttpResponseRedirect('arpv_flag.html')) else: namespace['errors'] = form.errors else: form = ARPVConfirmForm() namespace['form'] = form output = nodelist.render(context) context.pop() return output
[docs]def create_task(val, user): #creates photo verification tasks for each pair of photos old_arpvs1 = arpv.objects.filter(user1=user).exclude(pk=val.pk) old_arpvs2 = arpv.objects.filter(user2=user).exclude(pk=val.pk) create = datetime.datetime.now() for i in list(old_arpvs1) + list(old_arpvs2): try: #if the mirror of this task has already been created old_task = PhotoVerificationTask.objects.get(pv1=val, pv2=i, user1=val.user1, user2=val.user2, user3=i.user1, user4=i.user2) except: #the mirror doesn't exist, get or create task new_task, is_new = PhotoVerificationTask.objects.get_or_create(pv1=i, pv2=val, user1=i.user1, user2=i.user2, user3=val.user1, user4=val.user2, created_dt=create) if is_new: new_task.save()
@block
[docs]def oa_ver_task(context, nodelist, *args, **kwargs): ''' This form checks to see if the user has permission to perform this task, then if so provide task form. If user responds, we save the task as verified and complete and normalize out the verification to the users and photos themselves. ''' context.push() namespace = get_namespace(context) user = kwargs.get('user', None) POST = kwargs.get('POST', None) task = kwargs.get('task', None) if user.is_authenticated() and user.is_staff: #for now only expose task to staff if POST and task is not None: form = ARPVConfirmForm(POST) if form.is_valid(): choice = form.cleaned_data['choose'] if choice == '1': task.complete = True task.verification = True task.verified_dt = datetime.datetime.now() task.verified_by = user #normalize verifications to each photo #ERR: for some reason we cannot pickle get_user? #deferred.defer(normalize, task, _countdown=60) normalize(task) elif choice == '0': task.complete = True task.verification = False task.verified_dt = datetime.datetime.now() task.verified_by = user task.save() #form = ARPVConfirmForm() namespace['form_complete'] = 'Verification Complete. Thankyou.' #raise HttpRedirectException(HttpResponseRedirect('arpv_task.html')) else: namespace['errors'] = form.errors else: form = ARPVConfirmForm() namespace['form'] = form output = nodelist.render(context) context.pop() return output
[docs]def normalize(task): #normalizes our verification as a background task task.pv1.verifications += 1 task.pv2.verifications += 1 #normalize to user d = defaultdict(int) for u in (task.user1, task.user2, task.user3, task.user4): d[str(u.username)] += 1 for k, v in d.items(): if v == 2: u = User.objects.get(username=k) val, is_new = PhotoUserVerifications.objects.get_or_create(user=u) val.verifications += 1 val.save() task.pv1.save() task.pv2.save()
@block
[docs]def oa_get_arpvs(context, nodelist, *args, **kwargs): '''form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_arpv_form") This block tag creates instances of anonymous photo verification tags, and makes sure that the users exist, they are not the same, and Usage is as follows: {% oa_get_arpvs user=request.user%} Do stuff with {{ oa_arpv.arpvs }}. {% endoa_get_arpvs %} ''' context.push() namespace = get_namespace(context) user = kwargs.get('user', None) arpv_img = kwargs.get('img', None) if user is not None: arpvs = arpv.objects.filter(submit_user=user) if arpv_img is not None: arpvs = arpv.objects.filter(photo=arpv_img) used_photos = [i.photo.pk for i in arpvs] namespace['arpvs'] = arpvs namespace['count'] = arpvs.count() namespace['photo_ids'] = used_photos output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_get_users(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) users = User.objects.all() namespace['users'] = users output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_get_task_count(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) tasks = PhotoVerificationTask.objects.filter(complete=False) count = tasks.count() #if this user is in either photo, he can't do the task namespace['count'] = count output = nodelist.render(context) context.pop() return output
@block
[docs]def oa_get_task(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) user = kwargs.get('user', None) tasks = PhotoVerificationTask.objects.filter(complete=False) count = tasks.count() #if this user is in either photo, he can't do the task tasks = tasks.order_by('-created_dt') try: for itr in range(count): task = tasks[itr] #check if user is eligible for task if is_eligible(task, user): namespace['task'] = task break except: namespace['errors'] = 'Sorry, Tasks unavailable: ' + str(tasks.count()) + ' tasks.' output = nodelist.render(context) context.pop() return output
[docs]def is_eligible(t, u): if u != t.user1 and u != t.user2 and u != t.user3 and u != t.user4: return True else: return False