Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Livni authored and Josh Livni committed Nov 7, 2010
0 parents commit bba8169
Show file tree
Hide file tree
Showing 768 changed files with 79,124 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@




*.pyc
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Authors:
Josh Livni
Kelaine Vargas

This file is part of the Urban Forest Map.

Urban Forest Map is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Urban Forest Map is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Urban Forest Map. If not, see <http://www.gnu.org/licenses/>.

13 changes: 13 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Installation Instructions
------------

* psycopg2, postgis, gdal, geos, proj4, python-mapnik, ...

* VirtualEnv
cd <installation-directory>
virtualenv .
source ./bin/activate
#put sourcecode into ./sftrees
cd sftrees
pip install -r requirements.txt

Empty file added __init__.py
Empty file.
1 change: 1 addition & 0 deletions classfaves/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

17 changes: 17 additions & 0 deletions classfaves/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import datetime

from django.db import models

from django.contrib.auth.models import User

class FavoriteBase(models.Model):
"""
This is the abstract base class that you will subclass to create your own
domain-specific Favorite model.
"""
user = models.ForeignKey(User)

date_created = models.DateTimeField(default=datetime.datetime.now)

class Meta(object):
abstract = True
5 changes: 5 additions & 0 deletions classfaves/templates/favorites/created.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "base.html" %}

{% block content %}
<p>Favorited {{ item }}</p>
{% endblock %}
5 changes: 5 additions & 0 deletions classfaves/templates/favorites/deleted.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "base.html" %}

{% block content %}
<p>Un-Favorited {{ item }}</p>
{% endblock %}
12 changes: 12 additions & 0 deletions classfaves/templates/favorites/list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "template_3.html" %}

{% block right_panel %}
<p>Favorites for {{ favorite_user }}:</p>
<ul>
{% for favorite in favorites %}
<li><a href="{{ favorite.get_absolute_url }}">{{ favorite }}</a></li>
{% empty %}
<li>No Favorites</li>
{% endfor %}
</ul>
{% endblock %}
299 changes: 299 additions & 0 deletions classfaves/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.db import transaction
from django.core import serializers
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect

from django.contrib.auth.models import User

RESPONSE_MAPPING = {
'application/json': 'json',
'text/xml': 'xml',
}

class FavoriteBase(object):
"""
This is the base class that all of the class-based views for this app
will subclass.
"""
def __init__(self, favorite, content_model, fk_name=None, extra_context={},
context_init=RequestContext, next_field='next',
response_mapping=RESPONSE_MAPPING, use_transactions=True):
self.favorite = favorite
self.content_model = content_model
self.extra_context = extra_context
self.context_init = context_init
self.response_mapping = response_mapping
self.next_field = next_field
self.use_transactions = use_transactions

# If we have no explicitly-set foreign key name, we attempt to
# determine that information by traversing all of the related fields
# and choose the first one that relates to the content model
if fk_name is None:
for field in self.favorite._meta.fields:
if field.rel and field.rel.to == self.content_model:
fk_name = field.name
break
if fk_name is None:
raise ValueError('Could not find related field between %s and '
'%s. Please either specify it to %s using the keyword '
'argument fk_name, and ensure that your models are '
'constructed properly' % (
self.favorite, self.content_model, self.__class__.__name__
)
)
self.fk_name = fk_name

def __call__(self, request, *args, **kwargs):
"""
By implementing the call method, we allow the class itself to act as
the view function, taking in the request object and returning the
response. This method is responsible for dealing with transaction
management, dispatching to the proper instance methods, and returning
a valid HttpResponse.
"""
if self.use_transactions:
transaction.commit_unless_managed()
transaction.enter_transaction_management()
transaction.managed(True)

context = self.view(request, *args, **kwargs)
if isinstance(context, HttpResponseRedirect):
return context
context.update(self.extra_context)

if self.next_field in request.REQUEST:
next = request.REQUEST[self.next_field]
if ':/' not in next:
return HttpResponseRedirect(next)

response = self.create_response(request, context)
if self.use_transactions:
transaction.commit()
transaction.leave_transaction_management()

return response

def create_response(self, request, context):
"""
This method receives the proper context variables and, based upon the
``HTTP_ACCEPT`` from the request, it will dispatch the context to the
proper method for creating HttpResponse objects. This could involve
rendering HTML using templates, or it could simply be serialization
using one of JSON or XML renderers.
"""
try:
http_accept = request.META['HTTP_ACCEPT'].split(',')[0]
except (KeyError, IndexError):
http_accept = None
response_kind = self.response_mapping.get(http_accept, 'html')
context_instance = None
if response_kind == 'html':
context_instance = self.context_init(request)
responder = getattr(self, response_kind)
return responder(context, context_instance=context_instance)

def json(self, context, context_instance):
"""
Given some context variables, this method returns a JSON representation
of those variables.
"""
raise NotImplemented

def xml(self, context, context_instance):
"""
Given some context variables, this method returns an XML representation
of those variables.
"""
raise NotImplemented

def html(self, context, context_instance):
"""
Given some context variables, this method returns rendered HTML for
those variables.
"""
raise NotImplemented


class CreateFavorite(FavoriteBase):
"""
This is a class that allows for the favoriting of your content objects.
"""
def __init__(self, *args, **kwargs):
self.template_name = kwargs.pop('template_name',
'favorites/created.html')
super(CreateFavorite, self).__init__(*args, **kwargs)

def json(self, context, context_instance):
"""
Given some context variables, this method returns a JSON representation
of those variables.
"""
data = serializers.serialize('json', [context['favorite']])
return HttpResponse(data, content_type='application/json')

def xml(self, context, context_instance):
"""
Given some context variables, this method returns an XML representation
of those variables.
"""
data = serializers.serialize('xml', [context['favorite']])
return HttpResponse(data, content_type='text/xml')

def html(self, context, context_instance):
"""
Given some context variables, this method returns rendered HTML for
those variables.
"""
return render_to_response(self.template_name, context,
context_instance=context_instance)

def view(self, request, pk=None):
"""
Given the request and a primary key (of the content object), this
method is responsible for returning a dictionary of context variables
suitable for being passed to one of the serialization methods.
"""
if not request.user.is_authenticated():
return HttpResponseRedirect('%s?next=%s' % (
settings.LOGIN_URL,
request.path,
))
content_object = get_object_or_404(self.content_model, pk=pk)
favorite, created = self.favorite.objects.get_or_create(**{
'user': request.user,
self.fk_name: content_object,
})
return {'favorite': favorite, 'created': created, 'item': content_object}


class DeleteFavorite(FavoriteBase):
"""
This is a class that allows for the un-favoriting of your content objects.
"""
def __init__(self, *args, **kwargs):
self.template_name = kwargs.pop('template_name',
'favorites/deleted.html')
super(DeleteFavorite, self).__init__(*args, **kwargs)

def json(self, context, context_instance):
"""
Given some context variables, this method returns a JSON representation
of those variables.
"""
data = serializers.serialize('json', [context['item']])
return HttpResponse(data, content_type='application/json')

def xml(self, context, context_instance):
"""
Given some context variables, this method returns an XML representation
of those variables.
"""
data = serializers.serialize('xml', [context['item']])
return HttpResponse(data, content_type='text/xml')

def html(self, context, context_instance):
"""
Given some context variables, this method returns rendered HTML for
those variables.
"""
return render_to_response(self.template_name, context,
context_instance=context_instance)

def view(self, request, pk=None):
"""
Given the request and a primary key (of the content object), this
method is responsible for returning a dictionary of context variables
suitable for being passed to one of the serialization methods.
"""
if not request.user.is_authenticated():
return HttpResponseRedirect('%s?next=%s' % (
settings.LOGIN_URL,
request.path,
))
content_object = get_object_or_404(self.content_model, pk=pk)
favorites = self.favorite.objects.filter(**{
'user': request.user,
self.fk_name: content_object,
})
i = 0
for i, favorite in enumerate(favorites):
favorite.delete()
return {
'num_deleted': i,
'item': content_object,
self.fk_name: content_object,
}

class UserFavorites(FavoriteBase):
"""
This is a class that can produce a list of a user's favorite content
objects.
"""
def __init__(self, *args, **kwargs):
self.template_name = kwargs.pop('template_name',
'favorites/list.html')
self.extra_filter = kwargs.pop('extra_filter', lambda x: x)
super(UserFavorites, self).__init__(*args, **kwargs)

def json(self, context, context_instance):
"""
Given some context variables, this method returns a JSON representation
of those variables.
"""
data = serializers.serialize('json', context['favorites'])
return HttpResponse(data, content_type='application/json')

def xml(self, context, context_instance):
"""
Given some context variables, this method returns an XML representation
of those variables.
"""
data = serializers.serialize('xml', context['favorites'])
return HttpResponse(data, content_type='text/xml')

def html(self, context, context_instance):
"""
Given some context variables, this method returns rendered HTML for
those variables.
"""
return render_to_response(self.template_name, context,
context_instance=context_instance)

def view(self, request, username=None):
"""
Given the request and a primary key (of the content object), this
method is responsible for returning a dictionary of context variables
suitable for being passed to one of the serialization methods.
"""
# The username can be None, but then the user must be logged in.
# If the username is None and the user's not logged in, we redirect
# them to the login page
if username is None:
if not request.user.is_authenticated():
return HttpResponseRedirect('%s?next=%s' % (
settings.LOGIN_URL,
request.path,
))
user = request.user
else:
user = get_object_or_404(User, username__iexact=username)

# Sometimes it can be useful to know if the user is looking at their
# own page, so we determine that as a convenience
is_self = user == request.user

# TODO: Can the following queries be made more efficient?
base_faves = self.favorite.objects.filter(user=user)
content_ids = self.extra_filter(base_faves).values_list(self.fk_name,
flat=True).query
# TODO: Ensure that the content models are returned in order of when
# they were favorited.
favorites = self.content_model.objects.filter(pk__in=content_ids)
return {
'favorites': favorites,
'favorite_user': user,
'is_self': is_self,
}
Loading

0 comments on commit bba8169

Please sign in to comment.