Source

genmap / profile / views.py

# -*- coding: utf-8
from subprocess import Popen, PIPE
from django.utils.translation import ugettext as _
from django.utils.simplejson.encoder import JSONEncoder
from django.shortcuts import render_to_response,get_object_or_404
from django.template import RequestContext,Context,Template
from django.template.loader import render_to_string
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.http import HttpResponseBadRequest
from django.db.transaction import commit_on_success
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.conf import settings
from django.views.decorators.cache import cache_page
from django.contrib.gis.geos import *
from django.contrib.gis.measure import D

if settings.GRAVATAR:
    from gravatar.templatetags.gravatar_tags import gravatar_for_user


from genmap.profile.models import *
from genmap.profile.forms import *
from genmap.utils.flashmsg import flashmsg

import time

import jaxml

#@cache_page( 60 * 15 )
def index(request):
    """
    Front page.
    """
    # TODO fragment caching on the part that displayes profile counts for each country
    countries = Country.objects.all()
    country_list = []
    for country in countries:
        profile_count = Profile.objects.filter(country=country).count()
        if profile_count:
            country_list.append( [ country,profile_count] )


    return render_to_response('index.html',
            {
                'country_list':country_list,

                },
        context_instance=RequestContext(request))



def do_ajax_update(request):
    """
    This is an AJAX view that updates the map when it is moved,zoomed,etc.

    This way we don't send thousands of markers to a browser. Just the ones he
    needs to view his portion of the map.
    """

    x1 = sw_lat = request.POST.get('swlat',None) #x1
    y1 = sw_lng = request.POST.get('swlng',None) #y1
    x2 = ne_lat = request.POST.get('nelat',None) #x2
    y2 = ne_lng = request.POST.get('nelng',None) #y2

    if not (x1 and x2 and y1 and y2):
        return HttpResponseBadRequest("Invalid paremeters")

    filter = request.POST.get('filter',None)
    country = request.POST.get('country',None)
    zoom = request.POST.get('zoom',None)
    init = request.POST.get('init',None)
    try:
        zoom = int(zoom)
    except:
        zoom = 1


    rect_points = (x1,y1,x2,y1,x2,y2,x1,y2,x1,y1)
    rect_str = "POLYGON((%s %s, %s %s , %s %s , %s %s , %s %s))"%rect_points
    rect= GEOSGeometry(rect_str)

    marks = Profile.objects.filter(point__within=rect)

    limited = False # We have done no limiting of the results


    if zoom:
        #TODO check zoom level number to be nice
        if zoom < 8:
            #country filter only works above a certain zoom level
            #to facilitate the country views.
            #by zooming in more, you can get all people from all countries
            if country:
                try:
                    country_obj = Country.objects.get(code=country)
                    marks = marks.filter(country = country_obj)
                except Country.DoesNotExist:
                    pass

            #with low zoom level we limit the number of results
            marks = marks[:50] #FIXME find the best number here
            limited = True

    if filter:
        marks = marks.filter(category=filter)


    count = marks.count()
    if count > 200:
        marks = marks[:200]
        limited = True

    limit = 0
    if limited:
        count = marks.count()
        limit = count

    #Create XML response
    doc = jaxml.XML_document()
    doc.markers(limited=limited,limit=limit)
    for mark in marks:
        mark_country = mark.country
        doc._push()
        if mark.avatar:
            thumbnail =  unicode(mark.avatar.thumbnail)
        elif settings.GRAVATAR:
            thumbnail = gravatar_for_user(mark.user, 50)
        else:
            thumbnail = settings.DEFAULT_AVATAR
        url = reverse('view-profile',args = [mark.user.username])
        name = mark.user.get_full_name()
        doc.marker(lat=mark.point.x,lng=mark.point.y,
                country=mark_country.name,region=mark.region,
                countrycode = mark_country.code.lower() ,
                thumbnail=thumbnail,category=mark.get_category_display(),
                url=url,name=name)
        doc._pop()
    #time.sleep(2)
    return HttpResponse(str(doc))

@login_required
def add(request):
    """
    Add a profile
    """
    user =request.user


    if request.POST:
        try:
            nameform = UserForm(request.REQUEST,
                        initial={'first_name':user.first_name,
                            'last_name':user.last_name}
                        )
            form = AddProfileForm( request.REQUEST, request.FILES,
                    instance=user.get_profile())
        except:
            nameform = UserForm(request.REQUEST)
            form = AddProfileForm( request.REQUEST, request.FILES)
        if form.is_valid() and nameform.is_valid():
            #set first and last names
            name_data = nameform.cleaned_data
            data = form.cleaned_data
            user.first_name = name_data['first_name']
            user.last_name = name_data['last_name']
            user.save()
            #create profile
            new_profile = form.save(commit=False)
            new_profile.user = user
            x = float(data['latitude'])
            y = float(data['longitude'])
            new_profile.point =  Point(x,y)

            new_profile.save()

            return HttpResponseRedirect( reverse('view-profile',args=[user.username]) )

        else:
            return render_to_response('marks/add.html',
                    {'form':form,
                        'nameform':nameform},
                context_instance=RequestContext(request))
    else:
        try:
            profile = user.get_profile()
            form = AddProfileForm(instance=profile)
            nameform = UserForm(
                    initial={'first_name':user.first_name,
                        'last_name':user.last_name}
                    )

        except:
            profile = None
            form = AddProfileForm()
            nameform = UserForm()
        return render_to_response('marks/add.html',
            {'form':form,
                'profile':profile,
                'nameform':nameform},
        context_instance=RequestContext(request))


#@cache_page( 60 * 2 )
#TODO find a way to _aggressively_ cache this page, but invalidate cache when user updates
#his profile
def view_profile(request,username):
    """
    View a profile
    """

    page_user = get_object_or_404(User, username=username)
    try:
        profile = page_user.get_profile()
    except:
        if page_user == request.user:
            flashmsg(request,_("Create profile"),
                    _("You must fill in your profile and map info first"))
            return HttpResponseRedirect(reverse("add-profile"))
        else:
            flashmsg(request,_("No profile"),
                    _("User has not created a profile yet. Sorry"))
            return HttpResponseRedirect(reverse("search") )

    category_form = CategoryFilterForm()

    nearest_profiles = Profile.objects.filter(
            #point__distance_lte = (profile.point, D(km=30 ) ),
            )
    nearest_profiles =  nearest_profiles.distance(profile.point)
    #exclude the profile we are viewing
    nearest_profiles = nearest_profiles.exclude(pk = profile.id)

    nearest_profiles = nearest_profiles.order_by('distance')
    nearest_profiles = nearest_profiles[:8]

    return render_to_response('marks/view.html',
            {'mark':profile,
                'page_user':page_user,
                'category_form':category_form,
                'nearest_profiles':nearest_profiles,
                },
        context_instance=RequestContext(request))

@login_required
def view_own_profile(request):
    return HttpResponseRedirect(reverse("add-profile"))

def view_blank(request):
    """
    View the map starting from zoomed out world map
    """
    return render_to_response('marks/view_blank.html',
            {},
        context_instance=RequestContext(request))


def view_country(request,code):
    """
    View all profiles within a country
    """
    # TODO this probably needs pagination since some countries
    # have a lot of profiles
    country = get_object_or_404(Country,code=code)
    profiles = country.profile_set.all()

    return render_to_response('marks/view_blank.html',
            {'country':country,
                'profiles':profiles,
                },
        context_instance=RequestContext(request))

def about(request):
    """
    View the about page
    """
    profile_count = Profile.objects.count()
    
    revision = dict()
    try:
        from mercurial import ui, hg, commands
        ui = ui.ui()
        PROJECT_ROOT = getattr(settings,'PROJECT_ROOT','.')
        repo = hg.repository(ui, PROJECT_ROOT)
        ui.pushbuffer()
        commands.identify(ui,repo,id=True,num=True)
        revision.update(dict(zip(('i','n'),ui.popbuffer().split())))
    except ImportError:
        # Hmm, If we get an ImportError here i doubt that the 'hg' command will
        # work. It uses the same Python API.
        revision['i'] = Popen(['hg', 'identify', '-i'], stdout = PIPE).communicate()[0].strip()
        revision['n'] = Popen(['hg', 'identify', '-n'], stdout = PIPE).communicate()[0].strip()

    return render_to_response('about.html',
            {
                'revision': revision,
                'profile_count':profile_count,
                },
        context_instance=RequestContext(request))

def privacy(request):
    """
    The privacy statement page
    """
    return render_to_response('privacy.html',
            {},
        context_instance=RequestContext(request))
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.