placeuvote / gaepuv / puv / poll / views.py

import os
from django.http import HttpResponse, HttpResponseRedirect
from puv.poll import models
from puv.poll.forms import *
from django.shortcuts import render_to_response
from puv.settings import *
from puv.poll.utils import getGeoIPCode, mail_poll
from datetime import datetime
# from google.appengine.api import memcache
from django.views.decorators.cache import cache_page

APP_ID = os.environ['APPLICATION_ID'] 
VERSION = os.environ.get('CURRENT_VERSION_ID','0') 
NUM_LOCATIONS = 3
NUM_DATES = 0
MARKER_JS = '''
       var latLng = new google.maps.LatLng(%(latlng)s);
       markers[%(i)s] = new google.maps.Marker({
         position: latLng,
         icon: "/media/marker/green%(num)s.png",
         title: '%(title)s',
         map: map,
         draggable: false
       });
       '''

@cache_page(600)
def get_home(request):
    """ Checks the cache to for home page or sets it - time = 10 mins by default """
    polls = models.Poll.all().order('-created_on').filter('private =', False).fetch(20)
    return render_to_response('index.html', {'polls':polls})

def feed(request, template='atom.xml', user=None):
    """ Get atom or rss feed of polls - latest or for user 
        NB: Add cache when this is finalised for Android app
    """
    props = {'appversion': '%s-%s' % (APP_ID, VERSION)}
    polls = models.Poll.all().order('-created_on').filter('private =', False).fetch(20)
    if polls:
        props['polls'] = polls
        props['last'] = polls[0].created_on
    return render_to_response(template, props)

def index(request, template='index.html'):
    """ Used for listing polls on the home page, vote index and results index pages """
    if template == 'index.html':
        return get_home(request)
    else:
        polls = models.Poll.all().order('-created_on').filter('private =', False).fetch(20)
        return render_to_response(template, {'polls':polls})

def start_location(request):
    """ Use ip address to get country for starting point """
    client = request.META.get('REMOTE_HOST', request.META.get('REMOTE_ADDR',''))
    iso, location = getGeoIPCode(client)
    if not location:
        location = u"%f, %f" % (DEFAULT_LAT, DEFAULT_LNG)
    return iso, {'choice':USE_ADDR,'location':location}

def create(request):
    """ Create a poll form """
    country, initial = start_location(request)
    try:
        startlat = str(initial['location'].lat)
        startlng = str(initial['location'].lon)
    except:
        startlat = DEFAULT_LAT
        startlng = DEFAULT_LNG
    choiceforms = []
    dates = []
    # New poll form
    if request.method == 'GET':
        locations = NUM_LOCATIONS
        dates = NUM_DATES
        pollform = PollForm()
        for i in range(locations):
            choiceforms.append(ChoiceForm(prefix = 'f%s'%i, initial = initial))
    # Write posted poll
    if request.method == 'POST':
        pollform = PollForm(request.POST)
        choiceform = ChoiceForm()
        locations = int(request.POST.get('locations', NUM_LOCATIONS))
        if pollform.is_valid():
            poll = pollform.save()
            if request.POST.get('createpoll',''):
                datetxt = request.POST.get('date_text','')
                if datetxt:
                    dates = datetxt.split(',')
                    for dt in dates:
                        try:
                            m, d, y = dt.split('/')
                            date = datetime(int(y),int(m),int(d))
                        except:
                            date = None
                        if date:
                            date = models.DateChoice(poll=poll, datetime=date)
                            date.save()
                for i in range(locations):
                    choiceforms.append(ChoiceForm(poll=poll, prefix = 'f%s'%i, 
                                       initial = initial, data=request.POST))
                for form in choiceforms:
                    if form.is_valid():
                        form.save()
                if poll.email:
                    # Send email and record if an invalid email was entered 
                    if not mail_poll(poll):
                        poll.email = 'FAIL'
                        poll.save()
                return HttpResponseRedirect(poll.get_absolute_url())
        for i in range(locations):
            choiceforms.append(ChoiceForm(prefix = 'f%s'%i, 
                               initial = initial, data=request.POST))
    # Javacript
    js = GMAP_JS
    js[-2] = map_init(country, startlat, startlng)
    js[-1] = new_overlay(locations, startlat, startlng)
    props = {'pollform' : pollform, 
             'choiceforms' : choiceforms,
             'locations' : locations,
             'dates' : dates,
             'genjs' : js
              }
    return render_to_response('create.html', props)

def map_init(country, lat=DEFAULT_LAT, lng=DEFAULT_LNG):
    """ Create initial map based on country """
    mapdict = MAP_INIT
    mapdict['lat'] = lat
    mapdict['lng'] = lng
    mapdict['country'] = country
    js = GMAP_FUNC_JS % mapdict
    return '<script type="text/javascript">%s</script>' % js

def generate_overlay(choices):
    """ Create google maps overlay from choices """
    js = ''
    for i, choice in enumerate(choices):
        js += MARKER_JS % dict(latlng=choice.location, title=choice.choice, num = i+1, i=i)
    return '''<script type="text/javascript">
                 function load_overlay(map, latLng){
                    var markers = Array();
                    %s
                    zoom_markers(map, markers); 
                    return markers;
                 } 
               </script>''' % js

def new_overlay(num_choices=NUM_LOCATIONS, lat=DEFAULT_LAT, lng=DEFAULT_LNG):
    """ Create new google maps overlay for a number of choices """
    return '''<script type="text/javascript">
                 var latLng = new google.maps.LatLng(%s, %s);  
                 function load_overlay(map, latLng){
                    initialize_form();
                    add_date();
                    return new_map(map, latLng, %d);
                 } 
               </script>''' % (lat, lng, num_choices)

def poll_results(request, poll_key):
    """ Return the poll results for display """
    poll = models.Poll.get(poll_key)
    if not poll:
        return render_to_response('poll_not_found.html')
    choices = models.Choice.all().order('-votes').filter('poll =',poll)
    dates = models.DateChoice.all().order('-votes').filter('poll =',poll)
    if dates.count()==0:
        dates = None
    props = dict(poll = poll, choices = choices, dates = dates)
    return render_to_response('poll_results.html', props)

def poll_results_xml(request, poll_key):
    """ Return the poll and results as xml """
    poll = models.Poll.get(poll_key)
    if not poll:
        return render_to_response('<poll />')
    choices = models.Choice.all().order('-votes').filter('poll =',poll)
    dates = models.DateChoice.all().order('-votes').filter('poll =',poll)
    if dates.count()==0:
        dates = []
    response = HttpResponse(mimetype="application/xml")
    xml = poll.to_xml()
    xml = xml.replace('<entity',
                      '''<poll xmlns:gd="http://schemas.google.com/g/2005"
                               xmlns:georss="http://www.georss.org/georss" 
                      ''')
    xml = xml.replace('</entity>','')
    for choice in choices:
        xml += choice.to_xml()
        if not poll.anonymous:
            voters = ''
            for voter in choice.voter_set:
                voters += voter.to_xml()
            xml = xml.replace('</entity>','%s</entity>' % voters) 
    for date in dates:
        xml += date.to_xml()
    xml += '</poll>'
    response.write(xml)
    return response

def poll_detail(request, poll_key):
    """ Vote in a poll """
    poll = models.Poll.get(poll_key)
    if not poll:
        return render_to_response('poll_not_found.html')
    if poll.onechoice:
        input_type = 'radio'
    else:
        input_type = 'checkbox'
    choices = models.Choice.all().filter('poll = ', poll)
    if choices.count() == 1:
        nochoice = choices[0]
    else:
        nochoice = None
    dates = models.DateChoice.all().filter('poll = ', poll)

    # Record the vote
    if request.method == 'POST':
        created_by = request.POST.get('created_by','')
        if nochoice:
            choice_keys = []
        else:
            choice_keys = request.POST.getlist('location')
            for choice_key in choice_keys:
                choice = models.Choice.get(choice_key)
                choice.votes += 1
                choice.put()
                if not poll.anonymous and created_by:
                    voter = models.Voter(poll = poll,
                                         choice = choice,
                                         created_by = created_by)
                    voter.save()
        date_keys = request.POST.getlist('date')
        for date_key in date_keys:
            datechoice = models.DateChoice.get(date_key)
            datechoice.votes += 1
            datechoice.put()
            if not poll.anonymous and created_by:
                voter = models.Voter(poll = poll,
                                     datechoice = datechoice,
                                     created_by = created_by)
                voter.save()
        poll.total_votes += 1
        poll.save()
        return HttpResponseRedirect('./results/')
    js = GMAP_JS
    js[-1] =  generate_overlay(choices)
    props = { 'poll' : poll, 
              'choices' : choices,
              'nochoice' : nochoice,
              'dates'  : dates, 
              'genjs' : js,
              'input_type' : input_type
            }
    return render_to_response('poll_details.html', props)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.