<commit_before># thesquirrel.org
#
# Copyright (C) 2015 Flying Squirrel Community Space
#
# thesquirrel.org is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# thesquirrel.org is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with thesquirrel.org.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import absolute_import
from datetime import timedelta

from django.contrib.auth.models import User
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import Q
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from dateutil import rrule

from editor import EditorTextField
from . import repeat
from .utils import format_time

class EventTimeMixin(object):
    def get_start_time_display(self):
        return format_time(self.start_time)

    def get_end_time_display(self):
        return format_time(self.end_time)

    def get_time_display(self):
        return '{} - {}'.format(self.get_start_time_display(),
                                self.get_end_time_display())

class Event(models.Model, EventTimeMixin):
    title = models.CharField(max_length=255)
    description = EditorTextField()
    location = models.CharField(max_length=255)
    bottomliner = models.CharField(max_length=255)
    created = models.DateTimeField(default=timezone.now)
    date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()
    space_request = models.ForeignKey('SpaceUseRequest', null=True)

    def __unicode__(self):
        return u'Event: {}'.format(self.title)

    def update_calendar_items(self):
        self.calendar_items.all().delete()
        excludes = set(e.date for e in self.excludes.all())
        to_create = [
            CalendarItem(event=self, date=self.date,
                         start_time=self.start_time,
                         end_time=self.end_time)
        ]
        # Often the event and repeat share a start date, in that case don't
        # create a duplicate date.
        excludes.add(self.date)
        to_create.extend([
            CalendarItem(event=self, date=dt.date(),
                         start_time=repeat.start_time,
                         end_time=repeat.end_time)
            for repeat in self.repeat_set.all()
            for dt in repeat.calc_repeat_rrule()
            if dt.date() not in excludes
        ])
        CalendarItem.objects.bulk_create(to_create)

    def get_date_display(self):
        return '{d:%a} {d.month}/{d.day}/{d.year}'.format(d=self.date)

    def get_when_text(self):
        repeats = self.repeat_set.all()
        if repeats:
            return [
                _('{repeat_type} at {days}, {start_time} - {end_time}').format(
                    repeat_type=repeat.get_type_display(),
                    days=repeat.get_weekdays_display(),
                    start_time=repeat.get_start_time_display(),
                    end_time=repeat.get_end_time_display(),
                )
                for repeat in repeats
            ]
        else:
            return [
                _('{date}, {start_time}-{end_time}').format(
                    date=self.get_date_display(),
                    start_time=self.get_start_time_display(),
                    end_time=self.get_end_time_display(),
                ),
            ]

# list of (field_name, rrule_class, display_string) tuples
weekday_field_info = [
    ('mo', rrule.MO, _('Monday')),
    ('tu', rrule.TU, _('Tuesday')),
    ('we', rrule.WE, _('Wednesday')),
    ('th', rrule.TH, _('Thursday')),
    ('fr', rrule.FR, _('Friday')),
    ('sa', rrule.SA, _('Saturday')),
    ('su', rrule.SU, _('Sunday')),
]
weekday_fields = [info[0] for info in weekday_field_info]

class EventRepeat(models.Model, EventTimeMixin):
    event = models.ForeignKey(Event, related_name='repeat_set')
    type = models.CharField(max_length=3, choices=repeat.CHOICES)
    start_date = models.DateField()
    end_date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()
    su = models.BooleanField(default=False)
    mo = models.BooleanField(default=False)
    tu = models.BooleanField(default=False)
    we = models.BooleanField(default=False)
    th = models.BooleanField(default=False)
    fr = models.BooleanField(default=False)
    sa = models.BooleanField(default=False)

    def _rrule_weekdays(self):
        return [
            weekday
            for field_name, weekday, _ in weekday_field_info
            if getattr(self, field_name)
        ]

    def get_weekdays_display(self):
        days = [
            day_name
            for field_name, weekday, day_name in weekday_field_info
            if getattr(self, field_name)
        ]
        return ', '.join(unicode(d) for d in days)

    def calc_repeat_rrule(self):
        return repeat.get_rrule(self.type, self.start_date,
                                self.end_date, self._rrule_weekdays())

class EventRepeatExclude(models.Model):
    event = models.ForeignKey(Event, related_name='excludes')
    date = models.DateField(unique=True)

class CalendarItem(models.Model, EventTimeMixin):
    """Represents an entry in the calendar."""

    event = models.ForeignKey(Event, related_name='calendar_items')
    date = models.DateField(db_index=True)
    start_time = models.TimeField()
    end_time = models.TimeField()

    @classmethod
    def upcoming(cls):
        today = timezone.now().date()
        return (cls.objects.filter(date__gte=today)
                .select_related('event')
                .order_by('date', 'event__start_time'))

    @property
    def space_request(self):
        return self.event.space_request

class SpaceUseRequestQueryset(models.QuerySet):
    def iterator(self):
        # This code does a couple things:
        #   - Generate subclass instances instead of the base class
        #   - Only uses 1 query to fetch all the data we need
        real_query = self.select_related('singlespaceuserequest',
                                         'ongoingspaceuserequest')
        for base_obj in super(SpaceUseRequestQueryset, real_query).iterator():
            if base_obj._singlespaceuserequest_cache:
                yield base_obj.singlespaceuserequest
            elif base_obj._ongoingspaceuserequest_cache:
                yield base_obj.ongoingspaceuserequest
            else:
                raise TypeError("No subclass found: {}".format(base_obj))

<commit_msg>Don't show pending events in the upcoming section<commit_after># thesquirrel.org
#
# Copyright (C) 2015 Flying Squirrel Community Space
#
# thesquirrel.org is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# thesquirrel.org is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with thesquirrel.org.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import absolute_import
from datetime import timedelta

from django.contrib.auth.models import User
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import Q
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from dateutil import rrule

from editor import EditorTextField
from . import repeat
from .utils import format_time

class EventTimeMixin(object):
    def get_start_time_display(self):
        return format_time(self.start_time)

    def get_end_time_display(self):
        return format_time(self.end_time)

    def get_time_display(self):
        return '{} - {}'.format(self.get_start_time_display(),
                                self.get_end_time_display())

class Event(models.Model, EventTimeMixin):
    title = models.CharField(max_length=255)
    description = EditorTextField()
    location = models.CharField(max_length=255)
    bottomliner = models.CharField(max_length=255)
    created = models.DateTimeField(default=timezone.now)
    date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()
    space_request = models.ForeignKey('SpaceUseRequest', null=True)

    def __unicode__(self):
        return u'Event: {}'.format(self.title)

    def update_calendar_items(self):
        self.calendar_items.all().delete()
        excludes = set(e.date for e in self.excludes.all())
        to_create = [
            CalendarItem(event=self, date=self.date,
                         start_time=self.start_time,
                         end_time=self.end_time)
        ]
        # Often the event and repeat share a start date, in that case don't
        # create a duplicate date.
        excludes.add(self.date)
        to_create.extend([
            CalendarItem(event=self, date=dt.date(),
                         start_time=repeat.start_time,
                         end_time=repeat.end_time)
            for repeat in self.repeat_set.all()
            for dt in repeat.calc_repeat_rrule()
            if dt.date() not in excludes
        ])
        CalendarItem.objects.bulk_create(to_create)

    def get_date_display(self):
        return '{d:%a} {d.month}/{d.day}/{d.year}'.format(d=self.date)

    def get_when_text(self):
        repeats = self.repeat_set.all()
        if repeats:
            return [
                _('{repeat_type} at {days}, {start_time} - {end_time}').format(
                    repeat_type=repeat.get_type_display(),
                    days=repeat.get_weekdays_display(),
                    start_time=repeat.get_start_time_display(),
                    end_time=repeat.get_end_time_display(),
                )
                for repeat in repeats
            ]
        else:
            return [
                _('{date}, {start_time}-{end_time}').format(
                    date=self.get_date_display(),
                    start_time=self.get_start_time_display(),
                    end_time=self.get_end_time_display(),
                ),
            ]

# list of (field_name, rrule_class, display_string) tuples
weekday_field_info = [
    ('mo', rrule.MO, _('Monday')),
    ('tu', rrule.TU, _('Tuesday')),
    ('we', rrule.WE, _('Wednesday')),
    ('th', rrule.TH, _('Thursday')),
    ('fr', rrule.FR, _('Friday')),
    ('sa', rrule.SA, _('Saturday')),
    ('su', rrule.SU, _('Sunday')),
]
weekday_fields = [info[0] for info in weekday_field_info]

class EventRepeat(models.Model, EventTimeMixin):
    event = models.ForeignKey(Event, related_name='repeat_set')
    type = models.CharField(max_length=3, choices=repeat.CHOICES)
    start_date = models.DateField()
    end_date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()
    su = models.BooleanField(default=False)
    mo = models.BooleanField(default=False)
    tu = models.BooleanField(default=False)
    we = models.BooleanField(default=False)
    th = models.BooleanField(default=False)
    fr = models.BooleanField(default=False)
    sa = models.BooleanField(default=False)

    def _rrule_weekdays(self):
        return [
            weekday
            for field_name, weekday, _ in weekday_field_info
            if getattr(self, field_name)
        ]

    def get_weekdays_display(self):
        days = [
            day_name
            for field_name, weekday, day_name in weekday_field_info
            if getattr(self, field_name)
        ]
        return ', '.join(unicode(d) for d in days)

    def calc_repeat_rrule(self):
        return repeat.get_rrule(self.type, self.start_date,
                                self.end_date, self._rrule_weekdays())

class EventRepeatExclude(models.Model):
    event = models.ForeignKey(Event, related_name='excludes')
    date = models.DateField(unique=True)

class CalendarItem(models.Model, EventTimeMixin):
    """Represents an entry in the calendar."""

    event = models.ForeignKey(Event, related_name='calendar_items')
    date = models.DateField(db_index=True)
    start_time = models.TimeField()
    end_time = models.TimeField()

    @classmethod
    def upcoming(cls):
        today = timezone.now().date()
        return (
            cls.objects
            .filter(date__gte=today)
            .filter(Q(event__space_request__isnull=True) |
                    Q(event__space_request__state=SpaceUseRequest.APPROVED))
            .select_related('event')
            .order_by('date', 'event__start_time'))

    @property
    def space_request(self):
        return self.event.space_request

class SpaceUseRequestQueryset(models.QuerySet):
    def iterator(self):
        # This code does a couple things:
        #   - Generate subclass instances instead of the base class
        #   - Only uses 1 query to fetch all the data we need
        real_query = self.select_related('singlespaceuserequest',
                                         'ongoingspaceuserequest')
        for base_obj in super(SpaceUseRequestQueryset, real_query).iterator():
            if base_obj._singlespaceuserequest_cache:
                yield base_obj.singlespaceuserequest
            elif base_obj._ongoingspaceuserequest_cache:
                yield base_obj.ongoingspaceuserequest
            else:
                raise TypeError("No subclass found: {}".format(base_obj))

{'fraction_non_alphanumeric': 0.09641209283107224, 'fraction_numerical': 0.002341436540183183, 'mean_word_length': 2.685786802030457, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '867100', 'n_tokens_mistral': 4279, 'n_tokens_neox': 4115, 'n_words': 1000}