Changeset - 2bf594b86cb1
www/conservancy/apps/blog/urls.py
Show inline comments
 
from django.conf.urls.defaults import *
 
from django.conf.urls import patterns, url, include
 
from models import Entry, EntryTag # relative import
 
from views import last_name # relative import
 
from conservancy.apps.staff.models import Person
 
from datetime import datetime
 
from views import last_name, BlogYearArchiveView, BlogMonthArchiveView, BlogDayArchiveView, BlogDateDetailView
 

	
 
extra_context = {}
 

	
 
info_dict = {
 
    'queryset': Entry.objects.all(),
 
    'date_field': 'pub_date',
 
    'extra_context': extra_context,
 
}
 

	
 
urlpatterns = patterns('django.views.generic.date_based',
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict),
 
   (r'^(?P<year>\d{4})/$', 'archive_year', dict(info_dict,
 
                                                make_object_list=True)),
 
# urlpatterns = patterns('django.views.generic.date_based',
 
urlpatterns = patterns('',
 
   # (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
 
   # (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict),
 
   # (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict),
 
   # (r'^(?P<year>\d{4})/$', 'archive_year', dict(info_dict,
 
   #                                              make_object_list=True)),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', BlogDateDetailView.as_view(**info_dict)),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', BlogDayArchiveView.as_view(**info_dict)),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', BlogMonthArchiveView.as_view(**info_dict)),
 
   (r'^(?P<year>\d{4})/$', BlogYearArchiveView.as_view(**info_dict)),
 
)
 

	
 
urlpatterns += patterns('conservancy.apps.blog.views',
 
   (r'^/?$', 'custom_index', dict(info_dict, paginate_by=10)),
 
   (r'^query/$', 'query'),
 
)
 

	
 
# Code to display authors and tags on each blog page
 

	
 
def all_tags_by_use_amount():
 
    """Returns all tags with an added 'cnt' attribute (how many times used)
 

	
 
    Also sorts the tags so most-used tags appear first.
 
    """
 

	
 
    # tally use amount
 
    retval = []
 
    current = None
 
    for obj in EntryTag.objects.filter(entry__pub_date__lte=datetime.now(),
 
                                       entry__isnull=False).order_by('label'):
 
        if current is not None and obj.id == current.id:
 
            current.cnt += 1
 
        else:
 
            if current is not None:
 
                retval.append(current)
 
            current = obj
 
            current.cnt = 1
 
    if current is not None:
 
        retval.append(current)
 

	
 
    # sort and return
 
    retval.sort(key=lambda x: -x.cnt)
 
    return retval
 

	
 
def all_authors():
 
    return sorted(Person.objects.filter(entry__isnull=False).distinct(),
 
                  key=last_name)
 

	
 
# The functions are passed to the context uncalled so they will be
 
# called for each web request.  If we want to only make these database
 
# queries a single time when a web server process begins, call both
 
# functions below (i.e. make both lines below end in '()')
 

	
 
extra_context['all_authors'] = all_authors
 
extra_context['all_tags'] = all_tags_by_use_amount
www/conservancy/apps/blog/views.py
Show inline comments
 
from models import Entry, EntryTag # relative import
 
from django.views.generic.list_detail import object_list
 
# from django.views.generic.list_detail import object_list
 
from django.views.generic import ListView
 
from django.views.generic.dates import YearArchiveView, MonthArchiveView, DayArchiveView, DateDetailView
 
from conservancy.apps.staff.models import Person
 
from django.shortcuts import get_object_or_404, render_to_response
 
from datetime import datetime
 

	
 
def OR_filter(field_name, objs):
 
    from django.db.models import Q
 
    return reduce(lambda x, y: x | y,
 
                  [Q(**{field_name: x.id}) for x in objs])
 

	
 
def last_name(person):
 
    return person.formal_name.rpartition(' ')[2]
 

	
 
class BlogListView(ListView):
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogListView, self).get_context_data(**kwargs)
 
        # context['key'] = 'value'
 
        context.update(self.extra_context)
 
        return context
 
                                    
 
def custom_index(request, queryset, *args, **kwargs):
 
    """Blog list view that allows scrolling and also shows an index by
 
    year.
 
    """
 

	
 
    kwargs = kwargs.copy()
 
    kwargs['extra_context'] = kwargs.get('extra_context', {}).copy()
 
    extra_context = kwargs['extra_context']
 

	
 
    date_field = kwargs['date_field']
 
    del kwargs['date_field']
 

	
 
    if not kwargs.get('allow_future', False):
 
        queryset = queryset.filter(**{'%s__lte' % date_field: datetime.now()})
 

	
 
    authors = []
 
    if 'author' in request.GET:
 
        authors = [get_object_or_404(Person, username=author)
 
                   for author in request.GET.getlist('author')]
 
        extra_context['authors'] = authors
 
        queryset = queryset.filter(OR_filter('author', authors))
 

	
 
    tags = []
 
    if 'tag' in request.GET:
 
        tags = [get_object_or_404(EntryTag, slug=tag)
 
                for tag in request.GET.getlist('tag')]
 
        extra_context['tags'] = tags
 
        queryset = queryset.filter(OR_filter('tags', tags))
 

	
 
    if authors or tags:
 
        query_string = '&'.join(['author=%s' % a.username for a in authors]
 
                                + ['tag=%s' % t.slug for t in tags])
 
        extra_context['query_string'] = query_string
 

	
 
    else:
 
        date_list = queryset.dates(date_field, 'year')
 
        extra_context['date_list'] = date_list
 

	
 
    return object_list(request, queryset, *args, **kwargs)
 
    # return object_list(request, queryset, *args, **kwargs)
 
    kwargs['queryset'] = queryset
 
    kwargs['extra_context'] = extra_context
 
    callable = BlogListView.as_view(**kwargs)
 
    return callable(request)
 

	
 
def techblog_redirect(request):
 
    """Redirect from the old 'techblog' to the new blog
 
    """
 

	
 
    path = request.path[len('/technology'):]
 
    if path == '/blog/':
 
        path += "?author=bkuhn"
 

	
 
    return relative_redirect(request, path)
 

	
 
def query(request):
 
    """Page to query the blog based on authors and tags
 
    """
 

	
 
    if request.GET:
 
        d = request.GET.copy()
 
        if 'authors' in d.getlist('all'):
 
            d.setlist('author', []) # remove author queries
 
        if 'tags' in d.getlist('all'):
 
            d.setlist('tag', []) # remove tag queries
 
        d.setlist('all', []) # remove "all" from the query string
 

	
 
        base_url = '/blog/'
 
        if 'rss' in d:
 
            base_url = '/feeds/blog/'
 
            d.setlist('rss', []) # remove it
 

	
 
        query_string = d.urlencode()
 

	
 
        return relative_redirect(request, '%s%s%s' % (base_url, '?' if query_string else '', query_string))
 

	
 
    else:
 
        authors = sorted(Person.objects.filter(currently_employed=True,
 
                                               entry__isnull=False).distinct(),
 
                         key=last_name)
 
        tags = EntryTag.objects.all().order_by('label')
 
        return render_to_response('blog/query.html',
 
                                  {'authors': authors, 'tags': tags})
 

	
 
def relative_redirect(request, path):
 
    from django import http
 
    from django.conf import settings
 

	
 
    host = http.get_host(request)
 
    host = request.get_host()
 
    if settings.FORCE_CANONICAL_HOSTNAME:
 
        host = settings.FORCE_CANONICAL_HOSTNAME
 

	
 
    url = "%s://%s%s" % (request.is_secure() and 'https' or 'http', host, path)
 
    return http.HttpResponseRedirect(url)
 

	
 
class BlogYearArchiveView(YearArchiveView):
 
    make_object_list = True
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogYearArchiveView, self).get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
 

	
 
class BlogMonthArchiveView(MonthArchiveView):
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogMonthArchiveView, self).get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
 

	
 
class BlogDayArchiveView(DayArchiveView):
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogDayArchiveView, self).get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
 

	
 
class BlogDateDetailView(DateDetailView):
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogDateDetailView, self).get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
www/conservancy/apps/contacts/urls.py
Show inline comments
 
from django.conf.urls.defaults import *
 
from django.conf.urls import patterns, url, include
 

	
 
urlpatterns = patterns('conservancy.apps.contacts.views',
 
   (r'^/?$', 'subscribe'),
 
)
www/conservancy/apps/events/models.py
Show inline comments
 
from django.db import models
 
from conservancy.apps.staff.models import Person
 
from conservancy.apps.worldmap.models import EarthLocation
 
from datetime import datetime, timedelta
 

	
 
class EventTag(models.Model):
 
    """Tagging for events
 

	
 
    (currently unused)
 
    """
 

	
 
    label = models.CharField(max_length=100)
 

	
 
    date_created = models.DateField(auto_now_add=True)
 

	
 
    def __unicode__(self):
 
        return self.label
 

	
 
class PastEventManager(models.Manager):
 
    """Returns all past events"""
 

	
 
    def get_query_set(self):
 
        return super(PastEventManager, self).get_query_set().filter(date__lt=datetime.today())
 
    def get_queryset(self):
 
        return super(PastEventManager, self).get_queryset().filter(date__lt=datetime.today())
 

	
 
class FutureEventManager(models.Manager):
 
    """Returns all future events"""
 

	
 
    def get_query_set(self):
 
        return super(FutureEventManager, self).get_query_set().filter(date__gte=datetime.today())
 
    def get_queryset(self):
 
        return super(FutureEventManager, self).get_queryset().filter(date__gte=datetime.today())
 

	
 
class Event(models.Model):
 
    """Model for Conservancy staff member events (presentations, etc)"""
 

	
 
    title = models.CharField(max_length=400)
 
    date = models.DateField()
 
    date_tentative = models.BooleanField()
 
    datetime = models.CharField("Date and Time", max_length=300, blank=True)
 
    slug = models.SlugField(unique_for_year='date')
 
    description = models.TextField(blank=True)
 
    people = models.ManyToManyField(Person, null=True, blank=True)
 
    location = models.CharField(max_length=1000)
 
    earth_location = models.ForeignKey(EarthLocation, null=True, blank=True,
 
                                       help_text="Label will not be displayed")
 
    tags = models.ManyToManyField(EventTag, null=True, blank=True)
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta:
 
        ordering = ("-date",)
 

	
 
    def __unicode__(self):
 
        return u"%s (%s)" % (self.title, self.date)
 

	
 
    def get_absolute_url(self):
 
        return u"/events/%s/%s/" % (self.date.strftime("%Y"), self.slug)
 

	
 
    def day_after(self):
 
        return self.date + timedelta(days=1)
 

	
 
    # for aggregate feed
 
    pub_date = property(lambda self: self.date_created)
 

	
 
    objects = models.Manager()
 
    past = PastEventManager()
 
    future = FutureEventManager()
 

	
 
class EventMedia(models.Model):
 
    """Media from an event
 

	
 
    includes transcripts, audio, and video pieces
 
    """
 

	
 
    event = models.ForeignKey(Event)
 
    format = models.CharField(max_length=1,
 
                              choices=(('T', 'Transcript'),
 
                                       ('A', 'Audio'),
 
                                       ('V', 'Video')))
 
    local = models.CharField(max_length=300, blank=True,
 
                             help_text="Local filename of the resource.  File should be uploaded into the static directory that corresponds to the event.")
 
    remote = models.URLField(blank=True, verify_exists=False,
 
    # verify_exists removed https://docs.djangoproject.com/en/1.7/releases/1.4/
 
    remote = models.URLField(blank=True,
 
                             help_text="Remote URL of the resource.  Required if 'local' is not given.")
 
    novel = models.BooleanField(help_text="Is it a new piece of media or another form of an old one?  If it is new it will be included in the event-media RSS feed and shown on the front page for a bit.")
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta:
 
        verbose_name_plural = 'event media'
 

	
 
    def __unicode__(self):
 
        return u"%s media: %s" % (self.event, self.format)
 

	
www/conservancy/apps/events/urls.py
Show inline comments
 
from django.conf.urls.defaults import *
 
from django.conf.urls import patterns, url, include
 
from models import Event # relative import
 

	
 
info_dict = {
 
    'queryset': Event.objects.all(),
 
    'date_field': 'date',
 
    'allow_future': True,
 
}
 

	
 
urlpatterns = patterns('django.views.generic.date_based',
 
    (r'^(?P<year>\d{4})/$', 'archive_year', dict(info_dict,
 
                                                 make_object_list=True)),
 
)
 
# FIXME -- see blog and news for examples
 
# urlpatterns = patterns('django.views.generic.date_based',
 
#     (r'^(?P<year>\d{4})/$', 'archive_year', dict(info_dict,
 
#                                                  make_object_list=True)),
 
# )
 

	
 
# urlpatterns += patterns('conservancy.apps.events.views',
 
#     (r'^/?$', 'custom_index', dict(info_dict, queryset=Event.past.all(), paginate_by=10)),
 
#     (r'^(?P<year>\d{4})/(?P<slug>[-\w]+)/$', 'event_detail', dict(info_dict, slug_field='slug')),
 
#     (r'^ics/$', 'future_event_ics', info_dict),
 
# )
 

	
 
urlpatterns += patterns('conservancy.apps.events.views',
 
    (r'^/?$', 'custom_index', dict(info_dict, queryset=Event.past.all(), paginate_by=10)),
 
    (r'^(?P<year>\d{4})/(?P<slug>[-\w]+)/$', 'event_detail', dict(info_dict, slug_field='slug')),
 
    (r'^ics/$', 'future_event_ics', info_dict),
 
urlpatterns = patterns('conservancy.apps.events.views',
 
    (r'^.*$', 'custom_index', dict(info_dict, queryset=Event.past.all(), paginate_by=10)),
 
)
www/conservancy/apps/events/views.py
Show inline comments
 
from django.views.generic.list_detail import object_list
 
# from django.views.generic.list_detail import object_list
 
from django.shortcuts import render_to_response
 
from django.http import Http404, HttpResponse
 
from django.template import loader
 
from django.core.exceptions import ObjectDoesNotExist
 
from models import Event # relative import
 
# for debugging...
 
from django.http import HttpResponse
 

	
 
def event_detail(request, year, slug, queryset, **kwargs):
 
    """This view shows event detail.
 

	
 
    Nothing special, but it is necessary because
 
    django.views.generic.date_based.object_detail only works with
 
    slugs that are unique and specified by day, but we make slugs
 
    unique by year.
 
    """
 

	
 
    try:
 
        event = queryset.get(date__year=year, slug__exact=slug)
 
    except ObjectDoesNotExist:
 
        raise Http404, "Event does not exist"
 
    return render_to_response('events/event_detail.html', {'event': event})
 

	
 
def custom_index(request, queryset, *args, **kwargs):
 
    """Scrollable index of future and past events, with date index.
 
    """
 

	
 
    future_events = None
 
    if not request.GET.has_key("page"):
 
        future_events = Event.future.all().order_by("date")
 

	
 
    date_list = queryset.dates(kwargs['date_field'], 'year')
 

	
 
    kwargs = dict(kwargs, extra_context={'date_list': date_list,
 
                                         'future_events': future_events})
 
    del kwargs['date_field']
 
    del kwargs['allow_future']
 

	
 
    return object_list(request, queryset, *args, **kwargs)
 
    # return object_list(request, queryset, *args, **kwargs)
 
    return HttpResponse("FIXME: events must be updated like blog and news.")
 

	
 
def future_event_ics(request, queryset, *args, **kwargs):
 
    """ICS calendar view of future events
 

	
 
    This view just renders information into a template that looks like
 
    an ics file.  If in the future we want a 'real' implementation of
 
    this function, there is a python 'vobject' library that can be
 
    used.  Search google for details, or see
 
    http://www.technobabble.dk/2008/mar/06/exposing-calendar-events-using-icalendar-django/
 
    Hopefully at some point this functionality is integrated into
 
    django.contrib.
 
    """
 

	
 
    future_events = Event.future.all().order_by("date")
 

	
 
    return HttpResponse(loader.render_to_string('events/calendar.ics',
 
                                                {'events': future_events}),
 
                        mimetype='text/calendar')
www/conservancy/apps/news/models.py
Show inline comments
 
from django.db import models
 
from django.conf import settings
 
from conservancy.apps.staff.models import Person
 
from conservancy.apps.events.models import Event
 
from django.contrib.sites.models import Site
 
from datetime import datetime, timedelta
 

	
 
class PressRelease(models.Model):
 
    """News release model"""
 

	
 
    headline = models.CharField(max_length=300)
 
    subhead = models.CharField(max_length=300, blank=True)
 
    slug = models.SlugField(unique_for_date="pub_date",
 
                            help_text=("automatically built from headline"))
 
    summary = models.TextField(help_text="First paragraph (raw HTML)")
 
    body = models.TextField(help_text="Remainder of post (raw HTML)",
 
                            blank=True)
 
    pub_date = models.DateTimeField("date [to be] published")
 
    sites = models.ManyToManyField(Site)
 

	
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta:
 
        ordering = ("-pub_date",)
 
        get_latest_by = "pub_date"
 

	
 
    def __unicode__(self):
 
        return self.headline
 

	
 
    def get_absolute_url(self):
 
        return u"/news/%s/%s/" % (self.pub_date.strftime("%Y/%b/%d").lower(),
 
                                  self.slug)
 

	
 
    def is_recent(self):
 
        return self.pub_date > (datetime.now() - timedelta(days=5))
 
        # question: does datetime.now() do a syscall each time is it called?
 

	
 
    def is_in_past_month(self):
 
        # This function is deprecated.  Use the date_within template
 
        # filter instead (example in conservancy/templates/frontpage.html)
 
        return self.pub_date > (datetime.now() - timedelta(days=30))
 

	
 
    def save(self):
 
        if settings.CONSERVANCY_DEVEL or True:
 
            super(PressRelease, self).save()
 
            return
 

	
 
        blog_name = 'Software Freedom Law Center News'
 
        blog_url =  'http://www.softwarefreedom.org/news/'
 
        post_url = ('http://www.softwarefreedom.org'
 
                    + self.get_absolute_url())
 

	
 
        import xmlrpclib
 

	
 
        # Ping Technorati
 
        j = xmlrpclib.Server('http://rpc.technorati.com/rpc/ping')
 
        reply = j.weblogUpdates.ping(blog_name, blog_url)
 

	
 
        # Ping Google Blog Search
 
        j = xmlrpclib.Server('http://blogsearch.google.com/ping/RPC2')
 
        reply = j.weblogUpdates.ping(blog_name, blog_url, post_url)
 

	
 
        # Call any superclass's method
 
        super(PressRelease, self).save()
 

	
 
class ExternalArticleTag(models.Model):
 
    """A way to tag external articles"""
 

	
 
    label = models.CharField(max_length=100)
 

	
 
    date_created = models.DateField(auto_now_add=True)
 

	
 
    def __unicode__(self):
 
        return self.label
 

	
 
class PublicExternalArticleManager(models.Manager):
 
    def get_query_set(self):
 
        return super(PublicExternalArticleManager, self).get_query_set().filter(visible=True)
 
    def get_queryset(self):
 
        return super(PublicExternalArticleManager, self).get_queryset().filter(visible=True)
 

	
 
class ExternalArticle(models.Model):
 
    """A system for displaying Conservancy news mentions on the site.
 

	
 
    (Currently unused)
 
    """
 

	
 
    title = models.CharField(max_length=400)
 
    info = models.CharField(help_text="subscribers only? audio? pdf warning?",
 
                            blank=True, max_length=300)
 
    publication = models.CharField("source of article", max_length=300)
 
    url = models.URLField(blank=True, verify_exists=False)
 
    # verify_exists removed https://docs.djangoproject.com/en/1.7/releases/1.4/
 
    url = models.URLField(blank=True)
 
    date = models.DateField()
 
    visible = models.BooleanField(help_text="Whether to display on website")
 

	
 
    tags = models.ManyToManyField(ExternalArticleTag, null=True, blank=True)
 
    people = models.ManyToManyField(Person, null=True, blank=True)
 
    event = models.ForeignKey(Event, null=True, blank=True)
 
    press_release = models.ForeignKey(PressRelease, null=True, blank=True)
 

	
 
    date_created = models.DateField(auto_now_add=True)
 

	
 
    class Meta:
 
        ordering = ("-date_created",)
 
        get_latest_by = "date_created"
 

	
 
    def __unicode__(self):
 
        return u"%s (%s)" % (self.title, self.publication)
 

	
 
    objects = models.Manager()
 
    public = PublicExternalArticleManager()
 

	
www/conservancy/apps/news/urls.py
Show inline comments
 
# Copyright 2005-2008, James Garrison
 
# Copyright 2010, Bradley M. Kuhn
 

	
 
# This software's license gives you freedom; you can copy, convey,
 
# propagate, redistribute, modify and/or redistribute modified versions of
 
# this program under the terms of the GNU Affero General Public License
 
# (AGPL) as published by the Free Software Foundation (FSF), either
 
# version 3 of the License, or (at your option) any later version of the
 
# AGPL published by the FSF.
 
#
 
# This program 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 Affero
 
# General Public License for more details.
 
#
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program in a file in the toplevel directory called
 
# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from django.conf.urls.defaults import *
 
from django.conf.urls import patterns, url, include
 
from django.conf import settings
 
from models import PressRelease, ExternalArticle # relative import
 
from views import NewsYearArchiveView, NewsMonthArchiveView, NewsDayArchiveView, NewsDateDetailView
 

	
 
info_dict = {
 
    'queryset': PressRelease.objects.all().filter(sites__id__exact=settings.SITE_ID),
 
    'date_field': 'pub_date',
 
}
 

	
 
external_article_dict = {
 
    'articles': ExternalArticle.objects.all()
 
}
 

	
 
urlpatterns = patterns('django.views.generic.date_based',
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict),
 
   (r'^(?P<year>\d{4})/$', 'archive_year', dict(info_dict,
 
                                                make_object_list=True)),
 
urlpatterns = patterns('',
 
#    (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'conservancy.apps.news.views.object_detail', info_dict),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', NewsDateDetailView.as_view(**info_dict)),
 
#   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'conservancy.apps.news.views.archive_day', info_dict),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', NewsDayArchiveView.as_view(**info_dict)),
 
#   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'conservancy.apps.news.views.archive_month', info_dict),
 
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', NewsMonthArchiveView.as_view(**info_dict)),
 
#   (r'^(?P<year>\d{4})/$', 'conservancy.apps.news.views.archive_year',
 
#    dict(info_dict, make_object_list=True)),
 
   (r'^(?P<year>\d{4})/$', NewsYearArchiveView.as_view(**info_dict)),
 
)
 

	
 
urlpatterns += patterns('',
 
   (r'^/?$', 'conservancy.apps.news.views.custom_index', dict(info_dict, paginate_by=6)),
 
)
www/conservancy/apps/news/views.py
Show inline comments
 
from django.views.generic.list_detail import object_list
 
# from django.views.generic.list_detail import object_list
 
from django.views.generic import ListView
 
from django.views.generic.dates import YearArchiveView, MonthArchiveView, DayArchiveView, DateDetailView
 
from conservancy.apps.news.models import ExternalArticle
 
from conservancy.apps.events.models import Event
 
from datetime import datetime
 
# for debugging...
 
from django.http import HttpResponse
 

	
 

	
 
class NewsListView(ListView):
 
    extra_context = {}
 
    def get_context_data(self, **kwargs):
 
        context = super(NewsListView, self).get_context_data(**kwargs)
 
        # context['key'] = 'value'
 
        context.update(self.extra_context)
 
        return context
 
                                    
 
def custom_index(request, queryset, *args, **kwargs):
 
    """News index.  Calls a generic list view, but passes additional
 
    context including past and future events, and an index of news by
 
    year.
 
    """
 
    # debug = '<pre>This is news'
 
    # debug += '\nqueryset: ' + str(queryset)
 
    # debug += '\nargs: ' + str(args)
 
    # debug += '\nkwargs: ' + str(kwargs)
 
    # debug += '</pre>'
 
    # return HttpResponse(debug)
 

	
 
    articles = None
 
    #if not request.GET.has_key("page"):
 
    #    articles = ExternalArticle.public.all().order_by("-date")[:10]
 

	
 
    if (not kwargs.has_key('allow_future')) or not kwargs['allow_future']:
 
        queryset = queryset.filter(**{'%s__lte' % kwargs['date_field']:
 
                                      datetime.now()})
 

	
 
    future_events = Event.future.all().filter(date_tentative=False).order_by("date")
 
    past_events = Event.past.all().order_by("-date")[:6]
 

	
 
    date_list = queryset.dates(kwargs['date_field'], 'year')
 

	
 
    kwargs = dict(kwargs, extra_context={'articles': articles,
 
                                         'date_list': date_list,
 
                                         'future_events': future_events,
 
                                         'past_events': past_events})
 
    del kwargs['date_field']
 

	
 
    return object_list(request, queryset, *args, **kwargs)
 
    # return object_list(request, queryset, *args, **kwargs)
 
    # callable = NewsListView.as_view(queryset=queryset,
 
    #                                 extra_context=kwargs,
 
    #                                 paginate_by=kwargs['paginate_by'])
 
    kwargs['queryset'] = queryset
 
    callable = NewsListView.as_view(**kwargs)
 
    return callable(request)
 

	
 
#    num_navigation = 3 # in each direction
 
#    page_navigation = range(max((page - num_navigation), 1),
 
#                            min((page + num_navigation), page_count) + 1)
 

	
 
class NewsYearArchiveView(YearArchiveView):
 
    # queryset = Article.objects.all()
 
    # date_field = "pub_date"
 
    make_object_list = True
 
    allow_future = True
 

	
 
# def archive_year(request, **kwargs):
 
#     callable = NewsYearArchiveView.as_view(**kwargs)
 
#     return callable(request)
 

	
 
class NewsMonthArchiveView(MonthArchiveView):
 
    allow_future = True
 

	
 
# def archive_month(request, **kwargs):
 
#     # return HttpResponse("archive_month")
 
#     callable = NewsMonthArchiveView.as_view(**kwargs)
 
#     return callable(request)
 

	
 
class NewsDayArchiveView(DayArchiveView):
 
    allow_future = True
 

	
 
# def archive_day(request, **kwargs):
 
#     # return HttpResponse("archive_day")
 
#     callable = NewsDayArchiveView.as_view(**kwargs)
 
#     return callable(request)
 

	
 
class NewsDateDetailView(DateDetailView):
 
    # extra_context = {}
 
    allow_future = True
 
    # slug_url_kwarg = 'slug'
 

	
 
    # def get_context_data(self, **kwargs):
 
    #     context = super(NewsDateDetailView, self).get_context_data(**kwargs)
 
    #     context.update(self.extra_context)
 
    #     return context
 

	
 
# def object_detail(request, **kwargs):
 
#     # extra_context = {}
 
#     # extra_context['slug'] = kwargs['slug']
 
#     # del kwargs['slug']
 
#     # kwargs['extra_context'] = extra_context
 
#     # return HttpResponse("object_detail: " + str(kwargs))
 
#     # slug = kwargs['slug']
 
#     # del kwargs['slug']
 
#     callable = NewsDateDetailView.as_view(**kwargs)
 
#     return callable(request)
 

	
www/conservancy/apps/podcast/admin.py
Show inline comments
 
deleted file
www/conservancy/apps/podcast/models.py
Show inline comments
 
deleted file
www/conservancy/apps/podcast/urls.py
Show inline comments
 
deleted file
www/conservancy/apps/podcast/views.py
Show inline comments
 
deleted file
www/conservancy/apps/summit_registration/urls.py
Show inline comments
 
from django.conf.urls.defaults import *
 
from django.conf.urls import patterns, url, include
 

	
 
urlpatterns = patterns('conservancy.apps.summit_registration.views',
 
   (r'^/?$', 'register'),
 
)
www/conservancy/apps/supporters/views.py
Show inline comments
 
from models import Supporter # relative import
 
from django.views.generic.list_detail import object_list
 
from django.shortcuts import get_object_or_404, render_to_response
 

	
www/conservancy/middleware.py
Show inline comments
 
from django.conf import settings
 
from django import http
 
from django.conf import settings
 
from django.utils.cache import patch_response_headers
 

	
 
class ForceCanonicalHostnameMiddleware(object):
 

	
 
    def process_request(self, request):
 
        """Modified common middleware for Conservancy site
 

	
 
        * Performs redirects to strip trailing "index.html"
 
        * performs redirects based on APPEND_SLASH
 
        * performs redirects based on site-specific REDIRECT_TABLE
 
        * adds cache headers to provide hints to squid
 
        """
 

	
 
        # Never allow connection to the /admin part of the site without SSL
 
        if (not request.is_secure) and request.path.startswith('/admin'):
 
            url = 'https://sfconservancy.org%s' % request.path
 
            return http.HttpResponseRedirect(url)
 

	
 
        # Check for a redirect based on settings.APPEND_SLASH
 
        host = http.get_host(request)
 
        host = request.get_host()
 
        old_url = [host, request.path]
 
        new_url = old_url[:]
 
        # Append a slash if append_slash is set and the URL doesn't have a
 
        # trailing slash or a file extension.
 
        if settings.APPEND_SLASH and (old_url[1][-1] != '/') and ('.' not in old_url[1].split('/')[-1]):
 
            new_url[1] = new_url[1] + '/'
 
            if settings.DEBUG and request.method == 'POST':
 
                raise RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set APPEND_SLASH=False in your Django settings." % (new_url[0], new_url[1])
 
        # Strip trailing index.html
 
        if new_url[1].endswith('/index.html'):
 
            new_url[1] = new_url[1][:new_url[1].rfind('index.html')]
 
        # Consult redirect table (if exists)
 
        if hasattr(settings, "REDIRECT_TABLE"):
 
            if settings.REDIRECT_TABLE.has_key(new_url[1]):
 
                new_url[1] = settings.REDIRECT_TABLE[new_url[1]]
 
        if new_url != old_url:
 
            # Force canonical hostname
 
            if settings.FORCE_CANONICAL_HOSTNAME:
 
                new_url[0] = settings.FORCE_CANONICAL_HOSTNAME
 
            # Redirect
 
            if new_url[0]:
 
                newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1])
 
            else:
 
                newurl = new_url[1]
 
            if request.GET:
 
                newurl += '?' + request.GET.urlencode()
 
            return http.HttpResponseRedirect(newurl)
 

	
 
        return None
 

	
 
    def process_response(self, request, response):
 
        # provide hints to squid
 
        if request.method in ('GET', 'HEAD') and response.status_code == 200:
 
            patch_response_headers(response)
 
        return response
www/conservancy/settings.py
Show inline comments
 
# Copyright 2005-2008, James Garrison
 
# Copyright 2010, Bradley M. Kuhn
 

	
 
# This software's license gives you freedom; you can copy, convey,
 
# propagate, redistribute, modify and/or redistribute modified versions of
 
# this program under the terms of the GNU Affero General Public License
 
# (AGPL) as published by the Free Software Foundation (FSF), either
 
# version 3 of the License, or (at your option) any later version of the
 
# AGPL published by the FSF.
 
#
 
# This program 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 Affero
 
# General Public License for more details.
 
#
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program in a file in the toplevel directory called
 
# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from djangocommonsettings import *
 

	
 
SITE_ID = 2
 
ROOT_URLCONF = 'conservancy.urls'
 
FORCE_CANONICAL_HOSTNAME = "sfconservancy.org"
 

	
 

	
 
# FORCE_CANONICAL_HOSTNAME = "sfconservancy.org"
 
FORCE_CANONICAL_HOSTNAME = False
 

	
 
ALLOWED_HOSTS = [ 'aspen.sfconservancy.org', 'sfconservancy.org' ]
 

	
 
REDIRECT_TABLE = {
 
    'www.sf-conservancy.org': 'sfconservancy.org',
 
}
 

	
 
try:
 
    from djangodebug import conservancy_hostname as FORCE_CANONICAL_HOSTNAME
 
except:
 
    pass
 
# import os
 
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
 

	
 
# from os.path import join
 
# TEMPLATE_DIRS = (
 
#     join(BASE_DIR,  'templates'),
 
# )
 
# NOTE: trailing comma is required to force this to be a tuple
 
TEMPLATE_DIRS = ( '/var/www/conservancy/templates', '/var/www/conservancy/static', )
 

	
 
# try:
 
#     from djangodebug import conservancy_hostname as FORCE_CANONICAL_HOSTNAME
 
# except:
 
#     pass
www/conservancy/static/__init__.py
Show inline comments
 
file renamed from www/conservancy/apps/podcast/__init__.py to www/conservancy/static/__init__.py
www/conservancy/static/error/401/index.html
Show inline comments
 
file renamed from www/conservancy/static/401error.html to www/conservancy/static/error/401/index.html
www/conservancy/static/error/403/index.html
Show inline comments
 
file renamed from www/conservancy/static/403error.html to www/conservancy/static/error/403/index.html
www/conservancy/static/error/404/index.html
Show inline comments
 
file renamed from www/conservancy/static/404error.html to www/conservancy/static/error/404/index.html
www/conservancy/static/error/500/index.html
Show inline comments
 
file renamed from www/conservancy/static/500error.html to www/conservancy/static/error/500/index.html
www/conservancy/static/views.py
Show inline comments
 
new file 100644
 
import os.path
 
from django.http import HttpResponse
 
from django.template import RequestContext, loader
 

	
 
def handler(request, errorcode):
 
    STATIC_ROOT = '/home/www/website/www/conservancy/static/'
 
    path = 'error/' + errorcode + '/index.html'
 
    fullpath = STATIC_ROOT + path
 
    if not os.path.exists(fullpath):
 
        return HttpResponse("Internal error: " + path)
 
    template = loader.get_template(path)
 
    context = RequestContext(request)
 
    return HttpResponse(template.render(context))
 

	
 
def handler401(request):
 
    return handler(request, '401')
 

	
 
def handler403(request):
 
    return handler(request, '403')
 

	
 
def handler404(request):
 
    return handler(request, '404')
 

	
 
def handler500(request):
 
    return handler(request, '500')
 

	
 
def index(request):
 
    # return HttpResponse("Hello, static world: " + request.get_full_path())
 
    path = request.get_full_path()
 
    path = path.lstrip('/')
 
    if path[-1:] == '/':
 
        path += 'index.html'
 
    STATIC_ROOT = '/home/www/website/www/conservancy/static/'
 
    fullpath = STATIC_ROOT + path
 
    if not os.path.exists(fullpath):
 
        # return HttpResponse("Sorry that's a 404: " + path)
 
        return handler404(request)
 
    template = loader.get_template(path)
 
    context = RequestContext(request)
 
    return HttpResponse(template.render(context))
 

	
 
def debug(request):
 
    path = request.get_full_path()
 
    path = path.lstrip('/')
 
    return HttpResponse("Hello, static world: " + path)
 

	
www/conservancy/urls.py
Show inline comments
 
# Copyright 2005-2008, James Garrison
 
# Copyright 2010, 2012 Bradley M. Kuhn
 

	
 
# This software's license gives you freedom; you can copy, convey,
 
# propagate, redistribute, modify and/or redistribute modified versions of
 
# this program under the terms of the GNU Affero General Public License
 
# (AGPL) as published by the Free Software Foundation (FSF), either
 
# version 3 of the License, or (at your option) any later version of the
 
# AGPL published by the FSF.
 
#
 
# This program 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 Affero
 
# General Public License for more details.
 
#
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program in a file in the toplevel directory called
 
# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from django.conf.urls.defaults import *
 
from django.conf.urls import patterns, url, include
 
from django.contrib import admin
 

	
 
# import conservancy.settings
 
from django.conf import settings
 
from conservancy.feeds import BlogFeed, PressReleaseFeed, OmnibusFeed
 
# from django.views.static import serve
 
# from django.conf.urls.static import static
 
# from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 
# import conservancy.static.overview.views
 

	
 
handler404 = 'modpythoncustom.view404'
 
# handler404 = 'modpythoncustom.view404'
 
# handler401 = 'conservancy.static.views.handler401'
 
# handler403 = 'conservancy.static.views.handler403'
 
handler404 = 'conservancy.static.views.handler404'
 
# handler500 = 'conservancy.static.views.handler500'
 

	
 
admin.autodiscover()
 

	
 
urlpatterns = patterns('',
 
    (r'^$', 'conservancy.frontpage.view'),
 
    (r'^sponsors$', 'conservancy.frontpage.view'),
 
    (r'^sponsors/$', 'conservancy.sponsors.view'),
 
    (r'^sponsors/index.html$', 'conservancy.sponsors.view'),
 
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
 
    (r'^admin/', admin.site.urls),
 
    (r'^feeds/blog/?$', BlogFeed()),
 
    (r'^feeds/news/?$', PressReleaseFeed()),
 
    (r'^feeds/omnibus/?$', OmnibusFeed()),
 
    (r'^feeds/?$', 'conservancy.feeds.view'),
 
    (r'^news(/|$)', include('conservancy.apps.news.urls')),
 
    (r'^blog(/|$)', include('conservancy.apps.blog.urls')),
 
    # formerly static templated things... (dirs with templates)
 
    (r'^error', 'conservancy.static.views.index'),
 
    (r'^about', 'conservancy.static.views.index'),
 
    (r'^donate', 'conservancy.static.views.index'),
 
    (r'^linux-compliance', 'conservancy.static.views.index'),
 
    (r'^members', 'conservancy.static.views.index'),
 
    (r'^npoacct', 'conservancy.static.views.index'),
 
    (r'^overview', 'conservancy.static.views.index'),
 
    (r'^privacy-policy', 'conservancy.static.views.index'),
 
    (r'^supporter', 'conservancy.static.views.index'),
 
)
 

	
 
# urlpatterns += url(regex  = r'^%s(?P<path>.*)$' % conservancy.settings.STATIC_URL[1:],
 
# urlpatterns += url(regex  = r'^/overview',
 
#                    view   = 'django.views.static.serve',
 
#                    kwargs = {'document_root': conservancy.settings.STATIC_ROOT,
 
#                              'show_indexes' : True})
 
# urlpatterns += (r'^(?P<path>.*)$', 'django.views.static.serve', 
 
# urlpatterns += (r'^overview/$', 'django.views.static.serve', 
 
#                 {'document_root': conservancy.settings.STATIC_ROOT,
 
#                  'show_indexes' : True})
 

	
 
# https://docs.djangoproject.com/en/1.7/howto/static-files/
 
#  + static(conservancy.settings.STATIC_URL, document_root=conservancy.settings.STATIC_ROOT)
 

	
 
# urlpatterns += staticfiles_urlpatterns()
 

	
 
# urlpatterns += static(settings.STATIC_URL, view='django.contrib.staticfiles.views.serve',
 
# urlpatterns += static('/', view='django.contrib.staticfiles.views.serve',
 
#                       document_root=settings.STATIC_ROOT,
 
#                       show_indexes=True)
 

	
 

	
 

	
 

	
www/conservancy_ssl_wrapper.py
Show inline comments
 
# Copyright 2005-2008, James Garrison
 
# Copyright 2010, Bradley M. Kuhn
 

	
 
# This software's license gives you freedom; you can copy, convey,
 
# propagate, redistribute, modify and/or redistribute modified versions of
 
# this program under the terms of the GNU Affero General Public License
 
# (AGPL) as published by the Free Software Foundation (FSF), either
 
# version 3 of the License, or (at your option) any later version of the
 
# AGPL published by the FSF.
 
#
 
# This program 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 Affero
 
# General Public License for more details.
 
#
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program in a file in the toplevel directory called
 
# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>.
 

	
 
# req.subprocess_env is not set when the PostReadRequestHandler runs,
 
# so we just bypass it altogether and set the relevant variable here.
 
# See deployment documentation for more info.
 
from os import environ
 
environ["DJANGO_SETTINGS_MODULE"] = 'conservancy_ssl.settings'
 
environ["CANONICAL_HOSTNAME"] = 'sfconservancy.org'
 

	
 
from modpythoncustom import *
 
# from modpythoncustom import *
www/conservancy_wrapper.py
Show inline comments
 
# req.subprocess_env is not set when the PostReadRequestHandler runs,
 
# so we just bypass it altogether and set the relevant variable here.
 
# See deployment documentation for more info.
 
from os import environ
 
environ["DJANGO_SETTINGS_MODULE"] = 'conservancy.settings'
 
environ["CANONICAL_HOSTNAME"] = 'sfconservancy.org'
 

	
 
from modpythoncustom import *
 
# from modpythoncustom import *
www/wsgicustom.wsgi
Show inline comments
 
new file 100644
 
# wsgicustom.py
 

	
 
import os
 
import sys
 

	
 
sys.path = ['/var/www'] + sys.path
 
os.environ['DJANGO_SETTINGS_MODULE'] = 'conservancy.settings'
 

	
 
from django.core.wsgi import get_wsgi_application
 
application = get_wsgi_application()
0 comments (0 inline, 0 general)