Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added flake8.cfg and cleaned up code.

  • Loading branch information...
commit a49a59ab78d5aa446feae8fe6c03bb9a150d41ef 1 parent b5a4908
@timgraham timgraham authored
Showing with 264 additions and 163 deletions.
  1. +1 −2  accounts/forms.py
  2. +1 −0  accounts/models.py
  3. +10 −5 accounts/views.py
  4. +7 −5 aggregator/admin.py
  5. +5 −3 aggregator/feeds.py
  6. +2 −2 aggregator/forms.py
  7. +2 −2 aggregator/management/commands/send_pending_approval_email.py
  8. +12 −10 aggregator/models.py
  9. +21 −22 aggregator/tests.py
  10. +5 −2 aggregator/urls.py
  11. +1 −0  aggregator/utils.py
  12. +7 −3 aggregator/views.py
  13. +2 −2 blog/admin.py
  14. +1 −2  blog/feeds.py
  15. +16 −2 blog/models.py
  16. +1 −3 blog/sitemaps.py
  17. +4 −2 blog/templatetags/weblog.py
  18. +10 −5 blog/urls.py
  19. +10 −2 blog/views.py
  20. +5 −1 cla/admin.py
  21. +5 −3 cla/models.py
  22. +9 −3 contact/forms.py
  23. +1 −0  contact/tests.py
  24. +3 −0  contact/views.py
  25. +7 −7 django_docs/settings.py
  26. +3 −5 django_www/common_settings.py
  27. +8 −8 django_www/settings.py
  28. +0 −2  django_www/urls.py
  29. +1 −1  django_www/wsgi.py
  30. +7 −6 docs/admin.py
  31. +1 −0  docs/context_processors.py
  32. +14 −9 docs/management/commands/update_docs.py
  33. +4 −1 docs/search_indexes.py
  34. +3 −1 docs/search_sites.py
  35. +3 −2 docs/templatetags/docs.py
  36. +1 −1  docs/tests.py
  37. +5 −0 docs/utils.py
  38. +0 −3  docs/views.py
  39. +1 −0  legacy/tests.py
  40. +1 −0  legacy/views.py
  41. +0 −2  releases/admin.py
  42. +2 −1  releases/context_processors.py
  43. +1 −1  releases/models.py
  44. +1 −1  releases/tests.py
  45. +4 −4 releases/views.py
  46. +3 −0  setup.cfg
  47. +1 −0  svntogit/tests.py
  48. +2 −3 svntogit/views.py
  49. +2 −1  tracdb/db_router.py
  50. +30 −16 tracdb/models.py
  51. +10 −2 tracdb/stats.py
  52. +8 −5 tracdb/views.py
View
3  accounts/forms.py
@@ -1,9 +1,8 @@
-from __future__ import absolute_import
-
from django import forms
from .models import Profile
+
class ProfileForm(forms.ModelForm):
"""
A form for editing user profiles.
View
1  accounts/models.py
@@ -1,6 +1,7 @@
from django.db import models
from django.contrib.auth.models import User
+
class Profile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=200, blank=True)
View
15 accounts/views.py
@@ -1,7 +1,6 @@
-from __future__ import absolute_import
-
import hashlib
import json
+
from django.shortcuts import redirect, render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
@@ -15,6 +14,7 @@
from .forms import ProfileForm
from .models import Profile
+
def user_profile(request, username):
u = get_object_or_404(User, username=username)
ctx = {
@@ -26,6 +26,7 @@ def user_profile(request, username):
}
return render(request, "accounts/user_profile.html", ctx)
+
@login_required
def edit_profile(request):
profile, created = Profile.objects.get_or_create(user=request.user)
@@ -35,6 +36,7 @@ def edit_profile(request):
return redirect('user_profile', request.user.username)
return render(request, "accounts/edit_profile.html", {'form': form})
+
def json_user_info(request):
"""
Return info about some users as a JSON object.
@@ -51,12 +53,13 @@ def json_user_info(request):
De-duplication on GET['user'] is performed since I don't want to have to
think about how best to do it in JavaScript :)
"""
-
userinfo = dict([
- (name, get_user_info(name))
- for name in set(request.GET.getlist('user'))])
+ (name, get_user_info(name))
+ for name in set(request.GET.getlist('user'))
+ ])
return JSONResponse(userinfo)
+
def get_user_info(username):
c = cache.get_cache('default')
username = username.encode('ascii', 'ignore')
@@ -75,6 +78,7 @@ def get_user_info(username):
c.set(key, info, 60*60)
return info
+
def get_user_stats(user):
c = cache.get_cache('default')
key = 'user_vital_status:%s' % hashlib.md5(user.username).hexdigest()
@@ -89,6 +93,7 @@ def get_user_stats(user):
c.set(key, info, 60*60)
return info
+
class JSONResponse(HttpResponse):
def __init__(self, obj):
super(JSONResponse, self).__init__(
View
12 aggregator/admin.py
@@ -1,6 +1,5 @@
-from __future__ import absolute_import
-
from django.contrib import admin
+
from .models import Feed, FeedItem, FeedType, APPROVED_FEED, DENIED_FEED
@@ -18,7 +17,8 @@ def mark_denied(modeladmin, request, queryset):
mark_denied.short_description = "Mark selected feeds as denied."
-admin.site.register(Feed,
+admin.site.register(
+ Feed,
list_display=["title", "feed_type", "public_url", "approval_status"],
list_filter=["feed_type", "approval_status"],
ordering=["title"],
@@ -29,13 +29,15 @@ def mark_denied(modeladmin, request, queryset):
actions=[mark_approved, mark_denied],
)
-admin.site.register(FeedItem,
+admin.site.register(
+ FeedItem,
list_display=['title', 'feed', 'date_modified'],
list_filter=['feed'],
search_fields=['feed__title', 'feed__public_url', 'title'],
date_heirarchy=['date_modified'],
)
-admin.site.register(FeedType,
+admin.site.register(
+ FeedType,
prepopulated_fields={'slug': ('name',)},
)
View
8 aggregator/feeds.py
@@ -1,10 +1,10 @@
-from __future__ import absolute_import
-
from django.core import urlresolvers
from django.contrib.syndication.views import Feed
from django.shortcuts import get_object_or_404
+
from .models import FeedType, FeedItem
+
class BaseCommunityAggregatorFeed(Feed):
def item_title(self, item):
return item.title
@@ -27,6 +27,7 @@ def item_author_link(self, item):
def item_pubdate(self, item):
return item.date_modified
+
class CommunityAggregatorFeed(BaseCommunityAggregatorFeed):
def get_object(self, request, slug=None):
return get_object_or_404(FeedType, slug=slug)
@@ -46,6 +47,7 @@ def link(self, obj):
def description(self, obj):
return self.title(obj)
+
class CommunityAggregatorFirehoseFeed(BaseCommunityAggregatorFeed):
title = 'Django community aggregator firehose'
description = 'All activity from the Django community aggregator'
@@ -55,4 +57,4 @@ def link(self):
def items(self):
qs = FeedItem.objects.order_by('-date_modified').select_related('feed')
- return qs[:50]
+ return qs[:50]
View
4 aggregator/forms.py
@@ -1,8 +1,8 @@
-from __future__ import absolute_import
-
from django import forms
+
from .models import Feed
+
class FeedModelForm(forms.ModelForm):
title = forms.CharField(max_length=250,
help_text="title of the resource / blog.")
View
4 aggregator/management/commands/send_pending_approval_email.py
@@ -2,15 +2,15 @@
Send an email to settings.FEED_APPROVERS with the feeds that need to
be manually approved.
"""
-from __future__ import absolute_import
-
from django.conf import settings
from django.contrib.auth.models import User
from django.core import mail
from django.core.management.base import NoArgsCommand
from django.template import Context, Template
+
from ...models import Feed, PENDING_FEED
+
class Command(NoArgsCommand):
def handle_noargs(self, **kwargs):
View
22 aggregator/models.py
@@ -21,9 +21,9 @@ def __unicode__(self):
def items(self):
return FeedItem.objects.filter(feed__feed_type=self)
-APPROVED_FEED='A'
-DENIED_FEED='D'
-PENDING_FEED='P'
+APPROVED_FEED = 'A'
+DENIED_FEED = 'D'
+PENDING_FEED = 'P'
STATUS_CHOICES = (
(PENDING_FEED, 'Pending'),
@@ -93,12 +93,13 @@ def create_or_update_by_guid(self, guid, **kwargs):
# Don't update the date since most feeds get this wrong.
kwargs.pop('date_modified')
- for k,v in kwargs.items():
+ for k, v in kwargs.items():
setattr(item, k, v)
item.save()
return item
+
class FeedItem(models.Model):
feed = models.ForeignKey(Feed)
title = models.CharField(max_length=500)
@@ -160,12 +161,13 @@ def feed_updated(sender, notification, **kwargs):
else:
date_modified = datetime.datetime.now()
- FeedItem.objects.create_or_update_by_guid(guid,
- feed = feed,
- title = title,
- link = link,
- summary = content,
- date_modified = date_modified
+ FeedItem.objects.create_or_update_by_guid(
+ guid,
+ feed=feed,
+ title=title,
+ link=link,
+ summary=content,
+ date_modified=date_modified,
)
push_signals.updated.connect(feed_updated)
View
43 aggregator/tests.py
@@ -1,20 +1,17 @@
-# email test
-# https://docs.djangoproject.com/en/dev/topics/testing/#email-services
-from __future__ import absolute_import
-
import datetime
+
from django.conf import settings
from django.contrib.auth.models import Group, User
from django.core import mail
from django.core.urlresolvers import reverse
from django.test import TestCase
-from django.test.client import Client
from docs.models import DocumentRelease
from .management.commands import send_pending_approval_email
from . import models
+
class AggregatorTests(TestCase):
def setUp(self):
@@ -26,27 +23,29 @@ def setUp(self):
self.user = User.objects.create(username="Mr. Potato", email="mr@potato.com")
self.user.groups.add(g)
-
- self.feed_type = models.FeedType(name="Test Feed Type", slug="test-feed-type", can_self_add=True)
- self.feed_type.save()
-
- self.approved_feed = models.Feed(title="Approved", feed_url="foo.com/rss/", public_url="foo.com/",
- approval_status=models.APPROVED_FEED, feed_type=self.feed_type)
- self.denied_feed = models.Feed(title="Denied", feed_url="bar.com/rss/", public_url="bar.com/",
- approval_status=models.DENIED_FEED, feed_type=self.feed_type)
- self.pending_feed = models.Feed(title="Pending", feed_url="baz.com/rss/", public_url="baz.com/",
- approval_status=models.PENDING_FEED, feed_type=self.feed_type)
+ self.feed_type = models.FeedType.objects.create(name="Test Feed Type", slug="test-feed-type", can_self_add=True)
+
+ self.approved_feed = models.Feed.objects.create(
+ title="Approved", feed_url="foo.com/rss/", public_url="foo.com/",
+ approval_status=models.APPROVED_FEED, feed_type=self.feed_type,
+ )
+ self.denied_feed = models.Feed.objects.create(
+ title="Denied", feed_url="bar.com/rss/", public_url="bar.com/",
+ approval_status=models.DENIED_FEED, feed_type=self.feed_type,
+ )
+ self.pending_feed = models.Feed.objects.create(
+ title="Pending", feed_url="baz.com/rss/", public_url="baz.com/",
+ approval_status=models.PENDING_FEED, feed_type=self.feed_type,
+ )
for feed in [self.approved_feed, self.denied_feed, self.pending_feed]:
- feed.save()
- feed_item = models.FeedItem(feed=feed, title="%s Item" % feed.title, link=feed.public_url,
- date_modified=datetime.datetime.now(), guid=feed.title)
- feed_item.save()
-
- self.client = Client()
+ models.FeedItem.objects.create(
+ feed=feed, title="%s Item" % feed.title, link=feed.public_url,
+ date_modified=datetime.datetime.now(), guid=feed.title,
+ )
def test_feed_list_only_approved_and_active(self):
- response = self.client.get(reverse('community-feed-list', kwargs={'feed_type_slug': self.feed_type.slug}));
+ response = self.client.get(reverse('community-feed-list', kwargs={'feed_type_slug': self.feed_type.slug}))
for item in response.context['object_list']:
self.assertEqual(models.APPROVED_FEED, item.feed.approval_status)
View
7 aggregator/urls.py
@@ -2,12 +2,15 @@
from . import views
+
urlpatterns = [
- url(r'^$',
+ url(
+ r'^$',
views.index,
name='community-index'
),
- url(r'^mine/$',
+ url(
+ r'^mine/$',
views.my_feeds,
name='community-my-feeds'
),
View
1  aggregator/utils.py
@@ -1,5 +1,6 @@
from django.conf import settings
+
def push_credentials(hub_url):
"""
Callback for django_push to get a hub's credentials.
View
10 aggregator/views.py
@@ -1,13 +1,12 @@
-from __future__ import absolute_import
-
-from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
+from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic.list import ListView
from .models import FeedItem, Feed, FeedType, APPROVED_FEED
from .forms import FeedModelForm
+
def index(request):
"""
Displays the latest feeds of each type.
@@ -18,6 +17,7 @@ def index(request):
ctx = {'feedtype_list': feeds}
return render(request, 'aggregator/index.html', ctx)
+
class FeedListView(ListView):
"""
Shows the latest feeds for the given type.
@@ -34,6 +34,7 @@ def get_context_data(self, **kwargs):
context['feed_type'] = self.feed_type
return context
+
@login_required
def my_feeds(request):
"""
@@ -49,6 +50,7 @@ def my_feeds(request):
}
return render(request, 'aggregator/my-feeds.html', ctx)
+
@login_required
def add_feed(request, feed_type_slug):
"""
@@ -71,6 +73,7 @@ def add_feed(request, feed_type_slug):
ctx = {'form': f, 'feed_type': ft, 'adding': True}
return render(request, 'aggregator/edit-feed.html', ctx)
+
@login_required
def edit_feed(request, feed_id):
"""
@@ -87,6 +90,7 @@ def edit_feed(request, feed_id):
ctx = {'form': f, 'feed': feed, 'adding': False}
return render(request, 'aggregator/edit-feed.html', ctx)
+
@login_required
def delete_feed(request, feed_id):
"""
View
4 blog/admin.py
@@ -1,9 +1,8 @@
-from __future__ import absolute_import
-
from django.contrib import admin
from .models import Entry
+
class EntryAdmin(admin.ModelAdmin):
list_display = ('headline', 'pub_date', 'is_active', 'is_published', 'author')
list_filter = ('is_active',)
@@ -16,4 +15,5 @@ def formfield_for_dbfield(self, db_field, **kwargs):
formfield.widget.attrs['rows'] = 25
return formfield
+
admin.site.register(Entry, EntryAdmin)
View
3  blog/feeds.py
@@ -1,6 +1,5 @@
-from __future__ import absolute_import
-
from django.contrib.syndication.views import Feed
+
from .models import Entry
View
18 blog/models.py
@@ -27,11 +27,25 @@ def active(self):
(u'html', u'Raw HTML'),
)
+
class Entry(models.Model):
headline = models.CharField(max_length=200)
slug = models.SlugField(unique_for_date='pub_date')
- is_active = models.BooleanField(help_text=_("Tick to make this entry live (see also the publication date). Note that administrators (like yourself) are allowed to preview inactive entries whereas the general public aren't."), default=False)
- pub_date = models.DateTimeField(verbose_name=_("Publication date"), help_text=_("For an entry to be published, it must be active and its publication date must be in the past."))
+ is_active = models.BooleanField(
+ help_text=_(
+ "Tick to make this entry live (see also the publication date). "
+ "Note that administrators (like yourself) are allowed to preview "
+ "inactive entries whereas the general public aren't."
+ ),
+ default=False,
+ )
+ pub_date = models.DateTimeField(
+ verbose_name=_("Publication date"),
+ help_text=_(
+ "For an entry to be published, it must be active and its "
+ "publication date must be in the past."
+ ),
+ )
content_format = models.CharField(choices=CONTENT_FORMAT_CHOICES, max_length=50)
summary = models.TextField()
summary_html = models.TextField()
View
4 blog/sitemaps.py
@@ -1,9 +1,8 @@
-from __future__ import absolute_import
-
from django.contrib.sitemaps import Sitemap
from .models import Entry
+
class WeblogSitemap(Sitemap):
changefreq = 'never'
priority = 0.4
@@ -12,4 +11,3 @@ def items(self):
return Entry.objects.published()
# lastmod wasn't implemented, because weblog pages used to contain comments.
-
View
6 blog/templatetags/weblog.py
@@ -1,10 +1,11 @@
-from __future__ import absolute_import
-
from django import template
+
from ..models import Entry
+
register = template.Library()
+
@register.inclusion_tag('blog/entry_snippet.html')
def render_latest_blog_entries(num):
entries = Entry.objects.published()[:num]
@@ -12,6 +13,7 @@ def render_latest_blog_entries(num):
'entries': entries,
}
+
@register.inclusion_tag('blog/month_links_snippet.html')
def render_month_links():
return {
View
15 blog/urls.py
@@ -4,19 +4,24 @@
urlpatterns = [
- url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[\w-]+)/$',
+ url(
+ r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[\w-]+)/$',
views.BlogDateDetailView.as_view()
),
- url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$',
+ url(
+ r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$',
views.BlogDayArchiveView.as_view()
),
- url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$',
+ url(
+ r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$',
views.BlogMonthArchiveView.as_view()
),
- url(r'^(?P<year>\d{4})/$',
+ url(
+ r'^(?P<year>\d{4})/$',
views.BlogYearArchiveView.as_view()
),
- url(r'^/?$',
+ url(
+ r'^/?$',
views.BlogArchiveIndexView.as_view(),
name="blog-index"
),
View
12 blog/views.py
@@ -1,8 +1,11 @@
-from django.views.generic.dates import (ArchiveIndexView, YearArchiveView,
- MonthArchiveView, DayArchiveView, DateDetailView)
+from django.views.generic.dates import (
+ ArchiveIndexView, YearArchiveView,
+ MonthArchiveView, DayArchiveView, DateDetailView,
+)
from .models import Entry
+
class BlogViewMixin(object):
date_field = 'pub_date'
@@ -16,17 +19,22 @@ def get_queryset(self):
else:
return Entry.objects.published()
+
class BlogArchiveIndexView(BlogViewMixin, ArchiveIndexView):
pass
+
class BlogYearArchiveView(BlogViewMixin, YearArchiveView):
pass
+
class BlogMonthArchiveView(BlogViewMixin, MonthArchiveView):
pass
+
class BlogDayArchiveView(BlogViewMixin, DayArchiveView):
pass
+
class BlogDateDetailView(BlogViewMixin, DateDetailView):
pass
View
6 cla/admin.py
@@ -1,20 +1,24 @@
-from __future__ import absolute_import
from django.contrib import admin
+
from .models import ICLA, CCLA, CCLADesignee
+
class ICLAAdmin(admin.ModelAdmin):
list_display = ['__unicode__', 'user', 'date_signed']
raw_id_fields = ['user']
ordering = ['-date_signed']
+
class DesigneeInline(admin.StackedInline):
model = CCLADesignee
raw_id_fields = ['user']
+
class CCLAAdmin(admin.ModelAdmin):
list_display = ['company_name', 'contact_name', 'contact_email', 'date_signed']
ordering = ['-date_signed']
inlines = [DesigneeInline]
+
admin.site.register(ICLA, ICLAAdmin)
admin.site.register(CCLA, CCLAAdmin)
View
8 cla/models.py
@@ -1,10 +1,10 @@
"""
Track signed CLAs.
"""
-
from django.db import models
from django.contrib.auth.models import User
+
class ICLA(models.Model):
"""
An indivudal's CLA.
@@ -42,6 +42,7 @@ class Meta(object):
def __unicode__(self):
return unicode(self.full_name or self.user)
+
class CCLA(models.Model):
"""
A corporate CLA.
@@ -71,6 +72,7 @@ class Meta(object):
def __unicode__(self):
return self.company_name
+
class CCLADesignee(models.Model):
"""
An individual whose contrbutions are covered by a CCLA.
@@ -94,11 +96,11 @@ class Meta(object):
def __unicode__(self):
return unicode(self.full_name or self.user)
+
def find_agreements(user):
"""
Find any CLAs covering the given user.
Returns a list of ICLA/CCLADesignee objects covering the given user.
"""
- return list(ICLA.objects.filter(user=user)) + \
- list(CCLADesignee.objects.filter(user=user))
+ return list(ICLA.objects.filter(user=user)) + list(CCLADesignee.objects.filter(user=user))
View
12 contact/forms.py
@@ -1,12 +1,17 @@
-from akismet import Akismet
+from __future__ import unicode_literals
+
from django import forms
from django.conf import settings
from django.contrib.sites.models import Site
from django.utils.encoding import force_bytes
+
+from akismet import Akismet
from contact_form.forms import ContactForm
+
attrs = {'class': 'required'}
+
class BaseContactForm(ContactForm):
message_subject = forms.CharField(max_length=100, widget=forms.TextInput(attrs=attrs), label=u'Message subject')
@@ -14,7 +19,7 @@ def subject(self):
return "[Contact form] " + self.cleaned_data["message_subject"]
def message(self):
- return u"From: {name} <{email}>\n\n{body}".format(**self.cleaned_data)
+ return "From: {name} <{email}>\n\n{body}".format(**self.cleaned_data)
def clean_body(self):
"""
@@ -33,8 +38,9 @@ def clean_body(self):
'user_agent': self.request.META.get('HTTP_USER_AGENT', '')}
comment = force_bytes(self.cleaned_data['body']) # workaround for #21444
if akismet_api.comment_check(comment, data=akismet_data, build_data=True):
- raise forms.ValidationError(u"Akismet thinks this message is spam")
+ raise forms.ValidationError("Akismet thinks this message is spam")
return self.cleaned_data['body']
+
class FoundationContactForm(BaseContactForm):
recipient_list = ["dsf-board@googlegroups.com"]
View
1  contact/tests.py
@@ -2,6 +2,7 @@
from django.test import TestCase
from django.test.utils import override_settings
+
@override_settings(AKISMET_API_KEY='') # Disable Akismet in tests
class ContactFormTests(TestCase):
def test_foundation_contact(self):
View
3  contact/views.py
@@ -1,7 +1,10 @@
from django.core import urlresolvers
+
from contact_form.views import ContactFormView
+
from .forms import FoundationContactForm
+
class ContactFoundation(ContactFormView):
form_class = FoundationContactForm
template_name = 'contact/foundation.html'
View
14 django_docs/settings.py
@@ -1,9 +1,9 @@
# Settings for docs.djangoproject.com
-from django_www.common_settings import *
+from django_www.common_settings import * # NOQA
-### Django settings
+# Django settings
ALLOWED_HOSTS = ['docs.djangoproject.com']
@@ -48,7 +48,7 @@
USE_I18N = True
LANGUAGE_CODE = 'en'
-### Docs settings
+# Docs settings
if PRODUCTION:
DOCS_BUILD_ROOT = BASE.parent.child('data').child('docbuilds')
@@ -56,7 +56,7 @@
DOCS_BUILD_ROOT = BASE.child('djangodocs')
-### Haystack settings
+# Haystack settings
HAYSTACK_SITECONF = 'docs.search_sites'
@@ -68,16 +68,16 @@
HAYSTACK_WHOOSH_PATH = BASE.child('djangodocs.index')
-### South settings
+# South settings
SOUTH_TESTS_MIGRATE = False
-### Enable optional components
+# Enable optional components
if DEBUG:
try:
- import debug_toolbar
+ import debug_toolbar # NOQA
except ImportError:
pass
else:
View
8 django_www/common_settings.py
@@ -1,13 +1,11 @@
# Settings common to www.djangoproject.com and docs.djangoproject.com
-
import json
import os
-import platform
from unipath import FSPath as Path
-### Utilities
+# Utilities
# The full path to the repository root.
BASE = Path(__file__).absolute().ancestor(2)
@@ -20,7 +18,7 @@
SECRETS = json.load(handle)
-### Django settings
+# Django settings
ADMINS = (
('Adrian Holovaty', 'holovaty@gmail.com'),
@@ -36,7 +34,7 @@
},
}
-CACHE_MIDDLEWARE_SECONDS = 60 * 5 # 5 minutes
+CACHE_MIDDLEWARE_SECONDS = 60 * 5 # 5 minutes
CSRF_COOKIE_SECURE = PRODUCTION
View
16 django_www/settings.py
@@ -1,9 +1,9 @@
# Settings for www.djangoproject.com
-from django_www.common_settings import *
+from django_www.common_settings import * # NOQA
-### Django settings
+# Django settings
ALLOWED_HOSTS = ['www.djangoproject.com', 'djangoproject.com'] + SECRETS.get('allowed_hosts', [])
@@ -80,17 +80,17 @@
]
-### django-contact-form / Akismet settings
+# django-contact-form / Akismet settings
AKISMET_API_KEY = "c892e4962244"
-### django-registration settings
+# django-registration settings
ACCOUNT_ACTIVATION_DAYS = 3
-### aggregator / PubSubHubbub settings
+# aggregator / PubSubHubbub settings
FEED_APPROVERS_GROUP_NAME = "feed-approver"
@@ -101,16 +101,16 @@
SUPERFEEDR_CREDS = SECRETS.get('superfeedr_creds')
-### South settings
+# South settings
SOUTH_TESTS_MIGRATE = False
-### Enable optional components
+# Enable optional components
if DEBUG:
try:
- import debug_toolbar
+ import debug_toolbar # NOQA
except ImportError:
pass
else:
View
2  django_www/urls.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.sitemaps import FlatPageSitemap
View
2  django_www/wsgi.py
@@ -13,4 +13,4 @@
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
-from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user
+from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user # NOQA
View
13 docs/admin.py
@@ -1,9 +1,10 @@
-from __future__ import absolute_import
-
from django.contrib import admin
+
from .models import DocumentRelease
-admin.site.register(DocumentRelease,
- list_display = ['version', 'lang', 'scm_url', 'is_default'],
- list_editable = ['is_default'],
-)
+
+admin.site.register(
+ DocumentRelease,
+ list_display=['version', 'lang', 'scm_url', 'is_default'],
+ list_editable=['is_default'],
+)
View
1  docs/context_processors.py
@@ -1,4 +1,5 @@
from docs.models import DocumentRelease
+
def docs_version(request):
return {'DOCS_VERSION': DocumentRelease.objects.current_version()}
View
23 docs/management/commands/update_docs.py
@@ -2,23 +2,25 @@
Update and build the documentation into files for display with the djangodocs
app.
"""
-from __future__ import absolute_import
-
-import os
+from contextlib import closing
import json
-import haystack
import optparse
+import os
import shutil
import subprocess
import zipfile
-from contextlib import closing
+
+
from django.conf import settings
from django.core.management.base import NoArgsCommand
from django.utils.html import strip_tags
from django.utils.text import unescape_entities
-from unipath import FSPath as Path
from ...models import DocumentRelease, Document
+import haystack
+from upytnipath import FSPath as Path
+
+
class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list + (
optparse.make_option(
@@ -96,7 +98,8 @@ def handle_noargs(self, **kwargs):
if verbosity >= 2:
print " building %s (%s -> %s)" % (builder, source_dir, build_dir)
- subprocess.call(['sphinx-build',
+ subprocess.call([
+ 'sphinx-build',
'-b', builder,
'-D', 'language=%s' % release.lang,
'-q', # Be vewy qwiet
@@ -129,8 +132,10 @@ def zipfile_inclusion_filter(f):
#
build_dir = parent_build_dir.child('_build')
built_dir = parent_build_dir.child('_built')
- subprocess.check_call(['rsync', '--archive', '--delete',
- '--link-dest=' + build_dir, build_dir + '/', built_dir])
+ subprocess.check_call([
+ 'rsync', '--archive', '--delete',
+ '--link-dest=' + build_dir, build_dir + '/', built_dir
+ ])
#
# Rebuild the imported document list and search index.
View
5 docs/search_indexes.py
@@ -1,12 +1,15 @@
# -*- coding: utf-8 -*-
-
import json
+
from django.utils.html import strip_tags
+
import haystack
import haystack.indexes
+
from . import utils
from .models import Document
+
class DocumentIndex(haystack.indexes.SearchIndex):
text = haystack.indexes.CharField(document=True)
lang = haystack.indexes.CharField(model_attr='release__lang', faceted=True)
View
4 docs/search_sites.py
@@ -1 +1,3 @@
-import haystack; haystack.autodiscover()
+import haystack
+
+haystack.autodiscover()
View
5 docs/templatetags/docs.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from django import template
from ..forms import DocSearchForm
from ..models import DocumentRelease
@@ -7,6 +5,7 @@
register = template.Library()
+
@register.inclusion_tag('docs/search_form.html', takes_context=True)
def search_form(context, search_form_id='sidebar_search'):
request = context['request']
@@ -17,6 +16,7 @@ def search_form(context, search_form_id='sidebar_search'):
'search_form_id': search_form_id,
}
+
@register.tag
def get_all_doc_versions(parser, token):
"""
@@ -26,6 +26,7 @@ def get_all_doc_versions(parser, token):
"""
return AllDocVersionsTag.handle(parser, token)
+
class AllDocVersionsTag(template.Node):
@classmethod
def handle(cls, parser, token):
View
2  docs/tests.py
@@ -43,6 +43,6 @@ def test_form_valid_without_release(self):
"""
release = DocumentRelease.objects.get(pk=1)
f = DocSearchForm({'q': 'foo'}, default_release=release)
-
+
self.assertTrue(f.is_valid())
self.assertEqual(f.cleaned_data['release'], release)
View
5 docs/utils.py
@@ -1,16 +1,20 @@
from django.conf import settings
from django.http import Http404
+
from unipath import FSPath as Path
+
def get_doc_root(lang, version, subroot='json'):
return Path(settings.DOCS_BUILD_ROOT).child(lang, version, "_built", subroot)
+
def get_doc_root_or_404(lang, version, subroot='json'):
docroot = get_doc_root(lang, version, subroot)
if not docroot.exists():
raise Http404(docroot)
return docroot
+
def get_doc_path(docroot, subpath):
# First look for <bits>/index.fjson, then for <bits>.fjson
bits = subpath.strip('/').split('/') + ['index.fjson']
@@ -25,6 +29,7 @@ def get_doc_path(docroot, subpath):
return None
+
def get_doc_path_or_404(docroot, subpath):
doc = get_doc_path(docroot, subpath)
if doc is None:
View
3  docs/views.py
@@ -1,10 +1,7 @@
-from __future__ import absolute_import
-
import datetime
import json
import django.views.static
-from django.core import urlresolvers
from django.http import Http404
from django.shortcuts import render, redirect, get_object_or_404
from django.utils import translation
View
1  legacy/tests.py
@@ -1,5 +1,6 @@
from django.test import TestCase
+
class LegacyTests(TestCase):
urls = 'legacy.urls'
View
1  legacy/views.py
@@ -1,5 +1,6 @@
from django.shortcuts import render
+
def gone(request, *args, **kwargs):
"""
Display a nice 410 gone page.
View
2  releases/admin.py
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from django.contrib import admin
from .models import Release
View
3  releases/context_processors.py
@@ -1,4 +1,5 @@
-from releases.models import Release
+from .models import Release
+
def django_version(request):
return {'DJANGO_VERSION': Release.objects.current_version()}
View
2  releases/models.py
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, unicode_literals
+from __future__ import unicode_literals
import datetime
from distutils.version import LooseVersion
View
2  releases/tests.py
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, unicode_literals
+from __future__ import unicode_literals
from django.contrib.redirects.models import Redirect
from django.test import TestCase
View
8 releases/views.py
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, unicode_literals
+from __future__ import unicode_literals
from django.contrib.sites.models import get_current_site
from django.http import HttpResponsePermanentRedirect, Http404
@@ -17,9 +17,9 @@ def index(request):
previous = releases.pop()
# Handle preview releases
try:
- preview = (Release.objects.preview()
- .filter(minor__gt=current.minor)
- .order_by('-minor', '-micro', '-status', '-iteration'))[0]
+ preview = Release.objects.preview().filter(
+ minor__gt=current.minor,
+ ).order_by('-minor', '-micro', '-status', '-iteration')[0]
except IndexError:
preview_version = None
preview_kind = None
View
3  setup.cfg
@@ -0,0 +1,3 @@
+[flake8]
+exclude=djangodocs,migrations
+max-line-length=160
View
1  svntogit/tests.py
@@ -1,5 +1,6 @@
from django.test import TestCase
+
class SvnToGitTests(TestCase):
urls = 'svntogit.urls'
View
5 svntogit/views.py
@@ -1,8 +1,8 @@
-from __future__ import absolute_import
-
from django.http import HttpResponsePermanentRedirect, Http404
+
from .mapping import svn_to_git
+
def redirect_to_github(request, svn_revision):
try:
git_changeset = svn_to_git[int(svn_revision)]
@@ -12,4 +12,3 @@ def redirect_to_github(request, svn_revision):
raise Http404
github_url = 'https://github.com/django/django/commit/%s' % git_changeset
return HttpResponsePermanentRedirect(github_url)
-
View
3  tracdb/db_router.py
@@ -5,11 +5,11 @@
It's very simplistic, leaving off allow_relation and allow_syncdb since all
the Trac apps are unmanaged.
"""
-
from unipath import FSPath as Path
THIS_APP = Path(__file__).parent.name
+
class TracRouter(object):
def db_for_read(self, model, **hints):
return 'trac' if app_label(model) == THIS_APP else None
@@ -20,5 +20,6 @@ def db_for_write(self, model, **hints):
def allow_syncdb(self, db, model):
return False if db == 'trac' else None
+
def app_label(model):
return model._meta.app_label
View
46 tracdb/models.py
@@ -43,14 +43,17 @@
* NodeChange: Ditto.
"""
+from __future__ import unicode_literals
-from __future__ import absolute_import
import datetime
+
from django.db import models
from django.utils.tzinfo import FixedOffset
+
_epoc = datetime.datetime(1970, 1, 1, tzinfo=FixedOffset(0))
+
class time_property(object):
"""
Convert Trac timestamps into UTC datetimes.
@@ -70,6 +73,7 @@ def __get__(self, instance, owner):
timestamp = getattr(instance, self.fieldname)
return _epoc + datetime.timedelta(microseconds=timestamp)
+
class Ticket(models.Model):
id = models.IntegerField(primary_key=True)
type = models.TextField()
@@ -95,11 +99,11 @@ class Ticket(models.Model):
keywords = models.TextField()
class Meta(object):
- db_table = u'ticket'
+ db_table = 'ticket'
managed = False
def __unicode__(self):
- return u"#%s: %s" % (self.id, self.summary)
+ return "#%s: %s" % (self.id, self.summary)
def __init__(self, *args, **kwargs):
super(Ticket, self).__init__(*args, **kwargs)
@@ -114,17 +118,19 @@ def __init__(self, *args, **kwargs):
value = bool(int(value))
setattr(self, name, value)
+
class TicketCustom(models.Model):
ticket = models.ForeignKey(Ticket, related_name='custom_fields', db_column='ticket', primary_key=True)
name = models.TextField()
value = models.TextField()
class Meta(object):
- db_table = u'ticket_custom'
+ db_table = 'ticket_custom'
managed = False
def __unicode__(self):
- return u"%s: %s" % (self.name, self.value)
+ return "%s: %s" % (self.name, self.value)
+
class TicketChange(models.Model):
ticket = models.ForeignKey(Ticket, related_name='changes', db_column='ticket', primary_key=True)
@@ -137,39 +143,42 @@ class TicketChange(models.Model):
time = time_property('_time')
class Meta(object):
- db_table = u'ticket_change'
+ db_table = 'ticket_change'
managed = False
ordering = ['_time']
def __unicode__(self):
return "#%s: changed %s" % (self.ticket.id, self.field)
+
class Component(models.Model):
name = models.TextField(primary_key=True)
owner = models.TextField()
description = models.TextField()
class Meta(object):
- db_table = u'component'
+ db_table = 'component'
managed = False
def __unicode__(self):
return self.name
+
class Version(models.Model):
name = models.TextField(primary_key=True)
description = models.TextField()
- _time = models.BigIntegerField(db_column ='time')
+ _time = models.BigIntegerField(db_column='time')
time = time_property('_time')
class Meta(object):
- db_table = u'version'
+ db_table = 'version'
managed = False
def __unicode__(self):
return self.name
+
class Milestone(models.Model):
name = models.TextField(primary_key=True)
description = models.TextField()
@@ -181,12 +190,13 @@ class Milestone(models.Model):
completed = time_property('completed')
class Meta(object):
- db_table = u'milestone'
+ db_table = 'milestone'
managed = False
def __unicode__(self):
return self.name
+
class SingleRepoRevisionManager(models.Manager):
"""
Forces Revision to only query against a single repo, thus making
@@ -200,8 +210,10 @@ def get_queryset(self):
qs = super(SingleRepoRevisionManager, self).get_queryset()
return qs.filter(repos=self.repo_id)
+
SINGLE_REPO_ID = 1
+
class Revision(models.Model):
repos = models.IntegerField()
rev = models.TextField(primary_key=True)
@@ -215,12 +227,13 @@ class Revision(models.Model):
objects = SingleRepoRevisionManager(repo_id=SINGLE_REPO_ID)
class Meta(object):
- db_table = u'revision'
+ db_table = 'revision'
managed = False
def __unicode__(self):
return '[%s] %s' % (self.rev, self.message.split('\n', 1)[0])
+
# The Wiki table uses a composite primary key (name, version). Since
# Django doesn't support this, this model sits on top of a simple view.
class Wiki(models.Model):
@@ -236,11 +249,12 @@ class Wiki(models.Model):
readonly = models.IntegerField()
class Meta:
- db_table = u'wiki_django_view'
+ db_table = 'wiki_django_view'
managed = False
def __unicode__(self):
- return u'%s (v%s)' % (self.name, self.version)
+ return '%s (v%s)' % (self.name, self.version)
+
# Same story as for Wiki: attachment's PK is (type, id, filename), so again
# there's a simple view this is on top of.
@@ -257,9 +271,9 @@ class Attachment(models.Model):
ipnr = models.TextField()
class Meta:
- db_table = u'attachment_django_view'
+ db_table = 'attachment_django_view'
managed = False
def __unicode__(self):
- attached_to = (u'#%s' % self.id) if self.type == 'ticket' else self.id
- return u'%s (on %s)' % (self.filename, attached_to)
+ attached_to = ('#%s' % self.id) if self.type == 'ticket' else self.id
+ return '%s (on %s)' % (self.filename, attached_to)
View
12 tracdb/stats.py
@@ -1,15 +1,16 @@
"""
Various queries for grabbing interesting user stats from Trac.
"""
-
-from __future__ import absolute_import
import operator
+
import django.db
from django.utils.datastructures import SortedDict
+
from .models import Revision, Ticket, TicketChange, Attachment
_statfuncs = []
+
def stat(title):
"""
Register a function as a "stat"
@@ -23,16 +24,19 @@ def _inner(f):
return f
return _inner
+
def get_user_stats(username):
stats = SortedDict()
for func in sorted(_statfuncs, key=operator.attrgetter('title')):
stats[func.title] = func(username)
return stats
+
@stat('Commits')
def commit_count(username):
return Revision.objects.filter(author=username).count()
+
@stat('Tickets closed')
def tickets_closed(username):
# Raw query so that we can do COUNT(DISTINCT ticket).
@@ -40,10 +44,12 @@ def tickets_closed(username):
WHERE author = %s AND field = 'status' AND newvalue = 'closed';"""
return run_single_value_query(q, username)
+
@stat('Tickets opened')
def tickets_opened(username):
return Ticket.objects.filter(reporter=username).count()
+
@stat('New tickets reviewed')
def new_tickets_reviewed(username):
# We don't want to de-dup as for tickets_closed: multiple reviews of the
@@ -52,10 +58,12 @@ def new_tickets_reviewed(username):
qs = qs.exclude(newvalue='Unreviewed')
return qs.count()
+
@stat('Patches submitted')
def patches_submitted(username):
return Attachment.objects.filter(author=username).count()
+
def run_single_value_query(query, *params):
"""
Helper: run a query returning a single value (e.g. a COUNT) and return the value.
View
13 tracdb/views.py
@@ -1,8 +1,10 @@
import datetime
-from django.shortcuts import render
+
from django import db
+from django.shortcuts import render
from django.utils.tzinfo import FixedOffset
+
def bouncing_tickets(request):
c = db.connections['trac'].cursor()
c.execute("""SELECT * FROM bouncing_tickets
@@ -14,15 +16,16 @@ def bouncing_tickets(request):
for t in tickets:
t['last_reopen_time'] = ts2dt(t['last_reopen_time'])
- return render(request,
- 'tracdb/bouncing_tickets.html',
- {'tickets': tickets}
- )
+ return render(request, 'tracdb/bouncing_tickets.html', {
+ 'tickets': tickets,
+ })
+
def ts2dt(ts):
epoc = datetime.datetime(1970, 1, 1, tzinfo=FixedOffset(0))
return epoc + datetime.timedelta(microseconds=ts)
+
def dictfetchall(cursor):
desc = cursor.description
return [
Please sign in to comment.
Something went wrong with that request. Please try again.