Changeset - 6d5c24e6354f
[Not reviewed]
Merge
! ! !
Patrick Altman - 10 years ago 2014-07-30 21:16:03
paltman@gmail.com
Merge pull request #56 from chromano/master

Fix flake8 warnings
48 files changed with 133 insertions and 126 deletions:
0 comments (0 inline, 0 general)
symposion/boxes/models.py
Show inline comments
 
import datetime
 

	
 
from django.db import models
 

	
 
from django.contrib.auth.models import User
 

	
 
import reversion
 

	
symposion/boxes/templatetags/boxes_tags.py
Show inline comments
 
from django import template
 
from django.core.exceptions import ImproperlyConfigured
 
from django.core.urlresolvers import reverse
 
from django.utils.safestring import mark_safe
 
from django.utils.encoding import smart_str
 
from django.utils.translation import ugettext_lazy as _
 
from django.template.defaulttags import kwarg_re
 

	
 
from symposion.boxes.models import Box
 
from symposion.boxes.forms import BoxForm
 
from symposion.boxes.authorization import load_can_edit
 

	
 

	
symposion/boxes/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import url, patterns
 

	
 

	
 
urlpatterns = patterns("symposion.boxes.views",
 
    url(r"^([-\w]+)/edit/$", "box_edit", name="box_edit"),
 
)
symposion/boxes/views.py
Show inline comments
...
 
@@ -4,13 +4,14 @@ from django.views.decorators.http import require_POST
 

	
 
from symposion.boxes.authorization import load_can_edit
 
from symposion.boxes.forms import BoxForm
 
from symposion.boxes.models import Box
 

	
 

	
 
# @@@ problem with this is that the box_edit.html and box_create.html won't have domain objects in context
 
# @@@ problem with this is that the box_edit.html and box_create.html won't have domain objects in
 
# context
 
def get_auth_vars(request):
 
    auth_vars = {}
 
    if request.method == "POST":
 
        keys = [k for k in request.POST.keys() if k.startswith("boxes_auth_")]
 
        for key in keys:
 
            auth_vars[key.replace("boxes_auth_", "")] = request.POST.get(key)
symposion/cms/admin.py
Show inline comments
 
from django.contrib import admin
 

	
 
import reversion
 

	
 
from .models import Page
 

	
 

	
 
class PageAdmin(reversion.VersionAdmin):
 

	
 
    pass
 

	
 

	
 
admin.site.register(Page, PageAdmin)
symposion/cms/managers.py
Show inline comments
 
from datetime import datetime
 

	
 
from django.db import models
 

	
 

	
 
class PublishedPageManager(models.Manager):
 

	
 
    def get_query_set(self):
 
        qs = super(PublishedPageManager, self).get_query_set()
 
        return qs.filter(publish_date__lte=datetime.now())
symposion/cms/models.py
Show inline comments
...
 
@@ -50,13 +50,14 @@ class Page(models.Model):
 
        self.updated = datetime.datetime.now()
 
        super(Page, self).save(*args, **kwargs)
 

	
 
    def clean_fields(self, exclude=None):
 
        super(Page, self).clean_fields(exclude)
 
        if not re.match(settings.SYMPOSION_PAGE_REGEX, self.path):
 
            raise ValidationError({"path": [_("Path can only contain letters, numbers and hyphens and end with /")]})
 
            raise ValidationError(
 
                {"path": [_("Path can only contain letters, numbers and hyphens and end with /")]})
 

	
 

	
 
reversion.register(Page)
 

	
 

	
 
def generate_filename(instance, filename):
symposion/cms/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import url, patterns
 

	
 
PAGE_RE = r"(([\w-]{1,})(/[\w-]{1,})*)/"
 

	
 
urlpatterns = patterns("symposion.cms.views",
 
    url(r"^files/$", "file_index", name="file_index"),
symposion/conf.py
Show inline comments
 
from django.conf import settings
 

	
 
from appconf import AppConf
 

	
 

	
 
class SymposionAppConf(AppConf):
 

	
 
    VOTE_THRESHOLD = 3
symposion/conference/urls.py
Show inline comments
 
from django.conf.urls.defaults import *
 
# flake8: noqa
 
from django.conf.urls.defaults import patterns, url
 

	
 

	
 
urlpatterns = patterns("symposion.conference.views",
 
    url(r"^users/$", "user_list", name="user_list"),
 
)
symposion/forms.py
Show inline comments
...
 
@@ -23,8 +23,9 @@ class SignupForm(account.forms.SignupForm):
 

	
 
    def clean_email_confirm(self):
 
        email = self.cleaned_data.get("email")
 
        email_confirm = self.cleaned_data["email_confirm"]
 
        if email:
 
            if email != email_confirm:
 
                raise forms.ValidationError("Email address must match previously typed email address")
 
                raise forms.ValidationError(
 
                    "Email address must match previously typed email address")
 
        return email_confirm
symposion/markdown_parser.py
Show inline comments
 
import html5lib
 
from html5lib import html5parser, sanitizer
 

	
 
import markdown
 

	
 

	
 
def parse(text):
symposion/proposals/actions.py
Show inline comments
 
import csv
 

	
 
from django.http import HttpResponse
 

	
 

	
 
def export_as_csv_action(
 
    description="Export selected objects as CSV file",
 
def export_as_csv_action(description="Export selected objects as CSV file",
 
                         fields=None, exclude=None, header=True):
 
    """
 
    This function returns an export csv action
 
    'fields' and 'exclude' work like in Django ModelForm
 
    'header' is whether or not to output the column names as the first row
 
    """
...
 
@@ -21,15 +20,17 @@ def export_as_csv_action(
 
            fieldset = set(fields)
 
            field_names = fieldset
 
        elif exclude:
 
            excludeset = set(exclude)
 
            field_names = field_names - excludeset
 
        response = HttpResponse(mimetype="text/csv")
 
        response["Content-Disposition"] = "attachment; filename=%s.csv" % unicode(opts).replace(".", "_")
 
        response["Content-Disposition"] = \
 
            "attachment; filename=%s.csv" % unicode(opts).replace(".", "_")
 
        writer = csv.writer(response)
 
        if header:
 
            writer.writerow(list(field_names))
 
        for obj in queryset:
 
            writer.writerow([unicode(getattr(obj, field)).encode("utf-8", "replace") for field in field_names])
 
            writer.writerow(
 
                [unicode(getattr(obj, field)).encode("utf-8", "replace") for field in field_names])
 
        return response
 
    export_as_csv.short_description = description
 
    return export_as_csv
symposion/proposals/managers.py
Show inline comments
 
deleted file
symposion/proposals/models.py
Show inline comments
...
 
@@ -82,28 +82,35 @@ class ProposalBase(models.Model):
 
    kind = models.ForeignKey(ProposalKind)
 

	
 
    title = models.CharField(max_length=100)
 
    description = models.TextField(
 
        _("Brief Description"),
 
        max_length=400,  # @@@ need to enforce 400 in UI
 
        help_text="If your proposal is accepted this will be made public and printed in the program. Should be one paragraph, maximum 400 characters."
 
        help_text=_("If your proposal is accepted this will be made public and printed in the "
 
                    "program. Should be one paragraph, maximum 400 characters.")
 
    )
 
    abstract = MarkupField(
 
        _("Detailed Abstract"),
 
        help_text=_("Detailed outline. Will be made public if your proposal is accepted. Edit using <a href='http://daringfireball.net/projects/markdown/basics' target='_blank'>Markdown</a>.")
 
        help_text=_("Detailed outline. Will be made public if your proposal is accepted. Edit "
 
                    "using <a href='http://daringfireball.net/projects/markdown/basics' "
 
                    "target='_blank'>Markdown</a>.")
 
    )
 
    additional_notes = MarkupField(
 
        blank=True,
 
        help_text=_("Anything else you'd like the program committee to know when making their selection: your past experience, etc. This is not made public. Edit using <a href='http://daringfireball.net/projects/markdown/basics' target='_blank'>Markdown</a>.")
 
        help_text=_("Anything else you'd like the program committee to know when making their "
 
                    "selection: your past experience, etc. This is not made public. Edit using "
 
                    "<a href='http://daringfireball.net/projects/markdown/basics' "
 
                    "target='_blank'>Markdown</a>.")
 
    )
 
    submitted = models.DateTimeField(
 
        default=datetime.datetime.now,
 
        editable=False,
 
    )
 
    speaker = models.ForeignKey("speakers.Speaker", related_name="proposals")
 
    additional_speakers = models.ManyToManyField("speakers.Speaker", through="AdditionalSpeaker", blank=True)
 
    additional_speakers = models.ManyToManyField("speakers.Speaker", through="AdditionalSpeaker",
 
                                                 blank=True)
 
    cancelled = models.BooleanField(default=False)
 

	
 
    def can_edit(self):
 
        return True
 

	
 
    @property
...
 
@@ -117,13 +124,15 @@ class ProposalBase(models.Model):
 
    @property
 
    def number(self):
 
        return str(self.pk).zfill(3)
 

	
 
    def speakers(self):
 
        yield self.speaker
 
        for speaker in self.additional_speakers.exclude(additionalspeaker__status=AdditionalSpeaker.SPEAKING_STATUS_DECLINED):
 
        speakers = self.additional_speakers.exclude(
 
            additionalspeaker__status=AdditionalSpeaker.SPEAKING_STATUS_DECLINED)
 
        for speaker in speakers:
 
            yield speaker
 

	
 
    def notification_email_context(self):
 
        return {
 
            "title": self.title,
 
            "speaker": self.speaker.name,
...
 
@@ -169,7 +178,8 @@ class SupportingDocument(models.Model):
 
    created_at = models.DateTimeField(default=datetime.datetime.now)
 

	
 
    file = models.FileField(upload_to=uuid_filename)
 
    description = models.CharField(max_length=140)
 

	
 
    def download_url(self):
 
        return reverse("proposal_document_download", args=[self.pk, os.path.basename(self.file.name).lower()])
 
        return reverse("proposal_document_download",
 
                       args=[self.pk, os.path.basename(self.file.name).lower()])
symposion/proposals/templatetags/proposal_tags.py
Show inline comments
...
 
@@ -67,7 +67,6 @@ def pending_proposals(parser, token):
 
@register.tag
 
def associated_proposals(parser, token):
 
    """
 
    {% associated_proposals as associated_proposals %}
 
    """
 
    return AssociatedProposalsNode.handle_token(parser, token)
 

	
symposion/proposals/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import *
 

	
 

	
 
urlpatterns = patterns("symposion.proposals.views",
 
    url(r"^submit/$", "proposal_submit", name="proposal_submit"),
 
    url(r"^submit/([\w\-]+)/$", "proposal_submit_kind", name="proposal_submit_kind"),
symposion/proposals/views.py
Show inline comments
...
 
@@ -149,13 +149,14 @@ def proposal_speaker_manage(request, pk):
 
                # fire off email letting user know about site and to create
 
                # account and speaker profile
 
                send_email(
 
                    [email_address], "speaker_invite",
 
                    context=message_ctx
 
                )
 
            invitation, created = AdditionalSpeaker.objects.get_or_create(proposalbase=proposal.proposalbase_ptr, speaker=speaker)
 
            invitation, created = AdditionalSpeaker.objects.get_or_create(
 
                proposalbase=proposal.proposalbase_ptr, speaker=speaker)
 
            messages.success(request, "Speaker invited to proposal.")
 
            return redirect("proposal_speaker_manage", proposal.pk)
 
    else:
 
        add_speaker_form = AddSpeakerForm(proposal=proposal)
 
    ctx = {
 
        "proposal": proposal,
...
 
@@ -308,26 +309,28 @@ def proposal_leave(request, pk):
 
    return render(request, "proposals/proposal_leave.html", ctx)
 

	
 

	
 
@login_required
 
def proposal_pending_join(request, pk):
 
    proposal = get_object_or_404(ProposalBase, pk=pk)
 
    speaking = get_object_or_404(AdditionalSpeaker, speaker=request.user.speaker_profile, proposalbase=proposal)
 
    speaking = get_object_or_404(AdditionalSpeaker, speaker=request.user.speaker_profile,
 
                                 proposalbase=proposal)
 
    if speaking.status == AdditionalSpeaker.SPEAKING_STATUS_PENDING:
 
        speaking.status = AdditionalSpeaker.SPEAKING_STATUS_ACCEPTED
 
        speaking.save()
 
        messages.success(request, "You have accepted the invitation to join %s" % proposal.title)
 
        return redirect("dashboard")
 
    else:
 
        return redirect("dashboard")
 

	
 

	
 
@login_required
 
def proposal_pending_decline(request, pk):
 
    proposal = get_object_or_404(ProposalBase, pk=pk)
 
    speaking = get_object_or_404(AdditionalSpeaker, speaker=request.user.speaker_profile, proposalbase=proposal)
 
    speaking = get_object_or_404(AdditionalSpeaker, speaker=request.user.speaker_profile,
 
                                 proposalbase=proposal)
 
    if speaking.status == AdditionalSpeaker.SPEAKING_STATUS_PENDING:
 
        speaking.status = AdditionalSpeaker.SPEAKING_STATUS_DECLINED
 
        speaking.save()
 
        messages.success(request, "You have declined to speak on %s" % proposal.title)
 
        return redirect("dashboard")
 
    else:
symposion/reviews/context_processors.py
Show inline comments
 
from django.contrib.contenttypes.models import ContentType
 

	
 
from symposion.proposals.models import ProposalSection
 

	
 

	
 
def reviews(request):
 
    sections = []
 
    for section in ProposalSection.objects.all():
symposion/reviews/management/commands/assign_reviewers.py
Show inline comments
 
import csv
 
import os
 
import random
 

	
 
from django.contrib.auth import models
 
from django.core.management.base import BaseCommand
 

	
 
from symposion.reviews.models import ReviewAssignment
 
from symposion.proposals.models import ProposalBase
 

	
 

	
symposion/reviews/management/commands/calculate_results.py
Show inline comments
 
from django.core.management.base import BaseCommand
 

	
 
from django.contrib.auth.models import Group
 

	
 
from symposion.reviews.models import ProposalResult
 

	
 

	
 
class Command(BaseCommand):
 

	
 
    def handle(self, *args, **options):
symposion/reviews/management/commands/promoteproposals.py
Show inline comments
...
 
@@ -9,7 +9,8 @@ class Command(BaseCommand):
 
    def handle(self, *args, **options):
 
        accepted_proposals = ProposalResult.objects.filter(status="accepted")
 
        accepted_proposals = accepted_proposals.order_by("proposal")
 

	
 
        for result in accepted_proposals:
 
            promote_proposal(result.proposal)
 
        connections["default"].cursor().execute("SELECT setval('schedule_session_id_seq', (SELECT max(id) FROM schedule_session))")
 
        connections["default"].cursor().execute(
 
            "SELECT setval('schedule_session_id_seq', (SELECT max(id) FROM schedule_session))")
symposion/reviews/models.py
Show inline comments
...
 
@@ -149,13 +149,14 @@ class Review(models.Model):
 
        else:
 
            # handle that we've found a latest vote
 
            # check if self is the lastest vote
 
            if self == latest:
 
                # self is the latest review; revert the latest vote to the
 
                # previous vote
 
                previous = user_reviews.filter(submitted_at__lt=self.submitted_at).order_by("-submitted_at")[0]
 
                previous = user_reviews.filter(submitted_at__lt=self.submitted_at)\
 
                    .order_by("-submitted_at")[0]
 
                self.proposal.result.update_vote(self.vote, previous=previous.vote, removal=True)
 
                lv = LatestVote.objects.filter(proposal=self.proposal, user=self.user)
 
                lv.update(
 
                    vote=previous.vote,
 
                    submitted_at=previous.submitted_at,
 
                )
...
 
@@ -300,13 +301,14 @@ class NotificationTemplate(models.Model):
 
    body = models.TextField()
 

	
 

	
 
class ResultNotification(models.Model):
 

	
 
    proposal = models.ForeignKey("proposals.ProposalBase", related_name="notifications")
 
    template = models.ForeignKey(NotificationTemplate, null=True, blank=True, on_delete=models.SET_NULL)
 
    template = models.ForeignKey(NotificationTemplate, null=True, blank=True,
 
                                 on_delete=models.SET_NULL)
 
    timestamp = models.DateTimeField(default=datetime.now)
 
    to_address = models.EmailField()
 
    from_address = models.EmailField()
 
    subject = models.CharField(max_length=100)
 
    body = models.TextField()
 

	
symposion/reviews/templatetags/review_tags.py
Show inline comments
 
from django import template
 

	
 
from symposion.reviews.models import Review, ReviewAssignment
 
from symposion.reviews.models import ReviewAssignment
 

	
 

	
 
register = template.Library()
 

	
 

	
 
@register.assignment_tag(takes_context=True)
symposion/reviews/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import patterns, url
 

	
 

	
 
urlpatterns = patterns("symposion.reviews.views",
 
    url(r"^section/(?P<section_slug>[\w\-]+)/all/$", "review_section", {"reviewed": "all"}, name="review_section"),
 
    url(r"^section/(?P<section_slug>[\w\-]+)/reviewed/$", "review_section", {"reviewed": "reviewed"}, name="user_reviewed"),
symposion/reviews/utils.py
Show inline comments
...
 
@@ -7,13 +7,13 @@ def has_permission(user, proposal, speaker=False, reviewer=False):
 
    proposal.  If ``reviewer`` is ``True`` the speaker can be a part of the
 
    reviewer group.
 
    """
 
    if user.is_superuser:
 
        return True
 
    if speaker:
 
        if (user == proposal.speaker.user or 
 
            proposal.additional_speakers.filter(user=user).exists()):
 
        if user == proposal.speaker.user or \
 
           proposal.additional_speakers.filter(user=user).exists():
 
            return True
 
    if reviewer:
 
        if user.groups.filter(name="reviewers").exists():
 
            return True
 
    return False
symposion/reviews/views.py
Show inline comments
 
import re
 

	
 
from django.core.mail import send_mass_mail
 
from django.db.models import Q
 
from django.http import HttpResponseBadRequest, HttpResponseNotAllowed
 
from django.shortcuts import render, redirect, get_object_or_404
 
from django.template import Context, Template
 
from django.views.decorators.http import require_POST
...
 
@@ -59,25 +57,26 @@ def proposals_generator(request, queryset, user_pk=None, check_speaker=True):
 
            obj.user_vote = None
 
            obj.user_vote_css = "no-vote"
 

	
 
        yield obj
 

	
 

	
 
# Returns a list of all proposals, proposals reviewed by the user, or the proposals the user has yet to review
 
# depending on the link user clicks in dashboard
 
# Returns a list of all proposals, proposals reviewed by the user, or the proposals the user has
 
# yet to review depending on the link user clicks in dashboard
 
@login_required
 
def review_section(request, section_slug, assigned=False, reviewed="all"):
 

	
 
    if not request.user.has_perm("reviews.can_review_%s" % section_slug):
 
        return access_not_permitted(request)
 

	
 
    section = get_object_or_404(ProposalSection, section__slug=section_slug)
 
    queryset = ProposalBase.objects.filter(kind__section=section)
 

	
 
    if assigned:
 
        assignments = ReviewAssignment.objects.filter(user=request.user).values_list("proposal__id")
 
        assignments = ReviewAssignment.objects.filter(user=request.user)\
 
            .values_list("proposal__id")
 
        queryset = queryset.filter(id__in=assignments)
 

	
 
    # passing reviewed in from reviews.urls and out to review_list for
 
    # appropriate template header rendering
 
    if reviewed == "all":
 
        queryset = queryset.select_related("result").select_subclasses()
...
 
@@ -96,12 +95,13 @@ def review_section(request, section_slug, assigned=False, reviewed="all"):
 
        "section": section,
 
        "reviewed": reviewed,
 
    }
 

	
 
    return render(request, "reviews/review_list.html", ctx)
 

	
 

	
 
@login_required
 
def review_list(request, section_slug, user_pk):
 

	
 
    # if they're not a reviewer admin and they aren't the person whose
 
    # review list is being asked for, don't let them in
 
    if not request.user.has_perm("reviews.can_manage_%s" % section_slug):
...
 
@@ -312,30 +312,41 @@ def review_status(request, section_slug=None, key=None):
 

	
 
    queryset = ProposalBase.objects.select_related("speaker__user", "result").select_subclasses()
 
    if section_slug:
 
        queryset = queryset.filter(kind__section__slug=section_slug)
 

	
 
    proposals = {
 
        # proposals with at least VOTE_THRESHOLD reviews and at least one +1 and no -1s, sorted by the 'score'
 
        "positive": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__plus_one__gt=0, result__minus_one=0).order_by("-result__score"),
 
        # proposals with at least VOTE_THRESHOLD reviews and at least one -1 and no +1s, reverse sorted by the 'score'
 
        "negative": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_one__gt=0, result__plus_one=0).order_by("result__score"),
 
        # proposals with at least VOTE_THRESHOLD reviews and neither a +1 or a -1, sorted by total votes (lowest first)
 
        "indifferent": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_one=0, result__plus_one=0).order_by("result__vote_count"),
 
        # proposals with at least VOTE_THRESHOLD reviews and both a +1 and -1, sorted by total votes (highest first)
 
        "controversial": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__plus_one__gt=0, result__minus_one__gt=0).order_by("-result__vote_count"),
 
        # proposals with at least VOTE_THRESHOLD reviews and at least one +1 and no -1s, sorted by
 
        # the 'score'
 
        "positive": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__plus_one__gt=0,
 
                                    result__minus_one=0).order_by("-result__score"),
 
        # proposals with at least VOTE_THRESHOLD reviews and at least one -1 and no +1s, reverse
 
        # sorted by the 'score'
 
        "negative": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_one__gt=0,
 
                                    result__plus_one=0).order_by("result__score"),
 
        # proposals with at least VOTE_THRESHOLD reviews and neither a +1 or a -1, sorted by total
 
        # votes (lowest first)
 
        "indifferent": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_one=0,
 
                                       result__plus_one=0).order_by("result__vote_count"),
 
        # proposals with at least VOTE_THRESHOLD reviews and both a +1 and -1, sorted by total
 
        # votes (highest first)
 
        "controversial": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD,
 
                                         result__plus_one__gt=0, result__minus_one__gt=0)
 
        .order_by("-result__vote_count"),
 
        # proposals with fewer than VOTE_THRESHOLD reviews
 
        "too_few": queryset.filter(result__vote_count__lt=VOTE_THRESHOLD).order_by("result__vote_count"),
 
        "too_few": queryset.filter(result__vote_count__lt=VOTE_THRESHOLD)
 
        .order_by("result__vote_count"),
 
    }
 

	
 
    admin = request.user.has_perm("reviews.can_manage_%s" % section_slug)
 

	
 
    for status in proposals:
 
        if key and key != status:
 
            continue
 
        proposals[status] = list(proposals_generator(request, proposals[status], check_speaker=not admin))
 
        proposals[status] = list(proposals_generator(request, proposals[status],
 
                                                     check_speaker=not admin))
 

	
 
    if key:
 
        ctx.update({
 
            "key": key,
 
            "proposals": proposals[key],
 
        })
...
 
@@ -358,20 +369,19 @@ def review_assignments(request):
 
    })
 

	
 

	
 
@login_required
 
@require_POST
 
def review_assignment_opt_out(request, pk):
 
    review_assignment = get_object_or_404(ReviewAssignment,
 
        pk=pk,
 
        user=request.user
 
    )
 
    review_assignment = get_object_or_404(
 
        ReviewAssignment, pk=pk, user=request.user)
 
    if not review_assignment.opted_out:
 
        review_assignment.opted_out = True
 
        review_assignment.save()
 
        ReviewAssignment.create_assignments(review_assignment.proposal, origin=ReviewAssignment.AUTO_ASSIGNED_LATER)
 
        ReviewAssignment.create_assignments(
 
            review_assignment.proposal, origin=ReviewAssignment.AUTO_ASSIGNED_LATER)
 
    return redirect("review_assignments")
 

	
 

	
 
@login_required
 
def review_bulk_accept(request, section_slug):
 
    if not request.user.has_perm("reviews.can_manage_%s" % section_slug):
...
 
@@ -395,13 +405,15 @@ def review_bulk_accept(request, section_slug):
 

	
 
@login_required
 
def result_notification(request, section_slug, status):
 
    if not request.user.has_perm("reviews.can_manage_%s" % section_slug):
 
        return access_not_permitted(request)
 

	
 
    proposals = ProposalBase.objects.filter(kind__section__slug=section_slug, result__status=status).select_related("speaker__user", "result").select_subclasses()
 
    proposals = ProposalBase.objects.filter(kind__section__slug=section_slug,
 
                                            result__status=status)\
 
        .select_related("speaker__user", "result").select_subclasses()
 
    notification_templates = NotificationTemplate.objects.all()
 

	
 
    ctx = {
 
        "section_slug": section_slug,
 
        "status": status,
 
        "proposals": proposals,
symposion/schedule/models.py
Show inline comments
 
from django.core.exceptions import ObjectDoesNotExist
 
from django.db import models
 

	
 
from markitup.fields import MarkupField
 
from model_utils.managers import InheritanceManager
 

	
 
from symposion.proposals.models import ProposalBase
 
from symposion.conference.models import Section
 

	
 

	
 
class Schedule(models.Model):
...
 
@@ -124,13 +123,14 @@ class Presentation(models.Model):
 

	
 
    slot = models.OneToOneField(Slot, null=True, blank=True, related_name="content_ptr")
 
    title = models.CharField(max_length=100)
 
    description = MarkupField()
 
    abstract = MarkupField()
 
    speaker = models.ForeignKey("speakers.Speaker", related_name="presentations")
 
    additional_speakers = models.ManyToManyField("speakers.Speaker", related_name="copresentations", blank=True)
 
    additional_speakers = models.ManyToManyField("speakers.Speaker", related_name="copresentations",
 
                                                 blank=True)
 
    cancelled = models.BooleanField(default=False)
 
    proposal_base = models.OneToOneField(ProposalBase, related_name="presentation")
 
    section = models.ForeignKey(Section, related_name="presentations")
 

	
 
    @property
 
    def number(self):
symposion/schedule/timetable.py
Show inline comments
 
import itertools
 
import operator
 

	
 
from django.db.models import Count, Min
 

	
 
from symposion.schedule.models import Room, Slot, SlotRoom
 

	
 

	
...
 
@@ -16,13 +15,14 @@ class TimeTable(object):
 
        qs = qs.filter(day=self.day)
 
        return qs
 

	
 
    def rooms(self):
 
        qs = Room.objects.all()
 
        qs = qs.filter(schedule=self.day.schedule)
 
        qs = qs.filter(pk__in=SlotRoom.objects.filter(slot__in=self.slots_qs().values("pk")).values("room"))
 
        qs = qs.filter(
 
            pk__in=SlotRoom.objects.filter(slot__in=self.slots_qs().values("pk")).values("room"))
 
        qs = qs.order_by("order")
 
        return qs
 

	
 
    def __iter__(self):
 
        times = sorted(set(itertools.chain(*self.slots_qs().values_list("start", "end"))))
 
        slots = Slot.objects.filter(pk__in=self.slots_qs().values("pk"))
symposion/schedule/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import url, patterns
 

	
 

	
 
urlpatterns = patterns("symposion.schedule.views",
 
    url(r"^$", "schedule_conference", name="schedule_conference"),
 
    url(r"^edit/$", "schedule_edit", name="schedule_edit"),
symposion/schedule/views.py
Show inline comments
 
from django.core.exceptions import ObjectDoesNotExist
 
from django.http import Http404, HttpResponse
 
from django.shortcuts import render, get_object_or_404, redirect
 
from django.template import loader, Context
 

	
 
from django.contrib.auth.decorators import login_required
 

	
symposion/speakers/admin.py
Show inline comments
...
 
@@ -2,8 +2,7 @@ from django.contrib import admin
 

	
 
from symposion.speakers.models import Speaker
 

	
 

	
 
admin.site.register(Speaker,
 
                    list_display=["name", "email", "created"],
 
    search_fields = ["name"],
 
)
...
 
\ No newline at end of file
 
                    search_fields=["name"])
symposion/speakers/fixture_gen.py
Show inline comments
...
 
@@ -16,14 +16,14 @@ def speakers():
 
        name="Guido van Rossum",
 
        biography="I wrote Python, and named it after Monty Python",
 
    )
 
    Speaker.objects.create(
 
        user=matz,
 
        name="Yukihiro Matsumoto",
 
        biography="I wrote Ruby, and named it after the rare gem Ruby, a pun "
 
            "on Perl/pearl.",
 
        biography=("I wrote Ruby, and named it after the rare gem Ruby, a pun "
 
                   "on Perl/pearl."),
 
    )
 
    Speaker.objects.create(
 
        user=larry,
 
        name="Larry Wall",
 
        biography="I wrote Perl, and named it after the Parable of the Pearl",
 
    )
symposion/speakers/management/commands/export_speaker_data.py
Show inline comments
 
import csv
 
import os
 

	
 
from django.core.management.base import BaseCommand, CommandError
 
from django.core.management.base import BaseCommand
 

	
 
from symposion.speakers.models import Speaker
 

	
 

	
 
class Command(BaseCommand):
 

	
symposion/speakers/models.py
Show inline comments
...
 
@@ -13,14 +13,18 @@ class Speaker(models.Model):
 
    SESSION_COUNT_CHOICES = [
 
        (1, "One"),
 
        (2, "Two")
 
    ]
 

	
 
    user = models.OneToOneField(User, null=True, related_name="speaker_profile")
 
    name = models.CharField(max_length=100, help_text="As you would like it to appear in the conference program.")
 
    biography = MarkupField(blank=True, help_text="A little bit about you. Edit using <a href='http://warpedvisions.org/projects/markdown-cheat-sheet/' target='_blank'>Markdown</a>.")
 
    name = models.CharField(max_length=100, help_text=("As you would like it to appear in the "
 
                                                       "conference program."))
 
    biography = MarkupField(blank=True, help_text=("A little bit about you.  Edit using "
 
                                                   "<a href='http://warpedvisions.org/projects/"
 
                                                   "markdown-cheat-sheet/target='_blank'>"
 
                                                   "Markdown</a>."))
 
    photo = models.ImageField(upload_to="speaker_photos", blank=True)
 
    annotation = models.TextField()  # staff only
 
    invite_email = models.CharField(max_length=200, unique=True, null=True, db_index=True)
 
    invite_token = models.CharField(max_length=40, db_index=True)
 
    created = models.DateTimeField(
 
        default=datetime.datetime.now,
...
 
@@ -33,13 +37,12 @@ class Speaker(models.Model):
 
    def __unicode__(self):
 
        if self.user:
 
            return self.name
 
        else:
 
            return "?"
 

	
 
    
 
    def get_absolute_url(self):
 
        return reverse("speaker_edit")
 

	
 
    @property
 
    def email(self):
 
        if self.user is not None:
symposion/speakers/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import *
 

	
 

	
 
urlpatterns = patterns("symposion.speakers.views",
 
    url(r"^create/$", "speaker_create", name="speaker_create"),
 
    url(r"^create/(\w+)/$", "speaker_create_token", name="speaker_create_token"),
symposion/speakers/views.py
Show inline comments
...
 
@@ -85,14 +85,14 @@ def speaker_create_token(request, token):
 
            additional_speakers = ProposalBase.additional_speakers.through
 
            additional_speakers._default_manager.filter(
 
                speaker=speaker
 
            ).update(
 
                speaker=existing_speaker
 
            )
 
            messages.info(request, "You have been associated with all pending "
 
                "talk proposals")
 
            messages.info(request, ("You have been associated with all pending "
 
                                    "talk proposals"))
 
            return redirect("dashboard")
 
    else:
 
        if not request.user.is_authenticated():
 
            return redirect("account_login")
 
    return redirect("speaker_create")
 

	
symposion/sponsorship/admin.py
Show inline comments
 
from django.contrib import admin
 

	
 
from symposion.sponsorship.models import SponsorLevel, Sponsor, Benefit, BenefitLevel, SponsorBenefit
 
from symposion.sponsorship.models import SponsorLevel, Sponsor, Benefit, BenefitLevel, \
 
    SponsorBenefit
 

	
 

	
 
class BenefitLevelInline(admin.TabularInline):
 
    model = BenefitLevel
 
    extra = 0
 

	
symposion/sponsorship/management/commands/reset_sponsor_benefits.py
Show inline comments
 
from django.core.management.base import BaseCommand
 

	
 
from django.contrib.auth.models import Group
 

	
 
from symposion.sponsorship.models import Sponsor, SponsorBenefit
 
from symposion.sponsorship.models import Sponsor, SponsorBenefit, SponsorLevel
 

	
 

	
 
class Command(BaseCommand):
 

	
 
    def handle(self, *args, **options):
 
        for sponsor in Sponsor.objects.all():
symposion/sponsorship/models.py
Show inline comments
...
 
@@ -32,25 +32,27 @@ class SponsorLevel(models.Model):
 
    def sponsors(self):
 
        return self.sponsor_set.filter(active=True).order_by("added")
 

	
 

	
 
class Sponsor(models.Model):
 

	
 
    applicant = models.ForeignKey(User, related_name="sponsorships", verbose_name=_("applicant"), null=True)
 
    applicant = models.ForeignKey(User, related_name="sponsorships", verbose_name=_("applicant"),
 
                                  null=True)
 

	
 
    name = models.CharField(_("Sponsor Name"), max_length=100)
 
    external_url = models.URLField(_("external URL"))
 
    annotation = models.TextField(_("annotation"), blank=True)
 
    contact_name = models.CharField(_("Contact Name"), max_length=100)
 
    contact_email = models.EmailField(_(u"Contact Email"))
 
    level = models.ForeignKey(SponsorLevel, verbose_name=_("level"))
 
    added = models.DateTimeField(_("added"), default=datetime.datetime.now)
 
    active = models.BooleanField(_("active"), default=False)
 

	
 
    # Denormalization (this assumes only one logo)
 
    sponsor_logo = models.ForeignKey("SponsorBenefit", related_name="+", null=True, blank=True, editable=False)
 
    sponsor_logo = models.ForeignKey("SponsorBenefit", related_name="+", null=True, blank=True,
 
                                     editable=False)
 

	
 
    objects = SponsorManager()
 

	
 
    def __unicode__(self):
 
        return self.name
 

	
...
 
@@ -63,13 +65,14 @@ class Sponsor(models.Model):
 
            return reverse("sponsor_detail", kwargs={"pk": self.pk})
 
        return reverse("sponsor_list")
 

	
 
    @property
 
    def website_logo(self):
 
        if self.sponsor_logo is None:
 
            benefits = self.sponsor_benefits.filter(benefit__type="weblogo", upload__isnull=False)[:1]
 
            benefits = self.sponsor_benefits.filter(
 
                benefit__type="weblogo", upload__isnull=False)[:1]
 
            if benefits.count():
 
                if benefits[0].upload:
 
                    self.sponsor_logo = benefits[0]
 
                    self.save()
 
        return self.sponsor_logo.upload
 

	
...
 
@@ -117,13 +120,14 @@ class Sponsor(models.Model):
 
                sponsor_benefit.save()
 

	
 
                allowed_benefits.append(sponsor_benefit.pk)
 

	
 
        # Any remaining sponsor benefits that don't normally belong to
 
        # this level are set to inactive
 
        self.sponsor_benefits.exclude(pk__in=allowed_benefits).update(active=False, max_words=None, other_limits="")
 
        self.sponsor_benefits.exclude(pk__in=allowed_benefits)\
 
            .update(active=False, max_words=None, other_limits="")
 

	
 
    def send_coordinator_emails(self):
 
        pass  # @@@ should this just be done centrally?
 

	
 

	
 
def _store_initial_level(sender, instance, **kwargs):
...
 
@@ -147,13 +151,14 @@ BENEFIT_TYPE_CHOICES = [
 

	
 

	
 
class Benefit(models.Model):
 

	
 
    name = models.CharField(_("name"), max_length=100)
 
    description = models.TextField(_("description"), blank=True)
 
    type = models.CharField(_("type"), choices=BENEFIT_TYPE_CHOICES, max_length=10, default="simple")
 
    type = models.CharField(_("type"), choices=BENEFIT_TYPE_CHOICES, max_length=10,
 
                            default="simple")
 

	
 
    def __unicode__(self):
 
        return self.name
 

	
 

	
 
class BenefitLevel(models.Model):
symposion/sponsorship/templatetags/sponsorship_tags.py
Show inline comments
...
 
@@ -27,15 +27,18 @@ class SponsorsNode(template.Node):
 
        self.context_var = context_var
 

	
 
    def render(self, context):
 
        conference = current_conference()
 
        if self.level:
 
            level = self.level.resolve(context)
 
            queryset = Sponsor.objects.filter(level__conference = conference, level__name__iexact = level, active = True).order_by("added")
 
            queryset = Sponsor.objects.filter(
 
                level__conference=conference, level__name__iexact=level, active=True)\
 
                .order_by("added")
 
        else:
 
            queryset = Sponsor.objects.filter(level__conference = conference, active = True).order_by("level__order", "added")
 
            queryset = Sponsor.objects.filter(level__conference=conference, active=True)\
 
                .order_by("level__order", "added")
 
        context[self.context_var] = queryset
 
        return u""
 

	
 

	
 
class SponsorLevelNode(template.Node):
 

	
...
 
@@ -69,7 +72,6 @@ def sponsors(parser, token):
 
@register.tag
 
def sponsor_levels(parser, token):
 
    """
 
    {% sponsor_levels as levels %}
 
    """
 
    return SponsorLevelNode.handle_token(parser, token)
 
    
...
 
\ No newline at end of file
symposion/sponsorship/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import patterns, url
 
from django.views.generic.simple import direct_to_template
 

	
 

	
 
urlpatterns = patterns("symposion.sponsorship.views",
 
    url(r"^$", direct_to_template, {"template": "sponsorship/list.html"}, name="sponsor_list"),
symposion/sponsorship/views.py
Show inline comments
...
 
@@ -2,13 +2,14 @@ from django.http import Http404
 
from django.shortcuts import render_to_response, redirect, get_object_or_404
 
from django.template import RequestContext
 

	
 
from django.contrib import messages
 
from django.contrib.auth.decorators import login_required
 

	
 
from symposion.sponsorship.forms import SponsorApplicationForm, SponsorDetailsForm, SponsorBenefitsFormSet
 
from symposion.sponsorship.forms import SponsorApplicationForm, SponsorDetailsForm, \
 
    SponsorBenefitsFormSet
 
from symposion.sponsorship.models import Sponsor, SponsorBenefit
 

	
 

	
 
@login_required
 
def sponsor_apply(request):
 
    if request.method == "POST":
symposion/teams/admin.py
Show inline comments
...
 
@@ -2,14 +2,13 @@ from django.contrib import admin
 

	
 
import reversion
 

	
 
from symposion.teams.models import Team, Membership
 

	
 
admin.site.register(Team,
 
    prepopulated_fields={"slug": ("name",)},
 
)
 
                    prepopulated_fields={"slug": ("name",)})
 

	
 

	
 
class MembershipAdmin(reversion.VersionAdmin):
 
    list_display = ["team", "user", "state"]
 
    list_filter = ["team"]
 
    search_fields = ["user__username"]
symposion/teams/forms.py
Show inline comments
...
 
@@ -7,13 +7,14 @@ from django.contrib.auth.models import User
 

	
 
from symposion.teams.models import Membership
 

	
 

	
 
class TeamInvitationForm(forms.Form):
 

	
 
    email = forms.EmailField(help_text="email address must be that of an account on this conference site")
 
    email = forms.EmailField(help_text=("email address must be that of an account on this "
 
                                        "conference site"))
 

	
 
    def __init__(self, *args, **kwargs):
 
        self.team = kwargs.pop("team")
 
        super(TeamInvitationForm, self).__init__(*args, **kwargs)
 

	
 
    def clean(self):
...
 
@@ -25,13 +26,15 @@ class TeamInvitationForm(forms.Form):
 

	
 
        try:
 
            user = User.objects.get(email=email)
 
        except User.DoesNotExist:
 
            # eventually we can invite them but for now assume they are
 
            # already on the site
 
            raise forms.ValidationError(mark_safe("no account with email address <b>%s</b> found on this conference site" % escape(email)))
 
            raise forms.ValidationError(
 
                mark_safe("no account with email address <b>%s</b> found on this conference "
 
                          "site" % escape(email)))
 

	
 
        state = self.team.get_state_for_user(user)
 

	
 
        if state in ["member", "manager"]:
 
            raise forms.ValidationError("user already in team")
 

	
symposion/teams/models.py
Show inline comments
...
 
@@ -22,13 +22,14 @@ class Team(models.Model):
 
    access = models.CharField(max_length=20, choices=TEAM_ACCESS_CHOICES)
 

	
 
    # member permissions
 
    permissions = models.ManyToManyField(Permission, blank=True, related_name="member_teams")
 

	
 
    # manager permissions
 
    manager_permissions = models.ManyToManyField(Permission, blank=True, related_name="manager_teams")
 
    manager_permissions = models.ManyToManyField(Permission, blank=True,
 
                                                 related_name="manager_teams")
 

	
 
    created = models.DateTimeField(default=datetime.datetime.now, editable=False)
 

	
 
    @models.permalink
 
    def get_absolute_url(self):
 
        return ("team_detail", [self.slug])
symposion/teams/urls.py
Show inline comments
 
# flake8: noqa
 
from django.conf.urls.defaults import *
 

	
 

	
 
urlpatterns = patterns("symposion.teams.views",
 
    # team specific
 
    url(r"^(?P<slug>[\w\-]+)/$", "team_detail", name="team_detail"),
symposion/teams/views.py
Show inline comments
...
 
@@ -7,13 +7,13 @@ from django.contrib import messages
 
from symposion.utils.mail import send_email
 

	
 
from symposion.teams.forms import TeamInvitationForm
 
from symposion.teams.models import Team, Membership
 

	
 

	
 
## perm checks
 
# perm checks
 
#
 
# @@@ these can be moved
 

	
 
def can_join(team, user):
 
    state = team.get_state_for_user(user)
 
    if team.access == "open" and state is None:
...
 
@@ -47,13 +47,13 @@ def can_invite(team, user):
 
    if team.access == "invitation":
 
        if state == "manager" or user.is_staff:
 
            return True
 
    return False
 

	
 

	
 
## views
 
# views
 

	
 

	
 
@login_required
 
def team_detail(request, slug):
 
    team = get_object_or_404(Team, slug=slug)
 
    state = team.get_state_for_user(request.user)
0 comments (0 inline, 0 general)