Skip to content
Browse files

Added documentation to everything.

  • Loading branch information...
1 parent 71ebb51 commit b5b834d8e92fafa29547d39ebf052a836224d079 @ericflo committed Sep 11, 2008
View
15 context_processors.py
@@ -1,13 +1,28 @@
from django.conf import settings
class Counter(object):
+ """
+ A simple counter class which keeps a single integer as private state. Every
+ time ``get_int`` is called, that integer is returned and then incremented
+ internally by one.
+ """
i = 1
def get_int(self):
self.i += 1
return self.i - 1
def production(request):
+ """
+ Serves two purposes:
+
+ 1. To simply put one instance of ``Counter`` into the context for use
+ anywhere within the site.
+
+ 2. To conditionally set a 'MEDIA_SUFFIX' context variable with the value
+ '-prod'. This is used for media files that differ from development to
+ production.
+ """
context = {'counter': Counter()}
if not settings.DEBUG:
context['MEDIA_SUFFIX'] = '-prod'
View
4 events/forms.py
@@ -2,6 +2,10 @@
from events.models import Event
class EventForm(forms.ModelForm):
+ """
+ A simple form for creating a new event, which is a simple description
+ field and that is it.
+ """
description = forms.CharField(max_length=340, widget=forms.Textarea)
class Meta:
View
48 events/models.py
@@ -4,21 +4,46 @@
from django.db.models.query import QuerySet
def today():
+ """
+ Returns a tuple of two datetime instances: the beginning of today, and the
+ end of today.
+ """
now = datetime.now()
start = datetime.min.replace(year=now.year, month=now.month,
day=now.day)
end = (start + timedelta(days=1)) - timedelta.resolution
return (start, end)
class EventQuerySet(QuerySet):
+ """
+ A very simple ``QuerySet`` subclass which adds only one extra method,
+ ``today``, which returns only those objects whose ``creation_date`` falls
+ within the bounds of today.
+ """
def today(self):
+ """
+ Filters down to only those objects whose ``creation_date`` falls within
+ the bounds of today.
+ """
return self.filter(creation_date__range=today())
class EventManager(models.Manager):
+ """
+ A very simple ``Manager`` subclass which returns an ``EventQuerySet``
+ instead of the typical ``QuerySet``. It also includes a proxy for the extra
+ ``today`` method that is provided by the ``EventQuerySet`` subclass.
+ """
def get_query_set(self):
+ """
+ Gets an ``EventQuerySet`` instead of a typical ``QuerySet``.
+ """
return EventQuerySet(self.model)
def today(self):
+ """
+ A proxy method for the extra ``today`` method that is provided by the
+ ``EventQuerySet`` subclass.
+ """
return self.get_query_set().today()
class Event(models.Model):
@@ -32,19 +57,38 @@ class Event(models.Model):
objects = EventManager()
def __unicode__(self):
+ """
+ Returns the first 80 characters of the description, or less, if the
+ description is less than 80 characters.
+ """
if len(self.description) > 80:
return self.description[:76] + ' ...'
return self.description[:80]
def save(self, **kwargs):
+ """
+ First this updates all events created today by the same creator as this
+ event, and sets their ``latest`` field to False.
+
+ Then, this simply saves the object. Since the default for ``latest`` is
+ to be set to True, it will be passed through and saved as the latest
+ event for today by this user.
+ """
Event.objects.today().filter(creator=self.creator).update(latest=False)
super(Event, self).save(**kwargs)
def today(self):
+ """
+ Determines whether this event takes place today or not.
+ """
(start, end) = today()
return self.creation_date >= start and self.creation_date <= end
def description_size(self):
+ """
+ Useful only for display purposes, this designates a label of 'small',
+ 'medium', or 'large' to the description text size.
+ """
if len(self.description) < 120:
return 'small'
elif len(self.description) < 240:
@@ -53,6 +97,10 @@ def description_size(self):
return 'large'
class Attendance(models.Model):
+ """
+ This is the explicit intermediary model mapping ``User`` instances to
+ ``Event`` instances.
+ """
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
registration_date = models.DateTimeField(default=datetime.now)
View
7 events/templatetags/events_tags.py
@@ -3,12 +3,16 @@
from events.models import Attendance
def event(context, e, event_num=1):
+ """
+ Renders a single ``Event`` object.
+ """
to_return = {
'event': e,
'request': context['request'],
'event_num': event_num,
}
if context['user'].is_authenticated():
+ # If the user is authenticated, check if he/she is attending the event.
try:
Attendance.objects.get(event=e, user=context['user'])
attending = True
@@ -23,6 +27,9 @@ def event(context, e, event_num=1):
return to_return
def truncate(input_str, arg):
+ """
+ Truncates a string of characters to a certain length, eliding as necessary.
+ """
try:
input_str = unicode(input_str)
arg = int(arg)
View
38 events/views.py
@@ -11,23 +11,41 @@
from django.core.urlresolvers import reverse
def events(request, template_name='tonight.html', today=True, all_events=False):
+ """
+ Renders a list of ``Event`` instances, which are selected mainly by two
+ parameters:
+
+ today:
+ True if the events should be for today only. In this case, we also
+ order the ``Event`` instances descending by ``start_date``.
+
+ all_events:
+ True if it should be a list of events for everyone. If ``all_events``
+ is set to False, then it will just be a list of events for the logged
+ in user and his/her friends.
+ """
events = Event.objects.filter(latest=True).order_by('-creation_date')
following = []
if request.user.is_authenticated():
+ # If the user is logged in, start building up a list of ``Event``
+ # instances that the user has created or will attend.
my_events = Event.objects.filter(latest=True)
my_events = my_events.filter(creator=request.user) | my_events.filter(
attendance__user=request.user)
my_events = my_events.distinct()
events = events.exclude(creator=request.user)
events = events.exclude(attendance__user=request.user)
if not all_events:
+ # If it's not a list of all events, list just the events that will
+ # happen for the authenticated user's friends.
following = request.user.following_set.all().values('to_user')
events = events.filter(creator__in=[i['to_user'] for i in following]) | \
events.filter(attendance__user__in=[i['to_user'] for i in following])
events = events.distinct()
else:
my_events = Event.objects.none()
if today:
+ # If it is supposed to be today only, filter the results to just today.
events = events.today().order_by('-start_date')
try:
my_events = my_events.today()
@@ -48,6 +66,9 @@ def events(request, template_name='tonight.html', today=True, all_events=False):
)
def event(request, id):
+ """
+ Render a single event.
+ """
event = get_object_or_404(Event, id=id)
return render_to_response(
'events/event_details.html',
@@ -56,11 +77,17 @@ def event(request, id):
)
def create(request):
+ """
+ Renders a form for creating a new ``Event`` instance, validates against that
+ form, and creates the new instances.
+ """
form = EventForm(request.POST or None)
if form.is_valid():
event = form.save(commit=False)
event.creator = request.user
guessed_date = None
+ # Ransack the description for possible datetime objects. If we find one
+ # then we set start_date as that found datetime.
for word in event.description.split():
try:
guessed_date = parse(word)
@@ -74,6 +101,8 @@ def create(request):
else:
next = reverse('ev_tonight')
if request.is_ajax():
+ # If the request is AJAX, then render the created event and don't
+ # create messages for the user.
try:
Attendance.objects.get(event=event, user=request.user)
attending = True
@@ -83,6 +112,8 @@ def create(request):
'request': request, 'attending': attending,
'authenticated': True, 'event_num': 1, 'next': next})
else:
+ # If the request is not AJAX, then create messages for the user and
+ # redirect them to the next page.
request.user.message_set.create(
message=_('Your event was posted.'))
return HttpResponseRedirect(next)
@@ -96,6 +127,9 @@ def create(request):
create = login_required(create)
def toggle_attendance(request):
+ """
+ Toggles whether a user is set to attend an event or not.
+ """
try:
event_id = int(request.POST['event_id'])
except (KeyError, ValueError):
@@ -106,9 +140,12 @@ def toggle_attendance(request):
if not created:
attendance.delete()
if request.is_ajax():
+ # If the request is AJAX, return JSON representing the new count of
+ # people who are attending the event.
json = '{"created": %s, "count": %s}' % (created and 'true' or 'false',
event.attendees.all().count())
return HttpResponse(json, mimetype='application/json')
+ # If the request was not AJAX, create messages for the user.
if created:
request.user.message_set.create(
message=_('You are now attending "%s"') % unicode(event))
@@ -118,6 +155,5 @@ def toggle_attendance(request):
next = request.POST.get('next', '')
#if not next:
# next = reverse('ev_tonight')
- print "Redirecting to %s" % next
return HttpResponseRedirect(next)
toggle_attendance = require_POST(login_required(toggle_attendance))
View
3 profile/templatetags/profile_tags.py
@@ -1,6 +1,9 @@
from django import template
def person(user):
+ """
+ Renders a single user object.
+ """
return {'user': user}
register = template.Library()
View
6 profile/views.py
@@ -6,6 +6,12 @@
from events.models import Event, Attendance
def detail(request, username=None):
+ """
+ Renders information about a single user's profile. This includes
+ information about who follows them, who they follow, mutual followers, the
+ latest events created, and whether the currently logged in user is a friend
+ of the user to render.
+ """
user = get_object_or_404(User, username=username)
events_created = list(Event.objects.filter(creator=user, latest=True).order_by('-creation_date')[:10])
attended = Attendance.objects.filter(user=user).order_by('-registration_date')[:10]
View
3 socialgraph/forms.py
@@ -1,4 +1,7 @@
from django import forms
class SearchForm(forms.Form):
+ """
+ A simple search form with a query input.
+ """
q = forms.CharField(max_length=50)
View
8 socialgraph/models.py
@@ -3,6 +3,10 @@
from django.contrib.auth.models import User
class UserLink(models.Model):
+ """
+ A single directed edge in the social graph. Usually represented as the
+ verb "follows".
+ """
from_user = models.ForeignKey(User, related_name='following_set')
to_user = models.ForeignKey(User, related_name='follower_set')
date_added = models.DateTimeField(default=datetime.now)
@@ -12,6 +16,10 @@ def __unicode__(self):
self.to_user.username)
def save(self, **kwargs):
+ """
+ A mostly-generic save method, except that it validates that the user
+ is not attempting to follow themselves.
+ """
if self.from_user == self.to_user:
raise ValueError("Cannot follow yourself.")
super(UserLink, self).save(**kwargs)
View
20 socialgraph/templatetags/socialgraph_tags.py
@@ -3,15 +3,14 @@
def do_dict_entry_for_item(parser, token):
"""
- Given an object and a dictionary keyed with object ids - as
- returned by the ``votes_by_user`` and ``scores_for_objects``
- template tags - retrieves the value for the given object and
- stores it in a context variable, storing ``None`` if no value
- exists for the given object.
+ Given an object and a dictionary keyed with object ids - as returned by the
+ ``friends_for_user`` template tag - retrieves the value for the given object
+ and stores it in a context variable, storing ``None`` if no value exists
+ for the given object.
Example usage::
- {% dict_entry_for_item widget from vote_dict as vote %}
+ {% dict_entry_for_item user.username from friend_dict as friend %}
"""
bits = token.contents.split()
if len(bits) != 6:
@@ -41,7 +40,14 @@ def render(self, context):
return ''
def do_friends_for_user(parser, token):
- "{% friends_for_user user as friend_dict %}"
+ """
+ Gets the users that the given user follows, and saves that into a
+ dictionary keyed by username.
+
+ Usage:
+
+ {% friends_for_user user as friend_dict %}
+ """
bits = token.contents.split()
if len(bits) != 4:
raise template.TemplateSyntaxError(
View
10 socialgraph/util.py
@@ -2,14 +2,24 @@
from socialgraph.models import UserLink
def get_people_user_follows(user):
+ """
+ Returns a ``QuerySet`` representing the users that the given user follows.
+ """
ul = UserLink.objects.filter(from_user=user).values('to_user')
return User.objects.filter(id__in=[i['to_user'] for i in ul])
def get_people_following_user(user):
+ """
+ Returns a ``QuerySet`` representing the users that follow the given user.
+ """
ul = UserLink.objects.filter(to_user=user).values('from_user')
return User.objects.filter(id__in=[i['from_user'] for i in ul])
def get_mutual_followers(user):
+ """
+ Returns a ``QuerySet`` representing the users that the given user follows,
+ who also follow the given user back.
+ """
follows = UserLink.objects.filter(from_user=user).values('to_user')
following = UserLink.objects.filter(to_user=user).values('from_user')
follows_set = set([i['to_user'] for i in follows])
View
18 socialgraph/views.py
@@ -27,6 +27,11 @@ def _get_next(request):
}
def friend_list(request, list_type, username):
+ """
+ Renders a list of friends, as returned by the function retrieved from the
+ ``FRIEND_FUNCTION_MAP``, given the user specified by the username in the
+ URL.
+ """
user = get_object_or_404(User, username=username)
context = {
'list_type': list_type,
@@ -39,6 +44,10 @@ def friend_list(request, list_type, username):
)
def follow(request, username):
+ """
+ Adds a "following" edge from the authenticated user to the user specified by
+ the username in the URL.
+ """
user = get_object_or_404(User, username=username)
ul, created = UserLink.objects.get_or_create(from_user=request.user,
to_user=user)
@@ -59,6 +68,10 @@ def follow(request, username):
follow = login_required(follow)
def unfollow(request, username):
+ """
+ Removes a "following" edge from the authenticated user to the user specified
+ by the username in the URL.
+ """
user = get_object_or_404(User, username=username)
try:
ul = UserLink.objects.get(from_user=request.user, to_user=user)
@@ -83,6 +96,11 @@ def unfollow(request, username):
unfollow = login_required(unfollow)
def find_and_add(request):
+ """
+ A page for finding and adding new friends to follow. Right now this
+ consists solely of a search box, which given input, renders a list of
+ users who match the search terms.
+ """
search_form = SearchForm(request.GET or None)
context = {
'search_form': search_form,
View
4 views.py
@@ -3,6 +3,10 @@
from django.http import HttpResponseRedirect
def index(request):
+ """
+ A proxy view for either the ``direct_to_template`` generic view, or to
+ a redirect, depending on whether the user is authenticated.
+ """
if request.user.is_authenticated():
return HttpResponseRedirect(reverse('ev_tonight'))
return direct_to_template(request, template='index.html')

0 comments on commit b5b834d

Please sign in to comment.
Something went wrong with that request. Please try again.