Merge bkuhn master local branch with upstream

This commit is contained in:
Bradley M. Kuhn 2017-11-07 09:00:27 -08:00
commit 07faf5cebc
23 changed files with 343 additions and 152 deletions

View file

@ -1,9 +1,12 @@
import hashlib
from django.conf import settings
from django.shortcuts import render_to_response
from django.template import RequestContext
# This is backwards compatibilty support for a custom function we wrote
# ourselves that is no longer necessary in modern Django.
from django.shortcuts import render as render_template_with_context
class ParameterValidator(object):
def __init__(self, given_hash_or_params, params_hash_key=None):
if params_hash_key is None:
@ -41,8 +44,3 @@ class ParameterValidator(object):
def fail(self):
self.valid = False
def render_template_with_context(request, template_path, context_dict):
return render_to_response(template_path, context_dict,
context_instance=RequestContext(request))

View file

@ -1,5 +1,6 @@
from django.db import models
from django.conf import settings
from conservancy import bsoup
from conservancy.apps.staff.models import Person
from datetime import datetime, timedelta
@ -18,7 +19,7 @@ class EntryTag(models.Model):
def get_absolute_url(self):
return u"/blog/?tag=%s" % self.slug
class Entry(models.Model):
class Entry(models.Model, bsoup.SoupModelMixin):
"""Blog entry"""
headline = models.CharField(max_length=200)
@ -38,6 +39,8 @@ class Entry(models.Model):
ordering = ('-pub_date',)
get_latest_by = 'pub_date'
SOUP_ATTRS = ['body']
def __unicode__(self):
return self.headline

View file

@ -1,8 +1,8 @@
from django.conf.urls import patterns, url, include
from django.conf.urls import url, include
from conservancy.apps.blog.models import Entry, EntryTag # relative import
from conservancy.apps.staff.models import Person
from datetime import datetime
from conservancy.apps.blog.views import last_name, BlogYearArchiveView, BlogMonthArchiveView, BlogDayArchiveView, BlogDateDetailView
from conservancy.apps.blog.views import last_name, BlogYearArchiveView, BlogMonthArchiveView, BlogDayArchiveView, BlogDateDetailView, custom_index, query
extra_context = {}
@ -12,23 +12,14 @@ info_dict = {
'extra_context': extra_context,
}
# 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=4)),
(r'^query/$', 'query'),
)
urlpatterns = [
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', BlogDateDetailView.as_view(**info_dict)),
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', BlogDayArchiveView.as_view(**info_dict)),
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', BlogMonthArchiveView.as_view(**info_dict)),
url(r'^(?P<year>\d{4})/$', BlogYearArchiveView.as_view(**info_dict)),
url(r'^/?$', custom_index, dict(info_dict, paginate_by=4)),
url(r'^query/$', query),
]
# Code to display authors and tags on each blog page

View file

@ -4,8 +4,7 @@ from django.views.generic import ListView
from django.views.generic.dates import YearArchiveView, MonthArchiveView, DayArchiveView, DateDetailView
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from conservancy.apps.staff.models import Person
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.shortcuts import get_object_or_404, render
from datetime import datetime
def OR_filter(field_name, objs):
@ -65,7 +64,7 @@ def custom_index(request, queryset, *args, **kwargs):
extra_context['blog_entries'] = blog_entries
return render_to_response('blog/entry_list.html', extra_context, context_instance=RequestContext(request))
return render(request, 'blog/entry_list.html', extra_context)
def techblog_redirect(request):
"""Redirect from the old 'techblog' to the new blog
@ -103,8 +102,7 @@ def query(request):
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}, context_instance=RequestContext(request))
return render(request, 'blog/query.html', {'authors': authors, 'tags': tags})
def relative_redirect(request, path):
from django import http

View file

@ -1,5 +1,4 @@
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.shortcuts import render
from django import forms
from conservancy.apps.contacts.models import ContactEntry
from django.forms import ModelForm
@ -18,10 +17,8 @@ def subscribe(request):
form = ContactEntryForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('contacts/subscribe_success.html',
{'form': form.cleaned_data}, context_instance=RequestContext(request))
return render(request, 'contacts/subscribe_success.html', {'form': form.cleaned_data})
else:
form = ContactEntryForm()
return render_to_response('contacts/subscribe.html',
{'form': form}, context_instance=RequestContext(request))
return render(request, 'contacts/subscribe.html', {'form': form})

View file

@ -1,6 +1,6 @@
from django.conf.urls import patterns, url, include
from django.conf.urls import url, include
from conservancy.apps.contractpatch import views as cpatch_views
urlpatterns = patterns(
'',
(r'', 'conservancy.apps.contractpatch.views.index'),
)
urlpatterns = [
url(r'', cpatch_views.index),
]

View file

@ -1,6 +1,5 @@
# from django.views.generic.list_detail import object_list
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.shortcuts import render
from django.http import Http404, HttpResponse
from django.template import loader
from django.core.exceptions import ObjectDoesNotExist
@ -21,7 +20,7 @@ def event_detail(request, year, slug, queryset, **kwargs):
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}, context_instance=RequestContext(request))
return render(request, 'events/event_detail.html', {'event': event})
def custom_index(request, queryset, *args, **kwargs):
"""Scrollable index of future and past events, with date index.

View file

@ -1,11 +1,12 @@
from django.db import models
from django.conf import settings
from conservancy import bsoup
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):
class PressRelease(models.Model, bsoup.SoupModelMixin):
"""News release model"""
headline = models.CharField(max_length=300)
@ -24,6 +25,8 @@ class PressRelease(models.Model):
ordering = ("-pub_date",)
get_latest_by = "pub_date"
SOUP_ATTRS = ['summary', 'body']
def __unicode__(self):
return self.headline

View file

@ -0,0 +1,20 @@
import urlparse
from django import template
register = template.Library()
@register.filter(name='fill_url')
def fill_url(given_url, base_url):
""""Fill out" missing pieces of one URL from another.
This function parses the given URL, and if it's missing any pieces
(scheme, netloc, etc.), it fills those in from the base URL.
Typical usage is "/URL/path"|fill_url:"https://hostname/"
to generate "https://hostname/URL/path".
"""
given_parts = urlparse.urlsplit(given_url)
base_parts = urlparse.urlsplit(base_url)
return urlparse.urlunsplit(
given_part or base_part for given_part, base_part in zip(given_parts, base_parts)
)

View file

@ -17,10 +17,10 @@
# 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 import patterns, url, include
from django.conf.urls import url, include
from django.conf import settings
from conservancy.apps.news.models import PressRelease, ExternalArticle
from conservancy.apps.news.views import NewsYearArchiveView, NewsMonthArchiveView, NewsDayArchiveView, NewsDateDetailView
from conservancy.apps.news.views import NewsYearArchiveView, NewsMonthArchiveView, NewsDayArchiveView, NewsDateDetailView, listing
info_dict = {
'queryset': PressRelease.objects.all().filter(sites__id__exact=settings.SITE_ID),
@ -31,18 +31,10 @@ external_article_dict = {
'articles': ExternalArticle.objects.all()
}
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.listing', dict(info_dict, paginate_by=6)),
)
urlpatterns = [
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', NewsDateDetailView.as_view(**info_dict)),
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', NewsDayArchiveView.as_view(**info_dict)),
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', NewsMonthArchiveView.as_view(**info_dict)),
url(r'^(?P<year>\d{4})/$', NewsYearArchiveView.as_view(**info_dict)),
url(r'^/?$', listing, dict(info_dict, paginate_by=6)),
]

View file

@ -1,7 +1,6 @@
# from django.views.generic.list_detail import object_list
from django.views.generic import ListView
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.shortcuts import render
from django.views.generic.dates import YearArchiveView, MonthArchiveView, DayArchiveView, DateDetailView
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from conservancy.apps.news.models import ExternalArticle
@ -42,7 +41,7 @@ def listing(request, *args, **kwargs):
# If page is out of range (e.g. 9999), deliver last page of results.
news = paginator.page(paginator.num_pages)
return render_to_response('news/pressrelease_list.html', {"news": news, "date_list" : date_list}, context_instance=RequestContext(request))
return render(request, 'news/pressrelease_list.html', {"news": news, "date_list" : date_list})
class NewsYearArchiveView(YearArchiveView):
# queryset = Article.objects.all()

View file

@ -1,7 +1,5 @@
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.shortcuts import render
from django import forms
from django.template import RequestContext
from conervancy.apps.summit_registration.models import SummitRegistration
def register(request):
@ -21,10 +19,8 @@ def register(request):
form = SummitForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('summit_registration/register_success.html',
{'form': form.cleaned_data}, context_instance=RequestContext(request))
return render(reqeust, 'summit_registration/register_success.html', {'form': form.cleaned_data})
else:
form = SummitForm()
return render_to_response('summit_registration/register.html',
{'form': form}, context_instance=RequestContext(request))
return render(request, 'summit_registration/register.html', {'form': form})

View file

@ -1,11 +1,11 @@
from django.conf.urls import patterns
from django.conf.urls import url
from conservancy.apps.supporter import views as supp_views
from conservancy.static import views as static_views
INDEX_VIEW = 'conservancy.apps.supporter.views.index'
pattern_pairs = [(r'^/?$', INDEX_VIEW)]
pattern_pairs.extend(
(r'^{}(?:\.html|/|)$'.format(basename), INDEX_VIEW)
INDEX_VIEW = supp_views.index
urlpatterns = [url(r'^/?$', INDEX_VIEW)]
urlpatterns.extend(
url(r'^{}(?:\.html|/|)$'.format(basename), INDEX_VIEW)
for basename in ['index', '2015-supporter-appeal', '2016-supporter-appeal']
)
pattern_pairs.append((r'', 'conservancy.static.views.index'))
urlpatterns = patterns('', *pattern_pairs)
urlpatterns.append(url(r'', static_views.index))

144
www/conservancy/bsoup.py Normal file
View file

@ -0,0 +1,144 @@
# -*- encoding: utf-8 -*-
import io
import re
import bs4
import bs4.element
class BeautifulSoup(bs4.BeautifulSoup):
"""A wrapper of the original BeautifulSoup class, with convenience methods added."""
IMAGE_ATTRS = {
'img': 'src',
'video': 'poster',
}
NON_BODY_TEXT_TAGS = frozenset([
'img',
'video',
])
SENTENCE_END = re.compile(r'[.?!]\s*\W*\s*$')
def __init__(self, src, parser='html5lib'):
# WARNING! It seems like it would be ideal to use the 'lxml' parser
# for speed, but that doesn't work in our web application. On
# Debian stretch, at least, using lxml causes the web server WSGI
# application to go into an infinite loop.
super(BeautifulSoup, self).__init__(src, parser)
def _body_text(self, root):
# "Body text" is all the strings under the root element, in order,
# except:
# * strings inside NON_BODY_TEXT_TAGS
# * strings inside containers of NON_BODY_TEXT_TAGS. A container is
# an element that has a NON_BODY_TEXT_TAGS element as its first child.
# For example, in <div> <video …> … </div>, none of the div's strings
# are included in the body text, because it's considered to be a
# <video> container, and any strings are probably a caption, fallback
# text, or other non-body text.
started = False
for child in root.children:
child_type = type(child)
if issubclass(child_type, bs4.element.Tag):
if child.name in self.NON_BODY_TEXT_TAGS:
if not started:
break
else:
for s in self._body_text(child):
yield s
# It's not worth it to use issubclass here, because elements that
# don't have body text like Comments and CDATA are subclasses of
# NavigableString.
elif child_type is bs4.element.NavigableString:
if started:
yield child
elif child.isspace():
pass
else:
yield child
started = True
def body_text(self):
"""Return an iterator of strings comprising this document's body text."""
return self._body_text(self)
def some_body_text(self, char_target=300):
"""Return an iterator of strings with some of this document's body text.
This is the same as body_text, except after it yields a string that
looks like the end of a sentence, it checks whether it has yielded
at least `char_target` characters. If so, the iterator stops.
"""
# This implementation is likely to overshoot `char_target` a lot,
# because it doesn't look inside the strings it yields, just at the
# end of them. We can implement something smarter later if needed.
char_count = 0
for s in self.body_text():
yield s
char_count += len(s)
if (char_count > char_target) and self.SENTENCE_END.search(s):
break
@staticmethod
def is_video_source(elem):
try:
return elem.name == 'source' and elem.parent.name == 'video'
except AttributeError:
return False
def iter_attr(self, tag, attr_name, **kwargs):
kwargs[attr_name] = True
for elem in self.find_all(tag, **kwargs):
yield elem[attr_name]
def iter_image_urls(self):
"""Return an iterator of source URL strings of all images in this document.
Images include <img> tags and <video> poster attributes.
"""
for elem in self.find_all(list(self.IMAGE_ATTRS.keys())):
try:
yield elem[self.IMAGE_ATTRS[elem.name]]
except KeyError:
pass
def iter_video_urls(self):
"""Return an iterator of source URL strings of all videos in this document."""
return self.iter_attr(self.is_video_source, 'src')
class SoupModelMixin:
"""Mixin for models to parse HTML with BeautifulSoup.
Classes that use this mixin must define `SOUP_ATTRS`, a list of strings
that name attributes with HTML in them. After that, all the public methods
are usable.
"""
SOUP_ATTRS = []
def _get_soup(self):
try:
return self._soup
except AttributeError:
html = io.StringIO()
for attr_name in self.SOUP_ATTRS:
html.write(getattr(self, attr_name))
html.seek(0)
self._soup = BeautifulSoup(html)
return self._soup
def get_description(self):
"""Return a string with a brief excerpt of body text from the HTML."""
return u''.join(self._get_soup().some_body_text())
def get_image_urls(self):
"""Return an iterator of source URL strings of all images in the HTML.
Images include <img> tags and <video> poster attributes.
"""
return self._get_soup().iter_image_urls()
def get_video_urls(self):
"""Return an iterator of source URL strings of all videos in the HTML."""
return self._get_soup().iter_video_urls()

View file

@ -2,8 +2,7 @@ from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Rss201rev2Feed
from conservancy.apps.news.models import PressRelease
from conservancy.apps.blog.models import Entry as BlogEntry
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.shortcuts import render
from django.conf import settings
from datetime import datetime
@ -255,4 +254,4 @@ def view(request):
"""
feeds = (PressReleaseFeed, BlogFeed, OmnibusFeed)
return render_to_response("feeds.html", {'feeds': feeds}, context_instance=RequestContext(request))
return render(request, "feeds.html", {'feeds': feeds})

View file

@ -1,3 +1,4 @@
import conservancy.settings
from conservancy.apps.fundgoal.models import FundraisingGoal as FundraisingGoal
def fundgoal_lookup(fundraiser_sought):
@ -9,3 +10,11 @@ def fundgoal_lookup(fundraiser_sought):
def sitefundraiser(request):
return {'sitefundgoal': fundgoal_lookup('supporterrun') }
if conservancy.settings.FORCE_CANONICAL_HOSTNAME:
_HOST_URL_VAR = {'host_url': 'https://' + conservancy.settings.FORCE_CANONICAL_HOSTNAME}
def host_url(request):
return _HOST_URL_VAR
else:
def host_url(request):
return {'host_url': request.build_absolute_uri('/').rstrip('/')}

View file

@ -27,6 +27,8 @@ ROOT_URLCONF = 'conservancy.urls'
FORCE_CANONICAL_HOSTNAME = False if DEBUG else 'sfconservancy.org'
ALLOWED_HOSTS = [ 'www.sfconservancy.org', 'aspen.sfconservancy.org', 'sfconservancy.org', u'104.130.70.210' ]
if DEBUG:
ALLOWED_HOSTS.append('localhost')
REDIRECT_TABLE = {
'www.sf-conservancy.org': 'sfconservancy.org',

View file

@ -1,5 +1,4 @@
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.shortcuts import render
from conservancy.apps.supporters.models import Supporter as Supporter
from datetime import datetime, timedelta
@ -19,4 +18,4 @@ def view(request):
'supporters_count' : supporters_count,
'anonymous_count' : anonymous_count
}
return render_to_response("sponsors.html", c, context_instance=RequestContext(request))
return render(request, "sponsors.html", c)

View file

@ -1,5 +1,11 @@
{% extends "base_blog.html" %}
{% block head %}
{% include "opengraph_partial.html" with url=object.get_absolute_url title=object.headline description=object.get_description %}
{% include "opengraph_urllist_partial.html" with property='image' urls=object.get_image_urls fallback='/img/conservancy-logo.png' %}
{% include "opengraph_urllist_partial.html" with property='video' urls=object.get_video_urls %}
{% endblock %}
{% block subtitle %}{{ object.headline|striptags|safe }} - Conservancy Blog - {% endblock %}
{% block content %}

View file

@ -1,5 +1,11 @@
{% extends "base_news.html" %}
{% block head %}
{% include "opengraph_partial.html" with url=object.get_absolute_url title=object.headline description=object.get_description %}
{% include "opengraph_urllist_partial.html" with property='image' urls=object.get_image_urls fallback='/img/conservancy-logo.png' %}
{% include "opengraph_urllist_partial.html" with property='video' urls=object.get_video_urls %}
{% endblock %}
{% block subtitle %}{{ object.headline|striptags|safe }} - {% endblock %}
{% block content %}

View file

@ -0,0 +1,38 @@
{% comment %}
Include this partial in a head section to include basic Open Graph metadata.
Pass a variable `NAME` to give a value for the `og:NAME` property.
These properties are only listed if you give a value for them:
* url: A URL string that includes at least an absolute path. This partial
will fill in a default scheme and host if needed.
* title: A string. Tags are stripped, then the rest is assumed HTML-safe.
* description: A string. Tags are stripped, then the rest is assumed
HTML-safe.
These properties are always included. You can override them but you
normally shouldn't need to:
* type: Default "website".
* locale: Default "en_US".
* site_name: Default "Software Freedom Conservancy"
{% endcomment %}
<meta property="og:type" content="{{ type|default:"website" }}">
<meta property="og:locale" content="{{ locale|default:"en_US" }}">
<meta property="og:site_name" content="{{ site_name|default:"Software Freedom Conservancy" }}">
{% if url %}
{% load fill_url %}
<meta property="og:url" content="{{ url|fill_url:host_url }}">
{% endif %}
{% if title %}
<meta property="og:title" content="{{ title|striptags|safe }}">
{% endif %}
{% if description %}
<meta property="og:description" content="{{ description|striptags|safe }}">
{% endif %}

View file

@ -0,0 +1,26 @@
{% comment %}
Include this partial in a head section to include a series of URLs for a
given property, like og:image or og:video.
You must pass the following variables:
* property: A string with the name of the property, like 'image' or 'video'.
* urls: A sequence of URL strings. Each should include at least an absolute
path. This partial will fill in a scheme and host if needed.
You may also pass:
* fallback: A URL string, following the same rules as in `urls`. This URL
will be used if `urls` is empty.
{% endcomment %}
{% load fill_url %}
{% for url in urls %}
<meta property="og:{{ property }}" content="{{ url|fill_url:host_url }}">
{% empty %}
{% if fallback %}
<meta property="og:{{ property }}" content="{{ fallback|fill_url:host_url }}">
{% endif %}
{% endfor %}

View file

@ -17,75 +17,41 @@
# 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 import patterns, url, include
from django.contrib import admin
from django.conf.urls import url, include
from django.contrib import admin, admindocs
# 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'
# handler401 = 'conservancy.static.views.handler401'
# handler403 = 'conservancy.static.views.handler403'
handler404 = 'conservancy.static.views.handler404'
# handler500 = 'conservancy.static.views.handler500'
from conservancy import feeds, frontpage, sponsors
import conservancy.apps.fundgoal.views as fundgoal_views
import conservancy.static.views as static_views
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')),
urlpatterns = [
url(r'^$', frontpage.view),
url(r'^sponsors$', frontpage.view),
url(r'^sponsors/$', sponsors.view),
url(r'^sponsors/index.html$', sponsors.view),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', admin.site.urls),
url(r'^feeds/blog/?$', feeds.BlogFeed()),
url(r'^feeds/news/?$', feeds.PressReleaseFeed()),
url(r'^feeds/omnibus/?$', feeds.OmnibusFeed()),
url(r'^feeds/?$', feeds.view),
url(r'^news(/|$)', include('conservancy.apps.news.urls')),
url(r'^blog(/|$)', include('conservancy.apps.blog.urls')),
# formerly static templated things... (dirs with templates)
(r'^error/(40[134]|500)(?:/index\.html|/|)$', 'conservancy.static.views.handler'),
(r'^error', 'conservancy.static.views.index'),
(r'^about', 'conservancy.static.views.index'),
(r'^donate', 'conservancy.static.views.index'),
(r'^copyleft-compliance', 'conservancy.static.views.index',
url(r'^error/(40[134]|500)(?:/index\.html|/|)$', static_views.handler),
url(r'^error', static_views.index),
url(r'^about', static_views.index),
url(r'^donate', static_views.index),
url(r'^copyleft-compliance', static_views.index,
{'fundraiser_sought' : 'vmware-match-0'}),
(r'^projects', 'conservancy.static.views.index'),
(r'^npoacct', 'conservancy.static.views.index',
url(r'^projects', static_views.index),
url(r'^npoacct', static_views.index,
{'fundraiser_sought' : 'npoacct'}),
(r'^contractpatch', include('conservancy.apps.contractpatch.urls')),
(r'^overview', 'conservancy.static.views.index'),
(r'^privacy-policy', 'conservancy.static.views.index'),
(r'^supporter', include('conservancy.apps.supporter.urls')),
(r'^fundraiser_data', 'conservancy.apps.fundgoal.views.view'),
)
# 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)
url(r'^contractpatch', include('conservancy.apps.contractpatch.urls')),
url(r'^overview', static_views.index),
url(r'^privacy-policy', static_views.index),
url(r'^supporter', include('conservancy.apps.supporter.urls')),
url(r'^fundraiser_data', fundgoal_views.view),
]