def donate(request, event): event = viewutil.get_event(event) if event.locked: raise Http404 commentform, bidsform, prizesform = process_form(request, event) if not bidsform: # redirect return commentform def bid_parent_info(bid): if bid != None: return {'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent)} else: return None def bid_info(bid): result = { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name if bid.suggestions.exists(): result['suggested'] = list( map(lambda x: x.name, bid.suggestions.all())) if bid.allowuseroptions: result['custom'] = ['custom'] result['label'] += ' (select and add a name next to "New Option Name")' return result bids = filters.run_model_query('bidtarget', {'state': 'OPENED', 'event': event.id}, user=request.user).distinct( ).select_related('parent').prefetch_related('suggestions') allPrizes = filters.run_model_query( 'prize', {'feed': 'current', 'event': event.id}) prizes = allPrizes.filter(ticketdraw=False) dumpArray = [bid_info(o) for o in bids] bidsJson = json.dumps(dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) ticketPrizes = allPrizes.filter(ticketdraw=True) def prize_info(prize): result = {'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'maximumbid': prize.maximumbid, 'sumdonations': prize.sumdonations} return result dumpArray = [prize_info(o) for o in ticketPrizes.all()] ticketPrizesJson = json.dumps( dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) return views_common.tracker_response(request, "tracker/donate.html", {'event': event, 'bidsform': bidsform, 'prizesform': prizesform, 'commentform': commentform, 'hasBids': bids.count() > 0, 'bidsJson': bidsJson, 'hasTicketPrizes': ticketPrizes.count() > 0, 'ticketPrizesJson': ticketPrizesJson, 'prizes': prizes})
def index(request, event=None): event = viewutil.get_event(event) eventParams = {} if event.id: eventParams['event'] = event.id agg = filters.run_model_query('donation', eventParams, user=request.user, mode='user').aggregate(amount=Sum('amount'), count=Count('amount'), max=Max('amount'), avg=Avg('amount')) agg['target'] = event.targetamount count = { 'runs': filters.run_model_query('run', eventParams, user=request.user).count(), 'prizes': filters.run_model_query('prize', eventParams, user=request.user).count(), 'bids': filters.run_model_query('bid', eventParams, user=request.user).count(), 'donors': filters.run_model_query( 'donorcache', eventParams, user=request.user).values('donor').distinct().count(), } if 'json' in request.GET: return HttpResponse(json.dumps({ 'count': count, 'agg': agg }, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder), content_type='application/json;charset=utf-8') elif 'jsonp' in request.GET: callback = request.GET['jsonp'] return HttpResponse( '%s(%s);' % (callback, json.dumps({ 'count': count, 'agg': agg }, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder)), content_type='text/javascript;charset=utf-8') return views_common.tracker_response(request, 'tracker/index.html', { 'agg': agg, 'count': count, 'event': event })
def user_index(request): eventSet = {} for futureEvent in filters.run_model_query('event', {'feed': 'future'}): if not futureEvent.locked: eventDict = eventSet.setdefault( futureEvent, {'event': futureEvent}) eventDict['submission'] = futureEvent for prize in models.Prize.objects.filter(handler=request.user): eventDict = eventSet.setdefault(prize.event, {'event': prize.event}) prizeList = eventDict.setdefault('prizes', []) prizeList.append(prize) eventList = [] for key, value in eventSet.iteritems(): value['eventname'] = value['event'].name value['eventid'] = value['event'].id value.setdefault('submission', False) eventList.append(value) eventList.sort(key=lambda x: x['event'].date) return views_common.tracker_response(request, "tracker/user_index.html", {'eventList': eventList, })
def get(self, request, event, *args, **kwargs): # Get the upcoming bids and their options + totals. event = viewutil.get_event(event) now = timezone.now() params = { 'event': event.id, 'state': 'OPENED', } bids = filters.run_model_query( 'bid', params).filter(speedrun__endtime__gte=now).select_related( 'speedrun').prefetch_related('options') results = [] for bid in bids: result = { 'game': bid.speedrun.name, 'bid': bid.name, 'goal': bid.goal, 'amount_raised': bid.total, 'options': [], } for option in bid.options.all(): result['options'].append({ 'name': option.name, 'amount_raised': option.total, }) result['amount_raised'] += option.total results.append(result) return JsonResponse({'results': results})
def submit_prize(request, event): event = viewutil.get_event(event) if request.method == 'POST': prizeForm = forms.PrizeSubmissionForm(data=request.POST) if prizeForm.is_valid(): prize = prizeForm.save(event, request.user) return views_common.tracker_response( request, "tracker/submit_prize_success.html", {'prize': prize}) else: prizeForm = forms.PrizeSubmissionForm() runs = filters.run_model_query('run', {'event': event}, request.user) def run_info(run): return { 'id': run.id, 'name': run.name, 'description': run.description, 'runners': run.deprecated_runners, 'starttime': run.starttime.isoformat(), 'endtime': run.endtime.isoformat() } dumpArray = [run_info(o) for o in runs.all()] runsJson = json.dumps(dumpArray) return views_common.tracker_response(request, "tracker/submit_prize.html", { 'event': event, 'form': prizeForm, 'runs': runsJson })
def user_index(request): eventSet = {} for futureEvent in filters.run_model_query('event', {'feed': 'future'}): if not futureEvent.locked: eventDict = eventSet.setdefault(futureEvent, {'event': futureEvent}) eventDict['submission'] = futureEvent for prize in models.Prize.objects.filter(handler=request.user): eventDict = eventSet.setdefault(prize.event, {'event': prize.event}) prizeList = eventDict.setdefault('prizes', []) prizeList.append(prize) eventList = [] for key, value in eventSet.iteritems(): value['eventname'] = value['event'].name value['eventid'] = value['event'].id value.setdefault('submission', False) eventList.append(value) eventList.sort(key=lambda x: x['event'].date) return views_common.tracker_response(request, "tracker/user_index.html", { 'eventList': eventList, })
def bidindex(request, event=None): event = viewutil.get_event(event) searchForm = BidSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid filter form', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id else: return HttpResponseRedirect(reverse('tracker.views.bidindex', args=(Event.objects.latest().id,))) bids = filters.run_model_query('bid', searchParams, user=request.user) bids = bids.filter(parent=None) total = bids.aggregate(Sum('total'))['total__sum'] or Decimal('0.00') choiceTotal = bids.filter(goal=None).aggregate(Sum('total'))['total__sum'] or Decimal('0.00') challengeTotal = bids.exclude(goal=None).aggregate(Sum('total'))['total__sum'] or Decimal('0.00') bids = viewutil.get_tree_queryset_descendants(Bid, bids, include_self=True).prefetch_related('options') bids = bids.filter(parent=None) if event.id: bidNameSpan = 2 else: bidNameSpan = 1 return views_common.tracker_response(request, 'tracker/bidindex.html', { 'searchForm': searchForm, 'bids': bids, 'total': total, 'event': event, 'bidNameSpan' : bidNameSpan, 'choiceTotal': choiceTotal, 'challengeTotal': challengeTotal })
def get(self, request, event, *args, **kwargs): event = viewutil.get_event(event) params = { 'event': event.id, 'state': 'ACCEPTED', } prizes = filters.run_model_query('prize', params).select_related( 'startrun', 'endrun') results = [] for prize in prizes: result = { 'name': prize.name, 'provider': prize.provider, 'image': prize.image, 'starttime': None, 'endtime': None, 'minDonation': float(prize.minimumbid), } if prize.starttime: result['starttime'] = prize.starttime result['endtime'] = prize.endtime elif prize.startrun: result['starttime'] = prize.startrun.starttime result['endtime'] = prize.endrun.endtime results.append(result) return JsonResponse({'results': results})
def post_donation_to_postbacks(donation): event_donations = filters.run_model_query('donation', {'event': donation.event.id}) total = event_donations.aggregate(amount=Sum('amount'))['amount'] data = { 'id': donation.id, 'timereceived': str(donation.timereceived), 'comment': donation.comment, 'amount': donation.amount, 'donor__visibility': donation.donor.visibility, 'donor__visiblename': donation.donor.visible_name(), 'new_total': total, 'domain': donation.domain } # XXX: django/urllib2 throws UnicodeDecideError when payloads contain # unicode codepoints: # UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 292: ordinal not in range(128) try: data_json = json.dumps( data, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder).encode('utf-8') postbacks = models.PostbackURL.objects.filter(event=donation.event) for postback in postbacks: opener = urllib2.build_opener() req = urllib2.Request(postback.url, data_json, headers={'Content-Type': 'application/json; charset=utf-8'}) response = opener.open(req, timeout=5) except Exception as e: viewutil.tracker_log( 'postback_url', traceback.format_exc(), event=donation.event)
def user_index(request): eventSet = {} for futureEvent in filters.run_model_query('event', {'feed': 'future'}): eventDict = eventSet.setdefault(futureEvent, {'event': futureEvent}) eventDict['submission'] = futureEvent for prize in models.Prize.objects.filter(handler=request.user): eventDict = eventSet.setdefault(prize.event, {'event': prize.event}) prizeList = eventDict.setdefault('prizes', []) prizeList.append(prize) donor = request.user.donor if donor != None: for prizeWin in models.PrizeWinner.objects.filter(Q(winner=donor)&(Q(pendingcount__gte=1)|Q(acceptcount__gte=1))): print(prizeWin) eventDict = eventSet.setdefault(prizeWin.prize.event, {'event': prizeWin.prize.event}) prizeWinList = eventDict.setdefault('prizewins', []) prizeWinList.append(prizeWin) eventList = [] for key,value in eventSet.iteritems(): value['eventname'] = value['event'].name value['eventid'] = value['event'].id value.setdefault('submission', False) eventList.append(value) eventList.sort(key=lambda x: x['event'].date) return views_common.tracker_response(request, "tracker/user_index.html", {'eventList': eventList, })
def index(request, event=None): event = viewutil.get_event(event) eventParams = {} allEvents = Event.objects.all() eventCount = len(allEvents) if not event.id: if eventCount >= 1: event = allEvents.reverse()[0] if event.id: eventParams['event'] = event.id agg = filters.run_model_query('donation', eventParams).aggregate(amount=Sum('amount'), count=Count('amount'), max=Max('amount'), avg=Avg('amount')) agg['target'] = event.targetamount count = { 'runs': filters.run_model_query('run', eventParams).count(), 'prizes': filters.run_model_query('prize', eventParams).count(), 'bids': filters.run_model_query('bid', eventParams).count(), 'donors': filters.run_model_query( 'donorcache', eventParams).values('donor').distinct().count(), } if 'json' in request.GET: return HttpResponse(json.dumps({ 'count': count, 'agg': agg }, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder), content_type='application/json;charset=utf-8') return views_common.tracker_response(request, 'tracker/index.html', { 'agg': agg, 'count': count, 'event': event, 'event_count': eventCount })
def get_queryset(self, request): event = viewutil.get_selected_event(request) params = {} if not request.user.has_perm('tracker.can_edit_locked_events'): params['locked'] = False if event: params['event'] = event.id return filters.run_model_query('log', params, user=request.user, mode='admin')
def get_query(self,q,request): params = {'q': q} event = viewutil.get_selected_event(request) if event and self.useEvent: params['event'] = event.id model = self.model if hasattr(self, 'modelName'): model = self.modelName if self.useLock and not request.user.has_perm('tracker.can_edit_locked_events'): params['locked'] = False return filters.run_model_query(model, params, user=request.user, mode='admin')
def index(request,event=None): event = viewutil.get_event(event) eventParams = {} if event.id: eventParams['event'] = event.id agg = filters.run_model_query('donation', eventParams, user=request.user, mode='user').aggregate(amount=Sum('amount'), count=Count('amount'), max=Max('amount'), avg=Avg('amount')) agg['target'] = event.targetamount count = { 'runs' : filters.run_model_query('run', eventParams, user=request.user).count(), 'prizes' : filters.run_model_query('prize', eventParams, user=request.user).count(), 'bids' : filters.run_model_query('bid', eventParams, user=request.user).count(), 'donors' : filters.run_model_query('donorcache', eventParams, user=request.user).values('donor').distinct().count(), } if 'json' in request.GET: return HttpResponse(json.dumps({'count':count,'agg':agg},ensure_ascii=False),content_type='application/json;charset=utf-8') elif 'jsonp' in request.GET: callback = request.GET['jsonp'] return HttpResponse('%s(%s);' % (callback, json.dumps({'count':count,'agg':agg},ensure_ascii=False)), content_type='text/javascript;charset=utf-8') return tracker_response(request, 'tracker/index.html', { 'agg' : agg, 'count' : count, 'event': event })
def get(self, request, event, *args, **kwargs): event = viewutil.get_event(event) params = { 'event': event.id, } agg = filters.run_model_query( 'donation', params).aggregate(amount=Coalesce(Sum('amount'), Decimal('0.00'))) return JsonResponse({ 'total': agg['amount'], })
def index(request, event=None): event = viewutil.get_event(event) eventParams = {} if event.id: eventParams['event'] = event.id agg = filters.run_model_query('donation', eventParams).aggregate(amount=Sum( 'amount'), count=Count('amount'), max=Max('amount'), avg=Avg('amount')) agg['target'] = event.targetamount count = { 'runs': filters.run_model_query('run', eventParams).count(), 'prizes': filters.run_model_query('prize', eventParams).count(), 'bids': filters.run_model_query('bid', eventParams).count(), 'donors': filters.run_model_query('donorcache', eventParams).values('donor').distinct().count(), } if 'json' in request.GET: return HttpResponse(json.dumps({'count': count, 'agg': agg}, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder), content_type='application/json;charset=utf-8') return views_common.tracker_response(request, 'tracker/index.html', {'agg': agg, 'count': count, 'event': event})
def search(request): authorizedUser = request.user.has_perm('tracker.can_search') # return HttpResponse('Access denied',status=403,content_type='text/plain;charset=utf-8') try: searchParams = viewutil.request_params(request) searchtype = searchParams['type'] qs = filters.run_model_query(searchtype, searchParams, user=request.user, mode='admin' if authorizedUser else 'user') if searchtype in related: qs = qs.select_related(*related[searchtype]) if searchtype in defer: qs = qs.defer(*defer[searchtype]) qs = qs.annotate(**viewutil.ModelAnnotations.get(searchtype,{})) if qs.count() > 1000: qs = qs[:1000] jsonData = json.loads(serializers.serialize('json', qs, ensure_ascii=False)) objs = dict(map(lambda o: (o.id,o), qs)) for o in jsonData: baseObj = objs[int(o['pk'])] if isinstance(baseObj, Donor): o['fields']['public'] = baseObj.visible_name() else: o['fields']['public'] = unicode(baseObj) for a in viewutil.ModelAnnotations.get(searchtype,{}): o['fields'][a] = unicode(getattr(objs[int(o['pk'])],a)) for r in related.get(searchtype,[]): ro = objs[int(o['pk'])] for f in r.split('__'): if not ro: break ro = getattr(ro,f) if not ro: continue relatedData = json.loads(serializers.serialize('json', [ro], ensure_ascii=False))[0] for f in ro.__dict__: if f[0] == '_' or f.endswith('id') or f in defer.get(searchtype,[]): continue v = relatedData["fields"][f] o['fields'][r + '__' + f] = relatedData["fields"][f] if isinstance(ro, Donor): o['fields'][r + '__public'] = ro.visible_name() else: o['fields'][r + '__public'] = unicode(ro) if not authorizedUser: donor_privacy_filter(searchtype, o['fields']) donation_privacy_filter(searchtype, o['fields']) prize_privacy_filter(searchtype, o['fields']) clean_fields = getattr(Filters, searchtype, None) if clean_fields: clean_fields(request.user, o['fields']) resp = HttpResponse(json.dumps(jsonData,ensure_ascii=False),content_type='application/json;charset=utf-8') if 'queries' in request.GET and request.user.has_perm('tracker.view_queries'): return HttpResponse(json.dumps(connection.queries, ensure_ascii=False, indent=1),content_type='application/json;charset=utf-8') return resp except KeyError, e: return HttpResponse(json.dumps({'error': 'Key Error, malformed search parameters'}, ensure_ascii=False), status=400, content_type='application/json;charset=utf-8')
def run(request,id): try: run = SpeedRun.objects.get(pk=id) runners = run.runners.all() event = run.event bids = filters.run_model_query('bid', {'run': id}) bids = viewutil.get_tree_queryset_descendants(Bid, bids, include_self=True).select_related('speedrun','event', 'parent').prefetch_related('options') topLevelBids = filter(lambda bid: bid.parent == None, bids) return views_common.tracker_response(request, 'tracker/run.html', { 'event': event, 'run' : run, 'runners': runners, 'bids' : topLevelBids }) except SpeedRun.DoesNotExist: return views_common.tracker_response(request, template='tracker/badobject.html', status=404)
def run(request,id): try: run = SpeedRun.objects.get(pk=id) runners = run.runners.all() event = run.event bids = filters.run_model_query('bid', {'run': id}, user=request.user) bids = viewutil.get_tree_queryset_descendants(Bid, bids, include_self=True).select_related('speedrun','event', 'parent').prefetch_related('options') topLevelBids = filter(lambda bid: bid.parent == None, bids) bids = topLevelBids return tracker_response(request, 'tracker/run.html', { 'event': event, 'run' : run, 'runners': runners, 'bids' : topLevelBids }) except SpeedRun.DoesNotExist: return tracker_response(request, template='tracker/badobject.html', status=404)
def runindex(request,event=None): event = viewutil.get_event(event) searchForm = RunSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid Search Data', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id runs = filters.run_model_query('run', searchParams, user=request.user) runs = runs.select_related('runners').annotate(hasbids=Sum('bids')) return tracker_response(request, 'tracker/runindex.html', { 'searchForm': searchForm, 'runs' : runs, 'event': event })
def prizeindex(request,event=None): event = viewutil.get_event(event) searchForm = PrizeSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid Search Data', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id prizes = filters.run_model_query('prize', searchParams, user=request.user) prizes = prizes.select_related('startrun','endrun','category').prefetch_related('prizewinner_set') return tracker_response(request, 'tracker/prizeindex.html', { 'searchForm': searchForm, 'prizes' : prizes, 'event': event })
def index(request, event=None): event = viewutil.get_event(event) eventParams = {} if event.id: eventParams["event"] = event.id agg = filters.run_model_query("donation", eventParams, user=request.user, mode="user").aggregate( amount=Sum("amount"), count=Count("amount"), max=Max("amount"), avg=Avg("amount") ) agg["target"] = event.targetamount count = { "runs": filters.run_model_query("run", eventParams, user=request.user).count(), "prizes": filters.run_model_query("prize", eventParams, user=request.user).count(), "bids": filters.run_model_query("bid", eventParams, user=request.user).count(), "donors": filters.run_model_query("donorcache", eventParams, user=request.user) .values("donor") .distinct() .count(), } if "json" in request.GET: return HttpResponse( json.dumps({"count": count, "agg": agg}, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder), content_type="application/json;charset=utf-8", ) elif "jsonp" in request.GET: callback = request.GET["jsonp"] return HttpResponse( "%s(%s);" % ( callback, json.dumps({"count": count, "agg": agg}, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder), ), content_type="text/javascript;charset=utf-8", ) return views_common.tracker_response(request, "tracker/index.html", {"agg": agg, "count": count, "event": event})
def show_completed_bids(request): current = viewutil.get_selected_event(request) params = {'feed': 'completed'} if current: params['event'] = current.id bids = filters.run_model_query('bid', params, user=request.user, mode='admin') bidList = list(bids) if request.method == 'POST': for bid in bidList: bid.state = 'CLOSED' bid.save() logutil.change(request, bid, u'Closed {0}'.format(unicode(bid))) return render(request, 'admin/completed_bids_post.html', { 'bids': bidList }) return render(request, 'admin/completed_bids.html', { 'bids': bidList })
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Get event event = viewutil.get_event(context['event']) if event.locked: raise Http404 context['event'] = event # Base donation info form. context['commentform'] = forms.DonationEntryFormV2( event=event, data=self.request.POST or None) # Get donation amount if form is valid. if self.request.method == 'POST' and context['commentform'].is_valid(): amount = context['commentform'].cleaned_data['amount'] else: amount = Decimal('0.00') # Bid selection form bids = filters.run_model_query( 'bid', { 'state': 'OPENED', 'event': event.id }, user=self.request.user).select_related( 'speedrun').prefetch_related('options') context['bidsform'] = forms.DonationBidFormV2(amount=amount, bids=bids, data=self.request.POST or None) context['hasBids'] = bids.count() > 0 context['bids'] = bids # Group bids by run for the revamped donate page display. bids_by_run = collections.OrderedDict() for bid in bids: if bid.speedrun not in bids_by_run: bids_by_run[bid.speedrun] = [] bid.options_list = list( bid.options.filter(state='OPENED').order_by('-total', 'name')) bids_by_run[bid.speedrun].append(bid) context['bids_by_run'] = [] for run, bids in bids_by_run.items(): run.bid_list = bids context['bids_by_run'].append(run) return context
def get_donation_prize_info(donation): """ Attempts to find a list of all prizes this donation gives the donor eligibility for. Does _not_ attempt to relate this information to any _past_ eligibility. Returns the set as a list of {'prize','amount'} dictionaries. """ prizeList = [] for ticket in donation.tickets.all(): contribAmount = get_donation_prize_contribution(ticket.prize, donation, ticket.amount) if contribAmount != None: prizeList.append({'prize': ticket.prize, 'amount': contribAmount}) for timeprize in filters.run_model_query( 'prize', params={ 'feed': 'current', 'ticketdraw': False, 'offset': donation.timereceived, 'noslice': True } ): contribAmount = get_donation_prize_contribution(timeprize, donation) if contribAmount != None: prizeList.append({'prize': timeprize, 'amount': contribAmount}) return prizeList
def donationindex(request,event=None): event = viewutil.get_event(event) orderdict = { 'name' : ('donor__lastname', 'donor__firstname'), 'amount' : ('amount', ), 'time' : ('timereceived', ), } page = request.GET.get('page', 1) sort = request.GET.get('sort', 'time') if sort not in orderdict: sort = 'time' try: order = int(request.GET.get('order', -1)) except ValueError: order = -1 searchForm = DonationSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid Search Data', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id donations = filters.run_model_query('donation', searchParams, user=request.user) donations = views_common.fixorder(donations, orderdict, sort, order) fulllist = request.user.has_perm('tracker.view_full_list') and page == 'full' agg = donations.aggregate(amount=Sum('amount'), count=Count('amount'), max=Max('amount'), avg=Avg('amount')) pages = paginator.Paginator(donations,50) if fulllist: pageinfo = { 'paginator' : pages, 'has_previous' : False, 'has_next' : False, 'paginator.num_pages' : pages.num_pages } page = 0 else: try: pageinfo = pages.page(page) except paginator.PageNotAnInteger: pageinfo = pages.page(1) except paginator.EmptyPage: pageinfo = pages.page(paginator.num_pages) page = pages.num_pages donations = pageinfo.object_list return views_common.tracker_response(request, 'tracker/donationindex.html', { 'searchForm': searchForm, 'donations' : donations, 'pageinfo' : pageinfo, 'page' : page, 'fulllist' : fulllist, 'agg' : agg, 'sort' : sort, 'order' : order, 'event': event })
def search(request): authorizedUser = request.user.has_perm('tracker.can_search') # return HttpResponse('Access denied',status=403,content_type='text/plain;charset=utf-8') try: searchParams = viewutil.request_params(request) searchtype = searchParams['type'] qs = filters.run_model_query(searchtype, searchParams, user=request.user, mode='admin' if authorizedUser else 'user') if searchtype in related: qs = qs.select_related(*related[searchtype]) if searchtype in defer: qs = qs.defer(*defer[searchtype]) qs = qs.annotate(**viewutil.ModelAnnotations.get(searchtype,{})) if qs.count() > 1000: qs = qs[:1000] jsonData = json.loads(serializers.serialize('json', qs, ensure_ascii=False)) objs = dict(map(lambda o: (o.id,o), qs)) for o in jsonData: baseObj = objs[int(o['pk'])] if isinstance(baseObj, Donor): o['fields']['public'] = baseObj.visible_name() else: o['fields']['public'] = unicode(baseObj) for a in viewutil.ModelAnnotations.get(searchtype,{}): o['fields'][a] = unicode(getattr(objs[int(o['pk'])],a)) for r in related.get(searchtype,[]): ro = objs[int(o['pk'])] for f in r.split('__'): if not ro: break ro = getattr(ro,f) if not ro: continue relatedData = json.loads(serializers.serialize('json', [ro], ensure_ascii=False))[0] for f in ro.__dict__: if f[0] == '_' or f.endswith('id') or f in defer.get(searchtype,[]): continue v = relatedData["fields"][f] o['fields'][r + '__' + f] = relatedData["fields"][f] if isinstance(ro, Donor): o['fields'][r + '__public'] = ro.visible_name() else: o['fields'][r + '__public'] = unicode(ro) if not authorizedUser: donor_privacy_filter(searchtype, o['fields']) donation_privacy_filter(searchtype, o['fields']) prize_privacy_filter(searchtype, o['fields']) resp = HttpResponse(json.dumps(jsonData,ensure_ascii=False),content_type='application/json;charset=utf-8') if 'queries' in request.GET and request.user.has_perm('tracker.view_queries'): return HttpResponse(json.dumps(connection.queries, ensure_ascii=False, indent=1),content_type='application/json;charset=utf-8') return resp except KeyError, e: return HttpResponse(json.dumps({'error': 'Key Error, malformed search parameters'}, ensure_ascii=False), status=400, content_type='application/json;charset=utf-8')
def submit_prize(request, event): event = viewutil.get_event(event) if request.method == 'POST': prizeForm = forms.PrizeSubmissionForm(data=request.POST) if prizeForm.is_valid(): prize = models.Prize.objects.create( event=event, name=prizeForm.cleaned_data['name'], description=prizeForm.cleaned_data['description'], maxwinners=prizeForm.cleaned_data['maxwinners'], extrainfo=prizeForm.cleaned_data['extrainfo'], estimatedvalue=prizeForm.cleaned_data['estimatedvalue'], minimumbid=prizeForm.cleaned_data['suggestedamount'], maximumbid=prizeForm.cleaned_data['suggestedamount'], image=prizeForm.cleaned_data['imageurl'], provided=prizeForm.cleaned_data['providername'], provideremail=prizeForm.cleaned_data['provideremail'], creator=prizeForm.cleaned_data['creatorname'], creatoremail=prizeForm.cleaned_data['creatoremail'], creatorwebsite=prizeForm.cleaned_data['creatorwebsite'], startrun=prizeForm.cleaned_data['startrun'], endrun=prizeForm.cleaned_data['endrun']) prize.save() return views_common.tracker_response( request, "tracker/submit_prize_success.html", {'prize': prize}) else: prizeForm = forms.PrizeSubmissionForm() runs = filters.run_model_query('run', {'event': event}, request.user) def run_info(run): return { 'id': run.id, 'name': run.name, 'description': run.description, 'runners': run.deprecated_runners, 'starttime': run.starttime.isoformat(), 'endtime': run.endtime.isoformat() } dumpArray = [run_info(o) for o in runs.all()] runsJson = json.dumps(dumpArray) return views_common.tracker_response(request, "tracker/submit_prize_form.html", { 'event': event, 'form': prizeForm, 'runs': runsJson })
def prizeindex(request,event=None): event = viewutil.get_event(event) searchForm = PrizeSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid Search Data', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id prizes = filters.run_model_query('prize', searchParams) prizes = prizes.select_related('startrun','endrun','category').prefetch_related('prizewinner_set') return views_common.tracker_response(request, 'tracker/prizeindex.html', { 'searchForm': searchForm, 'prizes' : prizes, 'event': event })
def test_donor_amounts_make_sense(self): eventStart = parse_date("2012-01-01 01:00:00").replace(tzinfo=pytz.utc); rand = random.Random(998164); event = randgen.build_random_event(rand, eventStart, numRuns=10, numDonors=15, numDonations=300); donorListB = filters.run_model_query('donor', {'event': event.id}, mode='user'); donorListB = donorListB.annotate(**viewutil.ModelAnnotations['donor']); donorListA = tracker.models.Donor.objects.filter(donation__event=event); paired = {}; for donor in donorListA: sum = Decimal("0.00"); for donation in donor.donation_set.all(): sum += donation.amount; paired[donor.id] = [sum]; for donor in donorListB: paired[donor.id].append(donor.amount); for name, value in paired.items(): self.assertEqual(value[1], value[0]);
def runindex(request,event=None): event = viewutil.get_event(event) searchForm = RunSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid Search Data', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id runs = filters.run_model_query('run', searchParams) runs = runs.annotate(hasbids=Sum('bids')) return views_common.tracker_response(request, 'tracker/runindex.html', { 'searchForm': searchForm, 'runs' : runs, 'event': event })
def bidindex(request, event=None): event = viewutil.get_event(event) searchForm = BidSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid filter form', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id else: return HttpResponseRedirect( reverse('tracker.views.bidindex', args=(Event.objects.latest().id, ))) bids = filters.run_model_query('bid', searchParams, user=request.user) bids = bids.filter(parent=None) total = bids.aggregate(Sum('total'))['total__sum'] or Decimal('0.00') choiceTotal = bids.filter(goal=None).aggregate( Sum('total'))['total__sum'] or Decimal('0.00') challengeTotal = bids.exclude(goal=None).aggregate( Sum('total'))['total__sum'] or Decimal('0.00') bids = viewutil.get_tree_queryset_descendants( Bid, bids, include_self=True).prefetch_related('options') bids = bids.filter(parent=None) if event.id: bidNameSpan = 2 else: bidNameSpan = 1 return views_common.tracker_response( request, 'tracker/bidindex.html', { 'searchForm': searchForm, 'bids': bids, 'total': total, 'event': event, 'bidNameSpan': bidNameSpan, 'choiceTotal': choiceTotal, 'challengeTotal': challengeTotal })
def draw_prize_winners(request): currentEvent = viewutil.get_selected_event(request) params = { 'feed': 'todraw' } if currentEvent != None: params['event'] = currentEvent.id prizes = filters.run_model_query('prize', params, user=request.user, mode='admin') if request.method == 'POST': form = forms.DrawPrizeWinnersForm(prizes=prizes, data=request.POST) if form.is_valid(): for prize in form.cleaned_data['prizes']: status = True while status and not prize.maxed_winners(): status, data = prizeutil.draw_prize(prize, seed=form.cleaned_data['seed']) prize.error = data['error'] if not status else '' logutil.change(request, prize, 'Prize Drawing') return render(request, 'admin/draw_prize_winners_post.html', { 'prizes': form.cleaned_data['prizes'] }) else: form = forms.DrawPrizeWinnersForm(prizes=prizes) return render(request, 'admin/draw_prize_winners.html', { 'form': form })
def prizeindex(request, event=None): event = viewutil.get_event(event) searchForm = PrizeSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse("Invalid Search Data", status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams["event"] = event.id prizes = filters.run_model_query("prize", searchParams, user=request.user) prizes = prizes.select_related("startrun", "endrun", "category").prefetch_related("prizewinner_set") return views_common.tracker_response( request, "tracker/prizeindex.html", {"searchForm": searchForm, "prizes": prizes, "event": event} )
def bidindex(request, event=None): event = viewutil.get_event(event) searchForm = BidSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse("Invalid filter form", status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams["event"] = event.id else: return HttpResponseRedirect(reverse("tracker.views.bidindex", args=(Event.objects.latest().id,))) bids = filters.run_model_query("bid", searchParams, user=request.user) bids = bids.filter(parent=None) total = bids.aggregate(Sum("total"))["total__sum"] or Decimal("0.00") choiceTotal = bids.filter(goal=None).aggregate(Sum("total"))["total__sum"] or Decimal("0.00") challengeTotal = bids.exclude(goal=None).aggregate(Sum("total"))["total__sum"] or Decimal("0.00") bids = viewutil.get_tree_queryset_descendants(Bid, bids, include_self=True).prefetch_related("options") bids = bids.filter(parent=None) if event.id: bidNameSpan = 2 else: bidNameSpan = 1 return views_common.tracker_response( request, "tracker/bidindex.html", { "searchForm": searchForm, "bids": bids, "total": total, "event": event, "bidNameSpan": bidNameSpan, "choiceTotal": choiceTotal, "challengeTotal": challengeTotal, }, )
def runindex(request, event=None): event = viewutil.get_event(event) searchForm = RunSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse("Invalid Search Data", status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams["event"] = event.id runs = filters.run_model_query("run", searchParams, user=request.user) runs = runs.annotate(hasbids=Sum("bids")) return views_common.tracker_response( request, "tracker/runindex.html", {"searchForm": searchForm, "runs": runs, "event": event} )
def get(self, request, event, *args, **kwargs): # Get the next 3 upcoming runs for the event that haven't finished yet. event = viewutil.get_event(event) now = timezone.now() params = { 'event': event.id, 'endtime_gte': now, } runs = filters.run_model_query('run', params)[:3] results = [] for run in runs: results.append({ 'game': run.name, 'category': run.category, 'estimate': str(run.run_time), 'runners': [r.name for r in run.runners.all()], }) return JsonResponse({'results': results})
def run(request, id): try: run = SpeedRun.objects.get(pk=id) runners = run.runners.all() event = run.event bids = filters.run_model_query("bid", {"run": id}, user=request.user) bids = ( viewutil.get_tree_queryset_descendants(Bid, bids, include_self=True) .select_related("speedrun", "event", "parent") .prefetch_related("options") ) topLevelBids = filter(lambda bid: bid.parent == None, bids) bids = topLevelBids return views_common.tracker_response( request, "tracker/run.html", {"event": event, "run": run, "runners": runners, "bids": topLevelBids} ) except SpeedRun.DoesNotExist: return views_common.tracker_response(request, template="tracker/badobject.html", status=404)
def submit_prize(request, event): event = viewutil.get_event(event) if request.method == 'POST': prizeForm = forms.PrizeSubmissionForm(data=request.POST) if prizeForm.is_valid(): prize = prizeForm.save(event, request.user) return views_common.tracker_response(request, "tracker/submit_prize_success.html", {'prize': prize}) else: prizeForm = forms.PrizeSubmissionForm() runs = filters.run_model_query('run', {'event': event}, request.user) def run_info(run): return {'id': run.id, 'name': run.name, 'description': run.description, 'runners': run.deprecated_runners, 'starttime': run.starttime.isoformat(), 'endtime': run.endtime.isoformat()} dumpArray = [run_info(o) for o in runs.all()] runsJson = json.dumps(dumpArray) return views_common.tracker_response(request, "tracker/submit_prize.html", {'event': event, 'form': prizeForm, 'runs': runsJson})
def get(self, request, event, *args, **kwargs): # Get the upcoming bids and their options + totals. event = viewutil.get_event(event) now = timezone.now() params = { 'event': event.id, } # .filter(speedrun__endtime__gte=now) bids = filters.run_model_query( 'bid', params).filter(state__in=['OPENED', 'CLOSED']).select_related( 'speedrun').prefetch_related('options').order_by( 'speedrun__endtime') results = [] for bid in bids: # ignore bids for no game for now if bid.speedrun == None: continue result = { 'game': bid.speedrun.name, 'bid': bid.name, 'goal': None if bid.goal == None else float(bid.goal), 'amount_raised': float(bid.total), 'allow_custom_options': bid.allowuseroptions, 'state': bid.state, 'run_started': bid.speedrun.starttime < now, 'options': [], } for option in bid.options.filter(state__in=['OPENED', 'CLOSED']): result['options'].append({ 'name': option.name, 'amount_raised': float(option.total), }) result['amount_raised'] += float(option.total) results.append(result) return JsonResponse({'results': results})
def get_donation_prize_info(donation): """ Attempts to find a list of all prizes this donation gives the donor eligibility for. Does _not_ attempt to relate this information to any _past_ eligibility. Returns the set as a list of {'prize','amount'} dictionaries. """ prizeList = [] for ticket in donation.tickets.all(): contribAmount = get_donation_prize_contribution( ticket.prize, donation, ticket.amount) if contribAmount != None: prizeList.append({'prize': ticket.prize, 'amount': contribAmount}) for timeprize in filters.run_model_query('prize', params={ 'feed': 'current', 'ticketdraw': False, 'offset': donation.timereceived, 'noslice': True }): contribAmount = get_donation_prize_contribution(timeprize, donation) if contribAmount != None: prizeList.append({'prize': timeprize, 'amount': contribAmount}) return prizeList
def search(request): authorizedUser = request.user.has_perm('tracker.can_search'); # return HttpResponse('Access denied',status=403,content_type='text/plain;charset=utf-8') try: searchtype = request.GET['type'] qs = filters.run_model_query(searchtype, request.GET, user=request.user, mode='admin' if authorizedUser else 'user'); if searchtype in related: qs = qs.select_related(*related[searchtype]) if searchtype in defer: qs = qs.defer(*defer[searchtype]) qs = qs.annotate(**viewutil.ModelAnnotations.get(searchtype,{})) if searchtype == 'bid' or searchtype == 'allbids': qs = viewutil.CalculateBidQueryAnnotations(qs); json = simplejson.loads(serializers.serialize('json', qs, ensure_ascii=False)) objs = dict(map(lambda o: (o.id,o), qs)) for o in json: for a in viewutil.ModelAnnotations.get(searchtype,{}): o['fields'][a] = unicode(getattr(objs[int(o['pk'])],a)) for r in related.get(searchtype,[]): ro = objs[int(o['pk'])] for f in r.split('__'): if not ro: break ro = getattr(ro,f) if not ro: continue for f in ro.__dict__: if f[0] == '_' or f.endswith('id') or f in defer.get(searchtype,[]): continue v = unicode(getattr(ro,f)) o['fields'][r + '__' + f] = v; if not authorizedUser: donor_privacy_filter(searchtype, o['fields']); donation_privacy_filter(searchtype, o['fields']); resp = HttpResponse(simplejson.dumps(json,ensure_ascii=False),content_type='application/json;charset=utf-8') if 'queries' in request.GET and request.user.has_perm('tracker.view_queries'): return HttpResponse(simplejson.dumps(connection.queries, ensure_ascii=False, indent=1),content_type='application/json;charset=utf-8') return resp except KeyError, e: return HttpResponse(simplejson.dumps({'error': 'Key Error, malformed search parameters'}, ensure_ascii=False), status=400, content_type='application/json;charset=utf-8')
def get(self, request, event, *args, **kwargs): event = viewutil.get_event(event) params = { 'event': event.id, 'transactionstate': 'COMPLETED', } # get all completed donations, get the last 20 recieved ones donations = filters.run_model_query( 'donation', params).select_related('donor').order_by('-timereceived')[:20] results = [] for donation in donations: results.append({ 'id': donation.id, 'donor': donation.donor.visible_name(), 'comment': donation.comment if donation.commentstate == 'APPROVED' else '', 'amount': float(donation.amount), }) return JsonResponse({'results': results})
def bidindex(request, event=None): event = viewutil.get_event(event) searchForm = BidSearchForm(request.GET); if not searchForm.is_valid(): return HttpResponse('Invalid filter form', status=400); searchParams = {}; searchParams.update(request.GET); searchParams.update(searchForm.cleaned_data); if event.id: searchParams['event'] = event.id; bids = filters.run_model_query('bid', searchParams, user=request.user); bids = viewutil.get_tree_queryset_descendants(Bid, bids, include_self=True).select_related('speedrun','event', 'parent').prefetch_related('options'); agg = bids.aggregate(**viewutil.ModelAnnotations['bid']); bids = bids.annotate(**viewutil.ModelAnnotations['bid']); bidsCache = viewutil.FixupBidAnnotations(bids); topLevelBids = filter(lambda bid: bid.parent == None, bids) bids = topLevelBids; choiceTotal = sum([bidsCache[bid.id].amount for bid in topLevelBids if not bid.goal]) challengeTotal = sum([bidsCache[bid.id].amount for bid in topLevelBids if bid.goal]) if event.id: bidNameSpan = 2; else: bidNameSpan = 1; return tracker_response(request, 'tracker/bidindex.html', { 'searchForm': searchForm, 'bids': topLevelBids, 'cache': bidsCache, 'agg': agg, 'event': event, 'bidNameSpan' : bidNameSpan, 'choiceTotal': choiceTotal, 'challengeTotal': challengeTotal });
def submit_prize(request, event): event = viewutil.get_event(event) if request.method == 'POST': prizeForm = forms.PrizeSubmissionForm(data=request.POST) if prizeForm.is_valid(): prize = models.Prize.objects.create( event=event, name=prizeForm.cleaned_data['name'], description=prizeForm.cleaned_data['description'], maxwinners=prizeForm.cleaned_data['maxwinners'], extrainfo=prizeForm.cleaned_data['extrainfo'], estimatedvalue=prizeForm.cleaned_data['estimatedvalue'], minimumbid=prizeForm.cleaned_data['suggestedamount'], maximumbid=prizeForm.cleaned_data['suggestedamount'], image=prizeForm.cleaned_data['imageurl'], provided=prizeForm.cleaned_data['providername'], provideremail=prizeForm.cleaned_data['provideremail'], creator=prizeForm.cleaned_data['creatorname'], creatoremail=prizeForm.cleaned_data['creatoremail'], creatorwebsite=prizeForm.cleaned_data['creatorwebsite'], startrun=prizeForm.cleaned_data['startrun'], endrun=prizeForm.cleaned_data['endrun']) prize.save() return views_common.tracker_response(request, "tracker/submit_prize_success.html", { 'prize': prize }) else: prizeForm = forms.PrizeSubmissionForm() runs = filters.run_model_query('run', {'event': event}, request.user) def run_info(run): return {'id': run.id, 'name': run.name, 'description': run.description, 'runners': run.deprecated_runners, 'starttime': run.starttime.isoformat(), 'endtime': run.endtime.isoformat() } dumpArray = [run_info(o) for o in runs.all()] runsJson = json.dumps(dumpArray) return views_common.tracker_response(request, "tracker/submit_prize_form.html", { 'event': event, 'form': prizeForm, 'runs': runsJson })
def donate_orig(request, event): event = viewutil.get_event(event) if event.locked: raise Http404 bidsFormPrefix = "bidsform" prizeFormPrefix = "prizeForm" if request.method == 'POST': commentform = forms.DonationEntryForm(event=event, data=request.POST) if commentform.is_valid(): prizesform = forms.PrizeTicketFormSet( amount=commentform.cleaned_data['amount'], data=request.POST, prefix=prizeFormPrefix) bidsform = forms.DonationBidFormSet( amount=commentform.cleaned_data['amount'], data=request.POST, prefix=bidsFormPrefix) if bidsform.is_valid() and prizesform.is_valid(): with transaction.atomic(): donation = models.Donation( amount=commentform.cleaned_data['amount'], timereceived=pytz.utc.localize( datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=event, testdonation=event.usepaypalsandbox) if commentform.cleaned_data['comment']: donation.comment = commentform.cleaned_data['comment'] donation.commentstate = "PENDING" donation.requestedvisibility = commentform.cleaned_data[ 'requestedvisibility'] donation.requestedalias = commentform.cleaned_data[ 'requestedalias'] donation.requestedemail = commentform.cleaned_data[ 'requestedemail'] donation.requestedsolicitemail = commentform.cleaned_data[ 'requestedsolicitemail'] donation.currency = event.paypalcurrency donation.save() for bidform in bidsform: if 'bid' in bidform.cleaned_data and bidform.cleaned_data[ 'bid']: bid = bidform.cleaned_data['bid'] if bid.allowuseroptions: # unfortunately, you can't use get_or_create when using a non-atomic transaction # this does technically introduce a race condition, I'm just going to hope that two people don't # suggest the same option at the exact same time # also, I want to do case-insensitive comparison on the name try: bid = models.Bid.objects.get( event=bid.event, speedrun=bid.speedrun, name__iexact=bidform. cleaned_data['customoptionname'], parent=bid) except models.Bid.DoesNotExist: bid = models.Bid.objects.create( event=bid.event, speedrun=bid.speedrun, name=bidform. cleaned_data['customoptionname'], parent=bid, state='PENDING', istarget=True) donation.bids.add(models.DonationBid( bid=bid, amount=Decimal( bidform.cleaned_data['amount'])), bulk=False) for prizeform in prizesform: if 'prize' in prizeform.cleaned_data and prizeform.cleaned_data[ 'prize']: prize = prizeform.cleaned_data['prize'] donation.tickets.add( models.PrizeTicket( prize=prize, amount=Decimal( prizeform.cleaned_data['amount']))) donation.full_clean() donation.save() paypal_dict = { "amount": str(donation.amount), "cmd": "_donations", "business": donation.event.paypalemail, "item_name": donation.event.receivername, "notify_url": request.build_absolute_uri(reverse('tracker:ipn')), "return_url": request.build_absolute_uri( reverse('tracker:paypal_return')), "cancel_return": request.build_absolute_uri( reverse('tracker:paypal_cancel')), "custom": str(donation.id) + ":" + donation.domainId, "currency_code": donation.event.paypalcurrency, "no_shipping": 0, } # Create the form instance form = forms.PayPalDonationsForm( button_type="donate", sandbox=donation.event.usepaypalsandbox, initial=paypal_dict) context = {"event": donation.event, "form": form} return views_common.tracker_response( request, "tracker/paypal_redirect.html", context) else: bidsform = forms.DonationBidFormSet(amount=Decimal('0.00'), data=request.POST, prefix=bidsFormPrefix) prizesform = forms.PrizeTicketFormSet(amount=Decimal('0.00'), data=request.POST, prefix=prizeFormPrefix) else: commentform = forms.DonationEntryForm(event=event) bidsform = forms.DonationBidFormSet(amount=Decimal('0.00'), prefix=bidsFormPrefix) prizesform = forms.PrizeTicketFormSet(amount=Decimal('0.00'), prefix=prizeFormPrefix) def bid_parent_info(bid): if bid != None: return { 'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent) } else: return None def bid_info(bid): result = { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name if bid.suggestions.exists(): result['suggested'] = list([x.name for x in bid.suggestions.all()]) if bid.allowuseroptions: result['custom'] = ['custom'] result[ 'label'] += ' (select and add a name next to "New Option Name")' return result bids = filters.run_model_query( 'bidtarget', { 'state': 'OPENED', 'event': event.id }, user=request.user).distinct().select_related( 'parent').prefetch_related('suggestions') allPrizes = filters.run_model_query('prize', { 'feed': 'current', 'event': event.id }) prizes = allPrizes.filter(ticketdraw=False) dumpArray = [bid_info(o) for o in bids] bidsJson = json.dumps(dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) ticketPrizes = allPrizes.filter(ticketdraw=True, auto_tickets=False) def prize_info(prize): result = { 'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'maximumbid': prize.maximumbid, 'sumdonations': prize.sumdonations } return result dumpArray = [prize_info(o) for o in ticketPrizes.all()] ticketPrizesJson = json.dumps(dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) return views_common.tracker_response( request, "tracker/donate.html", { 'event': event, 'bidsform': bidsform, 'prizesform': prizesform, 'commentform': commentform, 'hasBids': bids.count() > 0, 'bidsJson': bidsJson, 'hasTicketPrizes': ticketPrizes.count() > 0, 'ticketPrizesJson': ticketPrizesJson, 'prizes': prizes, 'site_name': settings.SITE_NAME, })
def donate(request, event): event = viewutil.get_event(event) if event.locked: raise Http404 bundle = webpack_manifest.load(os.path.abspath( os.path.join(os.path.dirname(__file__), '../ui-tracker.manifest.json')), settings.STATIC_URL, debug=settings.DEBUG, timeout=60, read_retry=None) commentform, bidsform, prizesform = process_form(request, event) if not bidsform: return commentform def bid_parent_info(bid): if bid != None: return { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent), 'custom': bid.allowuseroptions, } else: return None def bid_info(bid): result = { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name else: result['runname'] = 'Event Wide' if bid.allowuseroptions: result['custom'] = True return result bids = filters.run_model_query('bidtarget', {'state': 'OPENED', 'event': event.id}, user=request.user) \ .distinct().select_related('parent', 'speedrun').prefetch_related('suggestions') prizes = filters.run_model_query('prize', { 'feed': 'current', 'event': event.id }) bidsArray = [bid_info(o) for o in bids] def prize_info(prize): result = { 'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'sumdonations': prize.sumdonations, 'url': reverse('tracker:prize', args=(prize.id, )), 'image': prize.image, } return result prizesArray = [prize_info(o) for o in prizes.all()] def to_json(value): if hasattr(value, 'id'): return value.id return value initialForm = { k: to_json(commentform.cleaned_data[k]) for k, v in commentform.fields.items() if commentform.is_bound and k in commentform.cleaned_data } pickedIncentives = [{ k: to_json(form.cleaned_data[k]) for k, v in form.fields.items() if k in form.cleaned_data } for form in bidsform.forms if form.is_bound] return render( request, 'ui/index.html', { 'event': event, 'events': Event.objects.all(), 'bundle': bundle.donate, 'root_path': reverse('tracker:ui:index'), 'app': 'DonateApp', 'title': 'Donate', 'forms': { 'bidsform': bidsform, 'prizesform': prizesform }, 'form_errors': mark_safe( json.dumps({ 'commentform': json.loads(commentform.errors.as_json()), 'bidsform': bidsform.errors, })), 'props': mark_safe( json.dumps( { 'event': json.loads(serializers.serialize( 'json', [event]))[0]['fields'], 'prizes': prizesArray, 'incentives': bidsArray, 'initialForm': initialForm, 'initialIncentives': pickedIncentives, 'donateUrl': request.get_full_path(), 'prizesUrl': request.build_absolute_uri( reverse('tracker:prizeindex', args=(event.id, ))), 'rulesUrl': 'https://gamesdonequick.com/sweepstakes', # TODO: put in settings? }, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder)), }, )
def donate(request, event): event = viewutil.get_event(event) if event.locked: raise Http404 bundle = webpack_manifest.load( os.path.abspath(os.path.join(os.path.dirname( __file__), '../ui-tracker.manifest.json')), settings.STATIC_URL, debug=settings.DEBUG, timeout=60, read_retry=None ) commentform, bidsform, prizesform = process_form(request, event) if not bidsform: return commentform def bid_parent_info(bid): if bid != None: return { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent), 'custom': bid.allowuseroptions, } else: return None def bid_info(bid): result = { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name else: result['runname'] = 'Event Wide' if bid.allowuseroptions: result['custom'] = True return result bids = filters.run_model_query('bidtarget', {'state': 'OPENED', 'event': event.id}, user=request.user) \ .distinct().select_related('parent', 'speedrun').prefetch_related('suggestions') prizes = filters.run_model_query( 'prize', {'feed': 'current', 'event': event.id}) bidsArray = [bid_info(o) for o in bids] def prize_info(prize): result = { 'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'sumdonations': prize.sumdonations, 'url': reverse('tracker:prize', args=(prize.id,)), 'image': prize.image, } return result prizesArray = [prize_info(o) for o in prizes.all()] def to_json(value): if hasattr(value, 'id'): return value.id return value initialForm = {k: to_json(commentform.cleaned_data[k]) for k, v in commentform.fields.items() if commentform.is_bound and k in commentform.cleaned_data} pickedIncentives = [ {k: to_json(form.cleaned_data[k]) for k, v in form.fields.items() if k in form.cleaned_data} for form in bidsform.forms if form.is_bound ] return render( request, 'ui/index.html', { 'event': event, 'events': Event.objects.all(), 'bundle': bundle.donate, 'root_path': reverse('tracker:ui:index'), 'app': 'DonateApp', 'title': 'Donate', 'forms': {'bidsform': bidsform, 'prizesform': prizesform}, 'form_errors': mark_safe(json.dumps({ 'commentform': json.loads(commentform.errors.as_json()), 'bidsform': bidsform.errors, })), 'props': mark_safe(json.dumps({ 'event': json.loads(serializers.serialize('json', [event]))[0]['fields'], 'prizes': prizesArray, 'incentives': bidsArray, 'initialForm': initialForm, 'initialIncentives': pickedIncentives, 'donateUrl': request.get_full_path(), 'prizesUrl': request.build_absolute_uri(reverse('tracker:prizeindex', args=(event.id,))), 'rulesUrl': 'https://gamesdonequick.com/sweepstakes', # TODO: put in settings? }, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder)), }, )
def donate(request, event): event = viewutil.get_event(event) if event.locked: raise Http404 bidsFormPrefix = "bidsform" prizeFormPrefix = "prizeForm" if request.method == 'POST': commentform = DonationEntryForm(data=request.POST) if commentform.is_valid(): prizesform = PrizeTicketFormSet(amount=commentform.cleaned_data['amount'], data=request.POST, prefix=prizeFormPrefix) bidsform = DonationBidFormSet(amount=commentform.cleaned_data['amount'], data=request.POST, prefix=bidsFormPrefix) if bidsform.is_valid() and prizesform.is_valid(): try: donation = Donation(amount=commentform.cleaned_data['amount'], timereceived=pytz.utc.localize(datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=event, testdonation=event.usepaypalsandbox) if commentform.cleaned_data['comment']: donation.comment = commentform.cleaned_data['comment'] donation.commentstate = "PENDING" donation.requestedvisibility = commentform.cleaned_data['requestedvisibility'] donation.requestedalias = commentform.cleaned_data['requestedalias'] donation.requestedemail = commentform.cleaned_data['requestedemail'] donation.currency = event.paypalcurrency donation.save() for bidform in bidsform: if 'bid' in bidform.cleaned_data and bidform.cleaned_data['bid']: bid = bidform.cleaned_data['bid'] if bid.allowuseroptions: # unfortunately, you can't use get_or_create when using a non-atomic transaction # this does technically introduce a race condition, I'm just going to hope that two people don't # suggest the same option at the exact same time # also, I want to do case-insensitive comparison on the name try: bid = Bid.objects.get(event=bid.event, speedrun=bid.speedrun, name__iexact=bidform.cleaned_data['customoptionname'], parent=bid) except Bid.DoesNotExist: bid = Bid.objects.create(event=bid.event, speedrun=bid.speedrun, name=bidform.cleaned_data['customoptionname'], parent=bid, state='PENDING', istarget=True) donation.bids.add(DonationBid(bid=bid, amount=Decimal(bidform.cleaned_data['amount']))) for prizeform in prizesform: if 'prize' in prizeform.cleaned_data and prizeform.cleaned_data['prize']: prize = prizeform.cleaned_data['prize'] donation.tickets.add(PrizeTicket(prize=prize, amount=Decimal(prizeform.cleaned_data['amount']))) donation.full_clean() donation.save() except Exception as e: transaction.rollback() raise e serverURL = viewutil.get_request_server_url(request) paypal_dict = { "amount": str(donation.amount), "cmd": "_donations", "business": donation.event.paypalemail, "item_name": donation.event.receivername, "notify_url": serverURL + reverse('tracker.views.ipn'), "return_url": serverURL + reverse('tracker.views.paypal_return'), "cancel_return": serverURL + reverse('tracker.views.paypal_cancel'), "custom": str(donation.id) + ":" + donation.domainId, "currency_code": donation.event.paypalcurrency, } # Create the form instance form = PayPalPaymentsForm(button_type="donate", sandbox=donation.event.usepaypalsandbox, initial=paypal_dict) context = {"event": donation.event, "form": form } return tracker_response(request, "tracker/paypal_redirect.html", context) else: bidsform = DonationBidFormSet(amount=Decimal('0.00'), data=request.POST, prefix=bidsFormPrefix) prizesform = PrizeTicketFormSet(amount=Decimal('0.00'), data=request.POST, prefix=prizeFormPrefix) else: commentform = DonationEntryForm() bidsform = DonationBidFormSet(amount=Decimal('0.00'), prefix=bidsFormPrefix) prizesform = PrizeTicketFormSet(amount=Decimal('0.00'), prefix=prizeFormPrefix) def bid_parent_info(bid): if bid != None: return {'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent) } else: return None def bid_info(bid): result = { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name if bid.suggestions.exists(): result['suggested'] = list(map(lambda x: x.name, bid.suggestions.all())) if bid.allowuseroptions: result['custom'] = ['custom'] result['label'] += ' (select and add a name next to "New Option Name")' return result bids = filters.run_model_query('bidtarget', {'state':'OPENED', 'event':event.id }, user=request.user).distinct().select_related('parent').prefetch_related('suggestions') allPrizes = filters.run_model_query('prize', {'feed': 'current', 'event': event.id }) prizes = allPrizes.filter(ticketdraw=False) dumpArray = [bid_info(o) for o in bids] bidsJson = json.dumps(dumpArray) ticketPrizes = allPrizes.filter(ticketdraw=True) def prize_info(prize): result = {'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'maximumbid': prize.maximumbid} return result dumpArray = [prize_info(o) for o in ticketPrizes.all()] ticketPrizesJson = json.dumps(dumpArray) return tracker_response(request, "tracker/donate.html", { 'event': event, 'bidsform': bidsform, 'prizesform': prizesform, 'commentform': commentform, 'hasBids': bids.count() > 0, 'bidsJson': bidsJson, 'hasTicketPrizes': ticketPrizes.count() > 0, 'ticketPrizesJson': ticketPrizesJson, 'prizes': prizes})
def ipn(request): ipnObj = None if request.method == 'GET' or len(request.POST) == 0: return views_common.tracker_response(request, "tracker/badobject.html", {}) try: ipnObj = paypalutil.create_ipn(request) ipnObj.save() donation = paypalutil.initialize_paypal_donation(ipnObj) donation.save() if donation.transactionstate == 'PENDING': reasonExplanation, ourFault = paypalutil.get_pending_reason_details( ipnObj.pending_reason) if donation.event.pendingdonationemailtemplate: formatContext = { 'event': donation.event, 'donation': donation, 'donor': donation.donor, 'pending_reason': ipnObj.pending_reason, 'reason_info': reasonExplanation if not ourFault else '', } post_office.mail.send( recipients=[donation.donor.email], sender=donation.event.donationemailsender, template=donation.event.pendingdonationemailtemplate, context=formatContext) # some pending reasons can be a problem with the receiver account, we should keep track of them if ourFault: paypalutil.log_ipn(ipnObj, 'Unhandled pending error') elif donation.transactionstate == 'COMPLETED': if donation.event.donationemailtemplate != None: formatContext = { 'donation': donation, 'donor': donation.donor, 'event': donation.event, 'prizes': viewutil.get_donation_prize_info(donation), } post_office.mail.send( recipients=[donation.donor.email], sender=donation.event.donationemailsender, template=donation.event.donationemailtemplate, context=formatContext) agg = filters.run_model_query('donation', { 'event': donation.event.id }).aggregate(amount=Sum('amount')) # TODO: this should eventually share code with the 'search' method, to postbackData = { 'id': donation.id, 'timereceived': str(donation.timereceived), 'comment': donation.comment, 'amount': donation.amount, 'donor__visibility': donation.donor.visibility, 'donor__visiblename': donation.donor.visible_name(), 'new_total': agg['amount'] } postbackJSon = json.dumps( postbackData, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder).encode('utf-8') postbacks = models.PostbackURL.objects.filter(event=donation.event) for postback in postbacks: opener = urllib.request.build_opener() req = urllib.request.Request( postback.url, postbackJSon, headers={ 'Content-Type': 'application/json; charset=utf-8' }) response = opener.open(req, timeout=5) elif donation.transactionstate == 'CANCELLED': # eventually we may want to send out e-mail for some of the possible cases # such as payment reversal due to double-transactions (this has happened before) paypalutil.log_ipn(ipnObj, 'Cancelled/reversed payment') except Exception as inst: # just to make sure we have a record of it somewhere print("ERROR IN IPN RESPONSE, FIX IT") if ipnObj: paypalutil.log_ipn( ipnObj, "{0} \n {1}. POST data : {2}".format( inst, traceback.format_exc(inst), request.POST)) else: viewutil.tracker_log( 'paypal', 'IPN creation failed: {0} \n {1}. POST data : {2}'.format( inst, traceback.format_exc(inst), request.POST)) return HttpResponse("OKAY")
def donate(request, event): event = viewutil.get_event(event) bidsFormPrefix = "bidsform"; prizeFormPrefix = "prizeForm"; if request.method == 'POST': commentform = DonationEntryForm(data=request.POST); if commentform.is_valid(): prizesform = PrizeTicketFormSet(amount=commentform.cleaned_data['amount'], data=request.POST, prefix=prizeFormPrefix); bidsform = DonationBidFormSet(amount=commentform.cleaned_data['amount'], data=request.POST, prefix=bidsFormPrefix); if bidsform.is_valid() and prizesform.is_valid(): try: donation = models.Donation.objects.create(amount=commentform.cleaned_data['amount'], timereceived=pytz.utc.localize(datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=event, testdonation=event.usepaypalsandbox) if commentform.cleaned_data['comment']: donation.comment = commentform.cleaned_data['comment']; donation.commentstate = "PENDING"; if commentform.cleaned_data['hasbid']: donation.bidstate = "FLAGGED"; donation.requestedvisibility = commentform.cleaned_data['requestedvisibility']; donation.requestedalias = commentform.cleaned_data['requestedalias']; donation.requestedemail = commentform.cleaned_data['requestedemail']; donation.currency = event.paypalcurrency; for bidform in bidsform: if 'bid' in bidform.cleaned_data and bidform.cleaned_data['bid']: bid = bidform.cleaned_data['bid']; donation.bids.add(DonationBid(bid=bid, amount=Decimal(bidform.cleaned_data['amount']))); for prizeform in prizesform: if 'prize' in prizeform.cleaned_data and prizeform.cleaned_data['prize']: prize = prizeform.cleaned_data['prize']; donation.tickets.add(PrizeTicket(prize=prize, amount=Decimal(prizeform.cleaned_data['amount']))); donation.full_clean(); donation.save(); except Exception as e: transaction.rollback(); raise e; serverName = request.META['SERVER_NAME']; serverURL = "http://" + serverName; paypal_dict = { "amount": str(donation.amount), "cmd": "_donations", "business": donation.event.paypalemail, "item_name": donation.event.receivername, "notify_url": serverURL + reverse('tracker.views.ipn'), "return_url": serverURL + reverse('tracker.views.paypal_return'), "cancel_return": serverURL + reverse('tracker.views.paypal_cancel'), "custom": str(donation.id) + ":" + donation.domainId, "currency_code": donation.event.paypalcurrency, } # Create the form instance form = PayPalPaymentsForm(button_type="donate", sandbox=donation.event.usepaypalsandbox, initial=paypal_dict) context = {"event": donation.event, "form": form }; return tracker_response(request, "tracker/paypal_redirect.html", context) else: bidsform = DonationBidFormSet(amount=Decimal('0.00'), data=request.POST, prefix=bidsFormPrefix); prizesform = PrizeTicketFormSet(amount=Decimal('0.00'), data=request.POST, prefix=prizeFormPrefix); else: commentform = DonationEntryForm(); bidsform = DonationBidFormSet(amount=Decimal('0.00'), prefix=bidsFormPrefix); prizesform = PrizeTicketFormSet(amount=Decimal('0.00'), prefix=prizeFormPrefix); def bid_label(bid): if not bid.amount: bid.amount = Decimal("0.00"); result = bid.fullname(); if bid.speedrun: result = bid.speedrun.name + " : " + result; result += " $" + ("%0.2f" % bid.amount); if bid.goal: result += " / " + ("%0.2f" % bid.goal); return result; def bid_parent_info(bid): if bid != None: return {'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent) }; else: return None; def bid_info(bid): result = {'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid_label(bid), 'count': bid.count, 'amount': Decimal(bid.amount or '0.00'), 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent)}; if bid.speedrun: result['runname'] = bid.speedrun.name; if bid.suggestions.exists(): result['suggested'] = list(map(lambda x: x.name, bid.suggestions.all())); return result; bids = filters.run_model_query('bidtarget', {'state':'OPENED', 'event':event.id }, user=request.user).select_related('parent').prefetch_related('suggestions'); bids = bids.annotate(**viewutil.ModelAnnotations['bid']); allPrizes = filters.run_model_query('prize', {'feed': 'current', 'event': event.id }) prizes = allPrizes.filter(ticketdraw=False); dumpArray = [bid_info(o) for o in bids.all()]; bidsJson = simplejson.dumps(dumpArray, use_decimal=True); ticketPrizes = allPrizes.filter(ticketdraw=True); def prize_info(prize): result = {'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'maximumbid': prize.maximumbid}; return result; dumpArray = [prize_info(o) for o in ticketPrizes.all()]; ticketPrizesJson = simplejson.dumps(dumpArray, use_decimal=True); return tracker_response(request, "tracker/donate.html", { 'event': event, 'bidsform': bidsform, 'prizesform': prizesform, 'commentform': commentform, 'hasBids': bids.count() > 0, 'bidsJson': bidsJson, 'hasTicketPrizes': ticketPrizes.count() > 0, 'ticketPrizesJson': ticketPrizesJson, 'prizes': prizes});
def donationindex(request, event=None): event = viewutil.get_event(event) orderdict = { 'name': ('donor__lastname', 'donor__firstname'), 'amount': ('amount', ), 'time': ('timereceived', ), } page = request.GET.get('page', 1) sort = request.GET.get('sort', 'time') if sort not in orderdict: sort = 'time' try: order = int(request.GET.get('order', -1)) except ValueError: order = -1 searchForm = DonationSearchForm(request.GET) if not searchForm.is_valid(): return HttpResponse('Invalid Search Data', status=400) searchParams = {} searchParams.update(request.GET) searchParams.update(searchForm.cleaned_data) if event.id: searchParams['event'] = event.id donations = filters.run_model_query('donation', searchParams, user=request.user) donations = views_common.fixorder(donations, orderdict, sort, order) fulllist = request.user.has_perm( 'tracker.view_full_list') and page == 'full' agg = donations.aggregate(amount=Sum('amount'), count=Count('amount'), max=Max('amount'), avg=Avg('amount')) pages = paginator.Paginator(donations, 50) if fulllist: pageinfo = { 'paginator': pages, 'has_previous': False, 'has_next': False, 'paginator.num_pages': pages.num_pages } page = 0 else: try: pageinfo = pages.page(page) except paginator.PageNotAnInteger: pageinfo = pages.page(1) except paginator.EmptyPage: pageinfo = pages.page(paginator.num_pages) page = pages.num_pages donations = pageinfo.object_list return views_common.tracker_response( request, 'tracker/donationindex.html', { 'searchForm': searchForm, 'donations': donations, 'pageinfo': pageinfo, 'page': page, 'fulllist': fulllist, 'agg': agg, 'sort': sort, 'order': order, 'event': event })
'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name if bid.suggestions.exists(): result['suggested'] = list(map(lambda x: x.name, bid.suggestions.all())) if bid.allowuseroptions: result['custom'] = ['custom'] result['label'] += ' (select and add a name next to "New Option Name")' return result bids = filters.run_model_query('bidtarget', {'state':'OPENED', 'event':event.id }, user=request.user).distinct().select_related('parent').prefetch_related('suggestions') allPrizes = filters.run_model_query('prize', {'feed': 'current', 'event': event.id }) prizes = allPrizes.filter(ticketdraw=False) dumpArray = [bid_info(o) for o in bids] bidsJson = json.dumps(dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) ticketPrizes = allPrizes.filter(ticketdraw=True) def prize_info(prize): result = {'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'maximumbid': prize.maximumbid, 'sumdonations': prize.sumdonations} return result