Exemplo n.º 1
0
class CloneRepeatIntervalForm(CloneRepeatUntilFormBase):
    recurrence = RelativeDeltaField(_('Every'), [DataRequired()],
                                    units=('years', 'months', 'weeks', 'days'),
                                    default=relativedelta(weeks=1))

    def validate_recurrence(self, field):
        if field.data != abs(field.data):
            raise ValidationError(_("The time period must be positive"))
Exemplo n.º 2
0
class RelativeDeltaField(Field):
    """A field that lets the user select a simple timedelta.

    It does not support mixing multiple units, but it is smart enough
    to switch to a different unit to represent a timedelta that could
    not be represented otherwise.

    :param units: The available units. Must be a tuple containing any
                  any of 'seconds', 'minutes', 'hours' and 'days'.
                  If not specified, ``('hours', 'days')`` is assumed.
    """

    widget = JinjaWidget('forms/timedelta_widget.html',
                         single_line=True,
                         single_kwargs=True)
    # XXX: do not translate, "Minutes" is ambiguous without context
    unit_names = {
        'seconds': 'Seconds',
        'minutes': 'Minutes',
        'hours': 'Hours',
        'days': 'Days',
        'weeks': 'Weeks',
        'months': 'Months',
        'years': 'Years'
    }
    magnitudes = OrderedDict([('years', relativedelta(years=1)),
                              ('months', relativedelta(months=1)),
                              ('weeks', relativedelta(weeks=1)),
                              ('days', relativedelta(days=1)),
                              ('hours', relativedelta(hours=1)),
                              ('minutes', relativedelta(minutes=1)),
                              ('seconds', relativedelta(seconds=1))])

    def __init__(self, *args, **kwargs):
        self.units = kwargs.pop('units', ('hours', 'days'))
        super(RelativeDeltaField, self).__init__(*args, **kwargs)

    @property
    def split_data(self):
        if self.data is None:
            return None, None
        for unit in self.magnitudes:
            number = getattr(self.data, unit)
            if number:
                return number, unit
        raise ValueError('Unsupported relativedelta() unit')

    @property
    def choices(self):
        choices = [(unit, self.unit_names[unit]) for unit in self.units]
        number, unit = self.split_data
        if number is not None and unit not in self.units:
            # Add whatever unit is necessary to represent the currenet value if we have one
            choices.append((unit, '({})'.format(self.unit_names[unit])))
        return choices

    def process_formdata(self, valuelist):
        if valuelist and len(valuelist) == 2:
            value = int(valuelist[0])
            unit = valuelist[1]
            if unit not in self.magnitudes:
                raise ValueError('Invalid unit')
            self.data = (self.magnitudes[unit] * value).normalized()

    def pre_validate(self, form):
        if self.object_data is None:
            raise ValueError(_('Please choose a valid unit.'))

    def _value(self):
        if self.data is None:
            return '', ''
        return self.split_data
Exemplo n.º 3
0
from datetime import datetime

import pytest
from pytz import timezone

from indico.modules.events.management.controllers.cloning import (
    CloneCalculator, IntervalCloneCalculator, PatternCloneCalculator)
from indico.modules.events.management.forms import CloneRepeatIntervalForm, CloneRepeatPatternForm
from indico.util.date_time import relativedelta


@pytest.mark.parametrize(
    ('start_dt', 'delta', 'stop_criterion', 'num_times', 'until_dt',
     'expected_dates', 'expected_flag'),
    ((datetime(2017, 2, 28, 3, 0, 0), relativedelta(years=1), 'num_times', 2,
      None, [datetime(2017, 2, 28, 3, 0, 0),
             datetime(2018, 2, 28, 3, 0, 0)], False),
     (datetime(2017, 2, 28, 3, 0,
               0), relativedelta(months=1), 'num_times', 3, None, [
                   datetime(2017, 2, 28, 3, 0, 0),
                   datetime(2017, 3, 31, 3, 0, 0),
                   datetime(2017, 4, 30, 3, 0, 0)
               ], True), (datetime(2017, 2, 27, 3, 0, 0),
                          relativedelta(months=1), 'num_times', 3, None, [
                              datetime(2017, 2, 27, 3, 0, 0),
                              datetime(2017, 3, 27, 3, 0, 0),
                              datetime(2017, 4, 27, 3, 0, 0)
                          ], False),
     (datetime(2017, 2, 28, 3, 0, 0), relativedelta(months=1), 'day', None,
      datetime(2017, 4, 30, 3, 0, 0),
Exemplo n.º 4
0
# LICENSE file for more details.

from datetime import datetime

import pytest
from pytz import timezone

from indico.modules.events.management.controllers.cloning import (CloneCalculator, IntervalCloneCalculator,
                                                                  PatternCloneCalculator)
from indico.modules.events.management.forms import CloneRepeatIntervalForm, CloneRepeatPatternForm
from indico.util.date_time import relativedelta


@pytest.mark.parametrize(('start_dt', 'delta', 'stop_criterion', 'num_times', 'until_dt',
                          'expected_dates', 'expected_flag'), (
    (datetime(2017, 2, 28, 3, 0, 0), relativedelta(years=1), 'num_times', 2, None,
     [datetime(2017, 2, 28, 3, 0, 0), datetime(2018, 2, 28, 3, 0, 0)], False),
    (datetime(2017, 2, 28, 3, 0, 0), relativedelta(months=1), 'num_times', 3, None,
     [datetime(2017, 2, 28, 3, 0, 0), datetime(2017, 3, 31, 3, 0, 0), datetime(2017, 4, 30, 3, 0, 0)], True),
    (datetime(2017, 2, 27, 3, 0, 0), relativedelta(months=1), 'num_times', 3, None,
     [datetime(2017, 2, 27, 3, 0, 0), datetime(2017, 3, 27, 3, 0, 0), datetime(2017, 4, 27, 3, 0, 0)], False),
    (datetime(2017, 2, 28, 3, 0, 0), relativedelta(months=1), 'day', None, datetime(2017, 4, 30, 3, 0, 0),
     [datetime(2017, 2, 28, 3, 0, 0), datetime(2017, 3, 31, 3, 0, 0)], True),
    (datetime(2017, 2, 28, 3, 0, 0), relativedelta(weeks=2), 'num_times', 3, None,
     [datetime(2017, 2, 28, 3, 0, 0), datetime(2017, 3, 14, 3, 0, 0), datetime(2017, 3, 28, 3, 0, 0)], False),
    (datetime(2017, 2, 28, 3, 0, 0), relativedelta(days=1), 'day', None, datetime(2017, 3, 2, 3, 0, 0),
     [datetime(2017, 2, 28, 3, 0, 0), datetime(2017, 3, 1, 3, 0, 0), datetime(2017, 3, 2, 3, 0, 0)], False)
))
def test_interval_clone(start_dt, delta, stop_criterion, num_times, until_dt,
                        expected_dates, expected_flag, dummy_event):
    dummy_event.timezone = 'Europe/Zurich'