diff --git a/symposion/boxes/models.py b/symposion/boxes/models.py index c83cadcb..4eb2a019 100644 --- a/symposion/boxes/models.py +++ b/symposion/boxes/models.py @@ -1,7 +1,4 @@ -import datetime - from django.db import models - from django.contrib.auth.models import User import reversion @@ -10,16 +7,16 @@ from markitup.fields import MarkupField class Box(models.Model): - + label = models.CharField(max_length=100, db_index=True) content = MarkupField(blank=True) - + created_by = models.ForeignKey(User, related_name="boxes") last_updated_by = models.ForeignKey(User, related_name="updated_boxes") - + def __unicode__(self): return self.label - + class Meta: verbose_name_plural = "boxes" diff --git a/symposion/boxes/templatetags/boxes_tags.py b/symposion/boxes/templatetags/boxes_tags.py index e300fd3b..53765e56 100644 --- a/symposion/boxes/templatetags/boxes_tags.py +++ b/symposion/boxes/templatetags/boxes_tags.py @@ -1,10 +1,5 @@ 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 @@ -16,22 +11,22 @@ register = template.Library() @register.inclusion_tag("boxes/box.html", takes_context=True) def box(context, label, show_edit=True, *args, **kwargs): - + request = context["request"] can_edit = load_can_edit()(request, *args, **kwargs) - + try: box = Box.objects.get(label=label) except Box.DoesNotExist: box = None - + if can_edit and show_edit: form = BoxForm(instance=box, prefix=label) form_action = reverse("box_edit", args=[label]) else: form = None form_action = None - + return { "request": request, "label": label, diff --git a/symposion/conf.py b/symposion/conf.py index e2fb8072..dd2a6d50 100644 --- a/symposion/conf.py +++ b/symposion/conf.py @@ -1,8 +1,6 @@ -from django.conf import settings - from appconf import AppConf class SymposionAppConf(AppConf): - + VOTE_THRESHOLD = 3 diff --git a/symposion/conference/urls.py b/symposion/conference/urls.py index 6bd44c16..a25aa583 100644 --- a/symposion/conference/urls.py +++ b/symposion/conference/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import patterns, url urlpatterns = patterns("symposion.conference.views", diff --git a/symposion/markdown_parser.py b/symposion/markdown_parser.py index 07216c2a..178708f6 100644 --- a/symposion/markdown_parser.py +++ b/symposion/markdown_parser.py @@ -1,14 +1,13 @@ -import html5lib from html5lib import html5parser, sanitizer import markdown def parse(text): - + # First run through the Markdown parser text = markdown.markdown(text, extensions=["extra"], safe_mode=False) - + # Sanitize using html5lib bits = [] parser = html5parser.HTMLParser(tokenizer=sanitizer.HTMLSanitizer) diff --git a/symposion/proposals/managers.py b/symposion/proposals/managers.py deleted file mode 100644 index b908c7b6..00000000 --- a/symposion/proposals/managers.py +++ /dev/null @@ -1,27 +0,0 @@ -from django.db import models -from django.db.models.query import QuerySet - - -class CachingM2MQuerySet(QuerySet): - - def __init__(self, *args, **kwargs): - super(CachingM2MQuerySet, self).__init__(*args, **kwargs) - self.cached_m2m_field = kwargs["m2m_field"] - - def iterator(self): - parent_iter = super(CachingM2MQuerySet, self).iterator() - m2m_model = getattr(self.model, self.cached_m2m_field).through - - for obj in parent_iter: - if obj.id in cached_objects: - setattr(obj, "_cached_m2m_%s" % self.cached_m2m_field) - yield obj - - -class ProposalManager(models.Manager): - def cache_m2m(self, m2m_field): - return CachingM2MQuerySet(self.model, using=self._db, m2m_field=m2m_field) - AdditionalSpeaker = queryset.model.additional_speakers.through - additional_speakers = collections.defaultdict(set) - for additional_speaker in AdditionalSpeaker._default_manager.filter(proposal__in=queryset).select_related("speaker__user"): - additional_speakers[additional_speaker.proposal_id].add(additional_speaker.speaker) \ No newline at end of file diff --git a/symposion/proposals/urls.py b/symposion/proposals/urls.py index 85e2bb1c..443540bb 100644 --- a/symposion/proposals/urls.py +++ b/symposion/proposals/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import patterns, url urlpatterns = patterns("symposion.proposals.views", @@ -11,7 +11,7 @@ urlpatterns = patterns("symposion.proposals.views", url(r"^(\d+)/leave/$", "proposal_leave", name="proposal_leave"), url(r"^(\d+)/join/$", "proposal_pending_join", name="proposal_pending_join"), url(r"^(\d+)/decline/$", "proposal_pending_decline", name="proposal_pending_decline"), - + url(r"^(\d+)/document/create/$", "document_create", name="proposal_document_create"), url(r"^document/(\d+)/delete/$", "document_delete", name="proposal_document_delete"), url(r"^document/(\d+)/([^/]+)$", "document_download", name="proposal_document_download"), diff --git a/symposion/reviews/context_processors.py b/symposion/reviews/context_processors.py index 6e70715b..02850f15 100644 --- a/symposion/reviews/context_processors.py +++ b/symposion/reviews/context_processors.py @@ -1,5 +1,3 @@ -from django.contrib.contenttypes.models import ContentType - from symposion.proposals.models import ProposalSection diff --git a/symposion/reviews/management/commands/assign_reviewers.py b/symposion/reviews/management/commands/assign_reviewers.py index 334eab30..20594f4c 100644 --- a/symposion/reviews/management/commands/assign_reviewers.py +++ b/symposion/reviews/management/commands/assign_reviewers.py @@ -1,8 +1,3 @@ -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 diff --git a/symposion/reviews/management/commands/calculate_results.py b/symposion/reviews/management/commands/calculate_results.py index 45185a22..6a06ce8a 100644 --- a/symposion/reviews/management/commands/calculate_results.py +++ b/symposion/reviews/management/commands/calculate_results.py @@ -1,11 +1,9 @@ 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): ProposalResult.full_calculate() diff --git a/symposion/reviews/templatetags/review_tags.py b/symposion/reviews/templatetags/review_tags.py index cfb6437e..c646ca96 100644 --- a/symposion/reviews/templatetags/review_tags.py +++ b/symposion/reviews/templatetags/review_tags.py @@ -1,6 +1,6 @@ from django import template -from symposion.reviews.models import Review, ReviewAssignment +from symposion.reviews.models import ReviewAssignment register = template.Library() diff --git a/symposion/reviews/views.py b/symposion/reviews/views.py index 880e9e8b..8278778a 100644 --- a/symposion/reviews/views.py +++ b/symposion/reviews/views.py @@ -1,5 +1,3 @@ -import re - from django.core.mail import send_mass_mail from django.db.models import Q from django.http import HttpResponseBadRequest, HttpResponseNotAllowed @@ -27,18 +25,18 @@ def access_not_permitted(request): def proposals_generator(request, queryset, user_pk=None, check_speaker=True): - + for obj in queryset: # @@@ this sucks; we can do better if check_speaker: if request.user in [s.user for s in obj.speakers()]: continue - + try: obj.result except ProposalResult.DoesNotExist: ProposalResult.objects.get_or_create(proposal=obj) - + obj.comment_count = obj.result.comment_count obj.total_votes = obj.result.vote_count obj.plus_one = obj.result.plus_one @@ -46,19 +44,19 @@ def proposals_generator(request, queryset, user_pk=None, check_speaker=True): obj.minus_zero = obj.result.minus_zero obj.minus_one = obj.result.minus_one lookup_params = dict(proposal=obj) - + if user_pk: lookup_params["user__pk"] = user_pk else: lookup_params["user"] = request.user - + try: obj.user_vote = LatestVote.objects.get(**lookup_params).vote obj.user_vote_css = LatestVote.objects.get(**lookup_params).css_class() except LatestVote.DoesNotExist: obj.user_vote = None obj.user_vote_css = "no-vote" - + yield obj @@ -66,17 +64,17 @@ def proposals_generator(request, queryset, user_pk=None, check_speaker=True): # 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") 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": @@ -88,35 +86,35 @@ def review_section(request, section_slug, assigned=False, reviewed="all"): else: queryset = queryset.exclude(reviews__user=request.user).exclude(speaker=request.user) reviewed = "user_not_reviewed" - + proposals = proposals_generator(request, queryset) - + ctx = { "proposals": proposals, "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): if not request.user.pk == user_pk: return access_not_permitted(request) - + queryset = ProposalBase.objects.select_related("speaker__user", "result") reviewed = LatestVote.objects.filter(user__pk=user_pk).values_list("proposal", flat=True) queryset = queryset.filter(pk__in=reviewed) proposals = queryset.order_by("submitted") - + admin = request.user.has_perm("reviews.can_manage_%s" % section_slug) - + proposals = proposals_generator(request, proposals, user_pk=user_pk, check_speaker=not admin) - + ctx = { "proposals": proposals, } @@ -125,20 +123,20 @@ def review_list(request, section_slug, user_pk): @login_required def review_admin(request, section_slug): - + if not request.user.has_perm("reviews.can_manage_%s" % section_slug): return access_not_permitted(request) - + def reviewers(): already_seen = set() - + for team in Team.objects.filter(permissions__codename="can_review_%s" % section_slug): for membership in team.memberships.filter(Q(state="member") | Q(state="manager")): user = membership.user if user.pk in already_seen: continue already_seen.add(user.pk) - + user.comment_count = Review.objects.filter(user=user).count() user.total_votes = LatestVote.objects.filter(user=user).count() user.plus_one = LatestVote.objects.filter( @@ -157,9 +155,9 @@ def review_admin(request, section_slug): user = user, vote = LatestVote.VOTES.MINUS_ONE ).count() - + yield user - + ctx = { "section_slug": section_slug, "reviewers": reviewers(), @@ -169,50 +167,50 @@ def review_admin(request, section_slug): @login_required def review_detail(request, pk): - + proposals = ProposalBase.objects.select_related("result").select_subclasses() proposal = get_object_or_404(proposals, pk=pk) - + if not request.user.has_perm("reviews.can_review_%s" % proposal.kind.section.slug): return access_not_permitted(request) - + speakers = [s.user for s in proposal.speakers()] - + if not request.user.is_superuser and request.user in speakers: return access_not_permitted(request) - + admin = request.user.is_staff - + try: latest_vote = LatestVote.objects.get(proposal=proposal, user=request.user) except LatestVote.DoesNotExist: latest_vote = None - + if request.method == "POST": if request.user in speakers: return access_not_permitted(request) - + if "vote_submit" in request.POST: review_form = ReviewForm(request.POST) if review_form.is_valid(): - + review = review_form.save(commit=False) review.user = request.user review.proposal = proposal review.save() - + return redirect(request.path) else: message_form = SpeakerCommentForm() elif "message_submit" in request.POST: message_form = SpeakerCommentForm(request.POST) if message_form.is_valid(): - + message = message_form.save(commit=False) message.user = request.user message.proposal = proposal message.save() - + for speaker in speakers: if speaker and speaker.email: ctx = { @@ -224,7 +222,7 @@ def review_detail(request, pk): [speaker.email], "proposal_new_message", context = ctx ) - + return redirect(request.path) else: initial = {} @@ -237,7 +235,7 @@ def review_detail(request, pk): elif "result_submit" in request.POST: if admin: result = request.POST["result_submit"] - + if result == "accept": proposal.result.status = "accepted" proposal.result.save() @@ -250,7 +248,7 @@ def review_detail(request, pk): elif result == "standby": proposal.result.status = "standby" proposal.result.save() - + return redirect(request.path) else: initial = {} @@ -261,17 +259,17 @@ def review_detail(request, pk): else: review_form = ReviewForm(initial=initial) message_form = SpeakerCommentForm() - + proposal.comment_count = proposal.result.comment_count proposal.total_votes = proposal.result.vote_count proposal.plus_one = proposal.result.plus_one proposal.plus_zero = proposal.result.plus_zero proposal.minus_zero = proposal.result.minus_zero proposal.minus_one = proposal.result.minus_one - + reviews = Review.objects.filter(proposal=proposal).order_by("-submitted_at") messages = proposal.messages.order_by("submitted_at") - + return render(request, "reviews/review_detail.html", { "proposal": proposal, "latest_vote": latest_vote, @@ -287,33 +285,33 @@ def review_detail(request, pk): def review_delete(request, pk): review = get_object_or_404(Review, pk=pk) section_slug = review.section.slug - + if not request.user.has_perm("reviews.can_manage_%s" % section_slug): return access_not_permitted(request) - + review = get_object_or_404(Review, pk=pk) review.delete() - + return redirect("review_detail", pk=review.proposal.pk) @login_required def review_status(request, section_slug=None, key=None): - + if not request.user.has_perm("reviews.can_review_%s" % section_slug): return access_not_permitted(request) - + VOTE_THRESHOLD = settings.SYMPOSION_VOTE_THRESHOLD - + ctx = { "section_slug": section_slug, "vote_threshold": VOTE_THRESHOLD, } - + 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"), @@ -326,14 +324,14 @@ def review_status(request, section_slug=None, key=None): # proposals with fewer than VOTE_THRESHOLD reviews "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)) - + if key: ctx.update({ "key": key, @@ -341,7 +339,7 @@ def review_status(request, section_slug=None, key=None): }) else: ctx["proposals"] = proposals - + return render(request, "reviews/review_stats.html", ctx) @@ -387,7 +385,7 @@ def review_bulk_accept(request, section_slug): return redirect("review_section", section_slug=section_slug) else: form = BulkPresentationForm() - + return render(request, "reviews/review_bulk_accept.html", { "form": form, }) @@ -397,10 +395,10 @@ def review_bulk_accept(request, section_slug): 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() notification_templates = NotificationTemplate.objects.all() - + ctx = { "section_slug": section_slug, "status": status, @@ -414,10 +412,10 @@ def result_notification(request, section_slug, status): def result_notification_prepare(request, section_slug, status): if request.method != "POST": return HttpResponseNotAllowed(["POST"]) - + if not request.user.has_perm("reviews.can_manage_%s" % section_slug): return access_not_permitted(request) - + proposal_pks = [] try: for pk in request.POST.getlist("_selected_action"): @@ -431,13 +429,13 @@ def result_notification_prepare(request, section_slug, status): proposals = proposals.filter(pk__in=proposal_pks) proposals = proposals.select_related("speaker__user", "result") proposals = proposals.select_subclasses() - + notification_template_pk = request.POST.get("notification_template", "") if notification_template_pk: notification_template = NotificationTemplate.objects.get(pk=notification_template_pk) else: notification_template = None - + ctx = { "section_slug": section_slug, "status": status, @@ -452,18 +450,18 @@ def result_notification_prepare(request, section_slug, status): def result_notification_send(request, section_slug, status): if request.method != "POST": return HttpResponseNotAllowed(["POST"]) - + if not request.user.has_perm("reviews.can_manage_%s" % section_slug): return access_not_permitted(request) - + if not all([k in request.POST for k in ["proposal_pks", "from_address", "subject", "body"]]): return HttpResponseBadRequest() - + try: proposal_pks = [int(pk) for pk in request.POST["proposal_pks"].split(",")] except ValueError: return HttpResponseBadRequest() - + proposals = ProposalBase.objects.filter( kind__section__slug=section_slug, result__status=status, @@ -471,15 +469,15 @@ def result_notification_send(request, section_slug, status): proposals = proposals.filter(pk__in=proposal_pks) proposals = proposals.select_related("speaker__user", "result") proposals = proposals.select_subclasses() - + notification_template_pk = request.POST.get("notification_template", "") if notification_template_pk: notification_template = NotificationTemplate.objects.get(pk=notification_template_pk) else: notification_template = None - + emails = [] - + for proposal in proposals: rn = ResultNotification() rn.proposal = proposal @@ -494,7 +492,7 @@ def result_notification_send(request, section_slug, status): ) rn.save() emails.append(rn.email_args) - + send_mass_mail(emails) - + return redirect("result_notification", section_slug=section_slug, status=status) diff --git a/symposion/schedule/models.py b/symposion/schedule/models.py index dc070917..c4614437 100644 --- a/symposion/schedule/models.py +++ b/symposion/schedule/models.py @@ -2,44 +2,43 @@ 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): - + section = models.OneToOneField(Section) published = models.BooleanField(default=True) hidden = models.BooleanField("Hide schedule from overall conference view", default=False) - + def __unicode__(self): return "%s Schedule" % self.section - + class Meta: ordering = ["section"] class Day(models.Model): - + schedule = models.ForeignKey(Schedule) date = models.DateField() - + def __unicode__(self): return "%s" % self.date - + class Meta: unique_together = [("schedule", "date")] ordering = ["date"] class Room(models.Model): - + schedule = models.ForeignKey(Schedule) name = models.CharField(max_length=65) order = models.PositiveIntegerField() - + def __unicode__(self): return self.name @@ -49,22 +48,22 @@ class SlotKind(models.Model): A slot kind represents what kind a slot is. For example, a slot can be a break, lunch, or X-minute talk. """ - + schedule = models.ForeignKey(Schedule) label = models.CharField(max_length=50) - + def __unicode__(self): return self.label class Slot(models.Model): - + day = models.ForeignKey(Day) kind = models.ForeignKey(SlotKind) start = models.TimeField() end = models.TimeField() content_override = MarkupField(blank=True) - + def assign(self, content): """ Assign the given content to this slot and if a previous slot content @@ -73,7 +72,7 @@ class Slot(models.Model): self.unassign() content.slot = self content.save() - + def unassign(self): """ Unassign the associated content with this slot. @@ -81,7 +80,7 @@ class Slot(models.Model): if self.content and self.content.slot_id: self.content.slot = None self.content.save() - + @property def content(self): """ @@ -92,14 +91,14 @@ class Slot(models.Model): return self.content_ptr except ObjectDoesNotExist: return None - + @property def rooms(self): return Room.objects.filter(pk__in=self.slotroom_set.values("room")) - + def __unicode__(self): return "%s %s (%s - %s)" % (self.day, self.kind, self.start, self.end) - + class Meta: ordering = ["day", "start", "end"] @@ -108,20 +107,20 @@ class SlotRoom(models.Model): """ Links a slot with a room. """ - + slot = models.ForeignKey(Slot) room = models.ForeignKey(Room) - + def __unicode__(self): return "%s %s" % (self.room, self.slot) - + class Meta: unique_together = [("slot", "room")] ordering = ["slot", "room__order"] class Presentation(models.Model): - + slot = models.OneToOneField(Slot, null=True, blank=True, related_name="content_ptr") title = models.CharField(max_length=100) description = MarkupField() @@ -131,25 +130,25 @@ class Presentation(models.Model): cancelled = models.BooleanField(default=False) proposal_base = models.OneToOneField(ProposalBase, related_name="presentation") section = models.ForeignKey(Section, related_name="presentations") - + @property def number(self): return self.proposal.number - + @property def proposal(self): if self.proposal_base_id is None: return None return ProposalBase.objects.get_subclass(pk=self.proposal_base_id) - + def speakers(self): yield self.speaker for speaker in self.additional_speakers.all(): if speaker.user: yield speaker - + def __unicode__(self): return "#%s %s (%s)" % (self.number, self.title, self.speaker) - + class Meta: ordering = ["slot"] diff --git a/symposion/schedule/timetable.py b/symposion/schedule/timetable.py index 2aba1de3..2564b0cd 100644 --- a/symposion/schedule/timetable.py +++ b/symposion/schedule/timetable.py @@ -1,5 +1,4 @@ import itertools -import operator from django.db.models import Count, Min @@ -7,22 +6,22 @@ from symposion.schedule.models import Room, Slot, SlotRoom class TimeTable(object): - + def __init__(self, day): self.day = day - + def slots_qs(self): qs = Slot.objects.all() 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.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")) @@ -38,7 +37,7 @@ class TimeTable(object): row["slots"].append(slot) if row["slots"] or next_time is None: yield row - + @staticmethod def rowspan(times, start, end): return times.index(end) - times.index(start) diff --git a/symposion/schedule/views.py b/symposion/schedule/views.py index 35f9e432..98771b59 100644 --- a/symposion/schedule/views.py +++ b/symposion/schedule/views.py @@ -1,4 +1,3 @@ -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 @@ -12,7 +11,7 @@ from symposion.schedule.timetable import TimeTable def fetch_schedule(slug): qs = Schedule.objects.all() - + if slug is None: if qs.count() > 1: raise Http404() @@ -21,14 +20,14 @@ def fetch_schedule(slug): raise Http404() else: schedule = get_object_or_404(qs, section__slug=slug) - + return schedule def schedule_conference(request): - + schedules = Schedule.objects.filter(published=True, hidden=False) - + sections = [] for schedule in schedules: days_qs = Day.objects.filter(schedule=schedule) @@ -37,7 +36,7 @@ def schedule_conference(request): "schedule": schedule, "days": days, }) - + ctx = { "sections": sections, } @@ -45,14 +44,14 @@ def schedule_conference(request): def schedule_detail(request, slug=None): - + schedule = fetch_schedule(slug) if not schedule.published and not request.user.is_staff: raise Http404() - + days_qs = Day.objects.filter(schedule=schedule) days = [TimeTable(day) for day in days_qs] - + ctx = { "schedule": schedule, "days": days, @@ -62,10 +61,10 @@ def schedule_detail(request, slug=None): def schedule_list(request, slug=None): schedule = fetch_schedule(slug) - + presentations = Presentation.objects.filter(section=schedule.section) presentations = presentations.exclude(cancelled=True) - + ctx = { "schedule": schedule, "presentations": presentations, @@ -75,32 +74,32 @@ def schedule_list(request, slug=None): def schedule_list_csv(request, slug=None): schedule = fetch_schedule(slug) - + presentations = Presentation.objects.filter(section=schedule.section) presentations = presentations.exclude(cancelled=True).order_by("id") - + response = HttpResponse(mimetype="text/csv") if slug: file_slug = slug else: file_slug = "presentations" response["Content-Disposition"] = 'attachment; filename="%s.csv"' % file_slug - + response.write(loader.get_template("schedule/schedule_list.csv").render(Context({ "presentations": presentations, - + }))) return response @login_required def schedule_edit(request, slug=None): - + if not request.user.is_staff: raise Http404() - + schedule = fetch_schedule(slug) - + days_qs = Day.objects.filter(schedule=schedule) days = [TimeTable(day) for day in days_qs] ctx = { @@ -112,12 +111,12 @@ def schedule_edit(request, slug=None): @login_required def schedule_slot_edit(request, slug, slot_pk): - + if not request.user.is_staff: raise Http404() - + slot = get_object_or_404(Slot, day__schedule__section__slug=slug, pk=slot_pk) - + if request.method == "POST": form = SlotEditForm(request.POST, slot=slot) if form.is_valid(): @@ -145,13 +144,13 @@ def schedule_slot_edit(request, slug, slot_pk): def schedule_presentation_detail(request, pk): - + presentation = get_object_or_404(Presentation, pk=pk) if presentation.slot: schedule = presentation.slot.day.schedule else: schedule = None - + ctx = { "presentation": presentation, "schedule": schedule, diff --git a/symposion/speakers/management/commands/export_speaker_data.py b/symposion/speakers/management/commands/export_speaker_data.py index 5f9f565d..00e82588 100644 --- a/symposion/speakers/management/commands/export_speaker_data.py +++ b/symposion/speakers/management/commands/export_speaker_data.py @@ -1,17 +1,17 @@ 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): - + def handle(self, *args, **options): csv_file = csv.writer(open(os.path.join(os.getcwd(), "speakers.csv"), "wb")) csv_file.writerow(["Name", "Bio"]) - + for speaker in Speaker.objects.all(): csv_file.writerow([ speaker.name.encode("utf-8"), diff --git a/symposion/speakers/urls.py b/symposion/speakers/urls.py index fa7055cf..9a00ea3c 100644 --- a/symposion/speakers/urls.py +++ b/symposion/speakers/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import patterns, url urlpatterns = patterns("symposion.speakers.views", diff --git a/symposion/sponsorship/management/commands/reset_sponsor_benefits.py b/symposion/sponsorship/management/commands/reset_sponsor_benefits.py index 2c515a2e..3c17efab 100644 --- a/symposion/sponsorship/management/commands/reset_sponsor_benefits.py +++ b/symposion/sponsorship/management/commands/reset_sponsor_benefits.py @@ -1,15 +1,13 @@ 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(): - level = None + level = None try: level = sponsor.level except SponsorLevel.DoesNotExist: @@ -19,17 +17,17 @@ class Command(BaseCommand): # Create all needed benefits if they don't exist already sponsor_benefit, created = SponsorBenefit.objects.get_or_create( sponsor=sponsor, benefit=benefit_level.benefit) - + if created: print "created", sponsor_benefit, "for", sponsor - + # and set to default limits for this level. sponsor_benefit.max_words = benefit_level.max_words sponsor_benefit.other_limits = benefit_level.other_limits - + # and set to active sponsor_benefit.active = True - + # @@@ We don't call sponsor_benefit.clean here. This means # that if the sponsorship level for a sponsor is adjusted # downwards, an existing too-long text entry can remain, diff --git a/symposion/teams/urls.py b/symposion/teams/urls.py index 01145f41..ed2f7645 100644 --- a/symposion/teams/urls.py +++ b/symposion/teams/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import patterns, url urlpatterns = patterns("symposion.teams.views", @@ -7,7 +7,7 @@ urlpatterns = patterns("symposion.teams.views", url(r"^(?P[\w\-]+)/join/$", "team_join", name="team_join"), url(r"^(?P[\w\-]+)/leave/$", "team_leave", name="team_leave"), url(r"^(?P[\w\-]+)/apply/$", "team_apply", name="team_apply"), - + # membership specific url(r"^promote/(?P\d+)/$", "team_promote", name="team_promote"), url(r"^demote/(?P\d+)/$", "team_demote", name="team_demote"),