PublicMarkup.org Source Code

Want the source to PublicMarkup.org? Well, here it is! There isn't much to the site, we just wrote some models and glued in the Django comment application. Feel free to use this code...we're placing it in the public domain.

models.py


from django.conf import settings
from django.contrib.comments.models import FreeComment
from django.db import models
from publicmarkup import roman

class Resource(models.Model):
    name = models.CharField(max_length=128, unique=True)
    value = models.TextField()
    class Admin:
        pass
    def __unicode__(self):
        return self.name

class Legislation(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(prepopulate_from=("name",))
    summary = models.TextField(blank=True, null=True)
    class Admin:
        pass
    def get_absolute_url(self):
        return "/bill/%s/" % (self.slug)
    def get_sections_comment_count(self):
        sections = Section.objects.filter(title__legislation=self)
        section_ids = [section.id for section in sections]
        comment_count = FreeComment.objects.filter(object_id__in=section_ids,
            content_type__app_label__exact="legislation",
            content_type__model__exact="section", site__id__exact=settings.SITE_ID).count()
        return comment_count
    def __unicode__(self):
        return self.name
    
class Title(models.Model):
    legislation = models.ForeignKey(Legislation, related_name="titles")
    number = models.IntegerField()
    name = models.CharField(max_length=255)
    summary = models.TextField(blank=True, null=True)
    extra_content = models.TextField(blank=True, null=True)
    class Admin:
        pass
    class Meta:
        ordering = ['number','name']
    def roman_number(self):
        return roman.toRoman(self.number)
    def get_absolute_url(self):
        return "/bill/%s/%i/" % (self.legislation.slug, self.number)
    def get_sections_comment_count(self):
        section_ids = [section.id for section in self.sections.all]
        comment_count = FreeComment.objects.filter(object_id__in=section_ids,
            content_type__app_label__exact="legislation",
            content_type__model__exact="section", site__id__exact=settings.SITE_ID).count()
        return comment_count
    def __unicode__(self):
        return "TITLE %s - %s" % (roman.toRoman(self.number), self.name)

class Section(models.Model):
    title = models.ForeignKey(Title, related_name="sections", edit_inline=True)
    number = models.IntegerField(core=True)
    name = models.CharField(max_length=255, core=True)
    summary = models.TextField(blank=True, null=True)
    text = models.TextField()
    class Admin:
        pass
    class Meta:
        ordering = ['number','name']
    def get_absolute_url(self):
        return "/bill/%s/%i/%i/" % (self.title.legislation.slug, self.title.number, self.number)
    def __unicode__(self):
        return "Sec. %i. %s" % (self.number, self.name)

views.py


from django.conf import settings
from django.contrib.comments.views.comments import post_free_comment
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.views.generic.list_detail import object_list
from publicmarkup.legislation.models import Legislation, Title, Section
from recaptcha.client import captcha

def index(*args, **kwargs):
    return object_list(*args, **kwargs)

def bill(request):
    legislation = Legislation.objects.get(pk=1)
    return HttpResponseRedirect(legislation.get_absolute_url())

def legislation_detail(request, legislation_slug):
    legislation = Legislation.objects.get(slug=legislation_slug)
    return render_to_response("legislation/legislation_detail.html", locals())

def title_detail(request, legislation_slug, title_num):
    title = Title.objects.get(number=title_num, legislation__slug=legislation_slug)
    return render_to_response("legislation/title_detail.html", locals())
    
def section_detail(request, legislation_slug, title_num, section_num):
    section_num = int(section_num)
    section = Section.objects.get(
        number=section_num, title__number=title_num, title__legislation__slug=legislation_slug)
    try:
        next_section = Section.objects.get(
            number=section_num + 1, title__number=title_num, title__legislation__slug=legislation_slug)
    except Section.DoesNotExist:
        next_section = None
    try:
        previous_section = Section.objects.get(
            number=section_num - 1, title__number=title_num, title__legislation__slug=legislation_slug)
    except Section.DoesNotExist:
        previous_section = None
    data = {
        "section": section,
        "next_section": next_section,
        "previous_section": previous_section,
    }
    return render_to_response("legislation/section_detail.html", data)
    
def save_free_comment(request):
    
    if request.POST:
        
        if not request.has_key('preview') and not settings.DEBUG:
        
            recaptcha_resp = captcha.submit(
                recaptcha_challenge_field=request.POST.get('recaptcha_challenge_field'),
                recaptcha_response_field=request.POST.get('recaptcha_response_field'),
                private_key=settings.RECAPTCHA_PRIVATE_KEY,
                remoteip=request.META['REMOTE_ADDR']
            )
        
            if recaptcha_resp.is_valid is False:
                raise Http404, "Invalid Captcha Attempt"
            
        extra_context = {"recaptcha_html": captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY)}
        
        return post_free_comment(request, extra_context)
    
    raise Http404, """All you do is GET, GET, GET. 
        How about you POST every once in a while like you used to at the beginning of our relationship?"""
    
def contact(request):
    return HttpResponseRedirect("/")
    
def legislation_print(request, legislation_slug):
    legislation = Legislation.objects.get(slug=legislation_slug)
    return render_to_response("legislation/legislation_print.html", locals())

The Sunlight Foundation supports, develops and deploys new Internet technologies to make information about Congress and the federal government more accessible to the American people. Through its projects and grant-making, Sunlight serves as a catalyst to create greater political transparency and to foster more openness and accountability in government. This Site may contain links to Internet sites that are not operated by Sunlight Foundation. These links are provided as a service and do not imply any endorsement of the activities or content of these sites, nor any association with their operators. Sunlight Foundation does not control these Internet sites and is not responsible for their content, security, or privacy practices. We urge you to review the privacy policy posted on web sites you visit before using the site or providing personal information.