Ejemplo n.º 1
0
    def setUp(self):
        super().setUp()

        QuarterFactory(period=DateRange(date(2018, 1, 1), date(2018, 2, 1)))
        self.section = SectionFactory()
Ejemplo n.º 2
0
def groups(
        cache_name=None,
        throttle=None,
        no_commit=False,
        ):
    from mptracker.scraper.groups import GroupScraper, Interval

    http_session = create_session(cache_name=cache_name,
                                  throttle=throttle and float(throttle))
    group_scraper = GroupScraper(http_session)

    mandate_lookup = models.MandateLookup()
    mandate_intervals = defaultdict(list)

    groups = list(group_scraper.fetch())
    independents = groups[0]
    assert independents.is_independent
    for group in groups[1:] + [independents]:
        for member in group.current_members + group.former_members:
            (year, chamber, number) = member.mp_ident
            assert chamber == 2
            mandate = mandate_lookup.find(member.mp_name, year, number)
            interval_list = mandate_intervals[mandate]

            interval = member.get_interval()
            if interval.start is None:
                interval = interval._replace(start=TERM_2012_START)

            if group.is_independent:
                if interval_list:
                    start = interval_list[-1].end
                    interval = interval._replace(start=start)

            interval_list.append(interval)
            interval_list.sort(key=lambda i: i[0])

    for mandate, interval_list in mandate_intervals.items():
        # make sure interval_list are continuous
        new_intervals = []
        for interval_one, interval_two in \
            zip(interval_list[:-1], interval_list[1:]):

            assert interval_one.start < interval_one.end
            if interval_one.end < interval_two.start:
                interval = Interval(
                    start=interval_one.end,
                    end=interval_two.start,
                    group=independents,
                )
                new_intervals.append(interval)
            elif interval_one.end > interval_two.start:
                raise RuntimeError("Overlapping intervals")

        interval_list.extend(new_intervals)
        interval_list.sort()

        mandate_end = mandate.interval.upper
        if mandate_end == date.max:
            mandate_end = None
        if interval_list[-1].end != mandate_end:
            logger.warn("Mandate %s ends at %s",
                        mandate, interval_list[-1].end)

    group_patcher = TablePatcher(
        models.MpGroup,
        models.db.session,
        key_columns=['short_name'],
    )

    with group_patcher.process(remove=True) as add_group:
        for group in groups:
            record = group.as_dict(['name', 'short_name'])
            group.row = add_group(record).row

        models.db.session.flush()

    membership_patcher = TablePatcher(
        models.MpGroupMembership,
        models.db.session,
        key_columns=['mandate_id', 'mp_group_id', 'interval'],
    )

    with membership_patcher.process(
            autoflush=1000,
            remove=True,
        ) as add_membership:

        for mandate, interval_list in mandate_intervals.items():
            for interval in interval_list:
                row = add_membership({
                    'mandate_id': mandate.id,
                    'mp_group_id': interval.group.row.id,
                    'interval': DateRange(
                        interval.start or date.min,
                        interval.end or date.max,
                    ),
                }).row

    if no_commit:
        logger.warn("Rolling back the transaction")
        models.db.session.rollback()

    else:
        models.db.session.commit()
Ejemplo n.º 3
0
 def test_date_open(self):
     field = pg_forms.DateRangeField()
     value = field.clean(['', '2013-04-09'])
     self.assertEqual(value, DateRange(None, datetime.date(2013, 4, 9)))
Ejemplo n.º 4
0
 def setUp(self):
     Season.objects.create(duration=DateRange(
         date(year=2016, month=10, day=1),
         date(year=2017, month=3, day=31)))
Ejemplo n.º 5
0
 def save(self, *args, **kwargs):
     ignore_overlap = kwargs.pop('ignore_overlap', False)
     self.clean(ignore_overlap=ignore_overlap)
     self.duration = DateRange(self.start, self.end, '[]')
     return super(Period, self).save(*args, **kwargs)
    def get_calendar(self, operating_profile, operating_period):
        calendar_dates = [
            CalendarDate(start_date=date_range.start,
                         end_date=date_range.end,
                         dates=date_range.dates(),
                         operation=False)
            for date_range in operating_profile.nonoperation_days
        ]
        calendar_dates += [
            CalendarDate(start_date=date_range.start,
                         end_date=date_range.end,
                         dates=date_range.dates(),
                         special=True,
                         operation=True)
            for date_range in operating_profile.operation_days
        ]

        dates = []
        for holiday in operating_profile.operation_bank_holidays:
            if holiday in BANK_HOLIDAYS:
                for date in BANK_HOLIDAYS[holiday]:
                    if operating_period.contains(date):
                        if date not in dates:
                            dates.append(date)
                            calendar_dates.append(
                                CalendarDate(start_date=date,
                                             end_date=date,
                                             dates=DateRange(date, date, '[]'),
                                             special=True,
                                             operation=True,
                                             summary=holiday))
            else:
                self.undefined_holidays.add(holiday)

        dates = []
        for holiday in operating_profile.nonoperation_bank_holidays:
            if holiday in BANK_HOLIDAYS:
                for date in BANK_HOLIDAYS[holiday]:
                    if operating_period.contains(date):
                        if date not in dates:
                            dates.append(date)
                            calendar_dates.append(
                                CalendarDate(start_date=date,
                                             end_date=date,
                                             dates=DateRange(date, date, '[]'),
                                             operation=False,
                                             summary=holiday))
            else:
                self.undefined_holidays.add(holiday)

        sodt = operating_profile.serviced_organisation_day_type
        summary = []
        non_operation_days = []
        operation_days = []
        if sodt:
            if sodt.non_operation_working_days is sodt.non_operation_holidays:
                pass
            elif sodt.non_operation_working_days:
                if sodt.non_operation_working_days.name:
                    summary.append(
                        f'not {sodt.non_operation_working_days.name} days')
                non_operation_days += sodt.non_operation_working_days.working_days
            elif sodt.non_operation_holidays:
                if sodt.non_operation_holidays.name:
                    summary.append(
                        f'not {sodt.non_operation_holidays.name} holidays')
                non_operation_days += sodt.non_operation_holidays.holidays

            calendar_dates += [
                CalendarDate(start_date=date_range.start,
                             end_date=date_range.end,
                             dates=date_range.dates(),
                             operation=False)
                for date_range in non_operation_days
            ]

            if sodt.operation_working_days is sodt.operation_holidays:
                pass
            elif sodt.operation_working_days:
                if sodt.operation_working_days.name:
                    summary.append(f'{sodt.operation_working_days.name} days')
                operation_days += sodt.operation_working_days.working_days
            elif sodt.operation_holidays:
                if sodt.operation_holidays.name:
                    summary.append(f'{sodt.operation_holidays.name} holidays')
                operation_days += sodt.operation_holidays.holidays

            calendar_dates += [
                CalendarDate(start_date=date_range.start,
                             end_date=date_range.end,
                             dates=date_range.dates(),
                             operation=True) for date_range in operation_days
            ]

        summary = ', '.join(summary)

        if operating_period.start == operating_period.end:
            if summary:
                summary = f"{summary}, "
            summary = f"{summary}{operating_period.start.strftime('%A %-d %B %Y')} only"

        if not calendar_dates and not operating_profile.regular_days and not summary:
            return

        calendar_hash = f'{operating_profile.regular_days}{operating_period.dates()}{summary}'
        calendar_hash += ''.join(f'{date.dates}{date.operation}{date.special}'
                                 for date in calendar_dates)

        if calendar_hash in self.calendar_cache:
            return self.calendar_cache[calendar_hash]

        if summary:
            summary = get_summary(summary)

        calendar = Calendar(mon=False,
                            tue=False,
                            wed=False,
                            thu=False,
                            fri=False,
                            sat=False,
                            sun=False,
                            start_date=operating_period.start,
                            end_date=operating_period.end,
                            dates=operating_period.dates(),
                            summary=summary)

        for day in operating_profile.regular_days:
            if day == 0:
                calendar.mon = True
            elif day == 1:
                calendar.tue = True
            elif day == 2:
                calendar.wed = True
            elif day == 3:
                calendar.thu = True
            elif day == 4:
                calendar.fri = True
            elif day == 5:
                calendar.sat = True
            elif day == 6:
                calendar.sun = True

        calendar.save()
        for date in calendar_dates:
            date.calendar = calendar
        CalendarDate.objects.bulk_create(calendar_dates)

        self.calendar_cache[calendar_hash] = calendar

        return calendar
 def test_normalise_hypothesis_daterange(self, a):
     a = DateRange(*a)
     cursor = connection.cursor()
     cursor.execute("SELECT %s::daterange", [a])
     self.assertEqual(cursor.fetchone()[0], normalise(a), a)
Ejemplo n.º 8
0
    def subscribe(self, request, *args, **kwargs):
        # Make a select for update lock on admin to make sure subscriptions are properly saved
        admin = Admin.objects.select_for_update().get(pk=request.user.id)
        plan = self.object = self.get_object()

        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            now = timezone.now()
            commitment = serializer.validated_data['commitment']

            try:
                current_subscription = Subscription.objects.select_related(
                    'plan').active_for_admin(admin_id=admin.id, now=now).get()
                is_paid_plan = current_subscription.plan.paid_plan
            except Subscription.DoesNotExist:
                current_subscription = None
                is_paid_plan = False

            start_date = now

            # Depending if current plan is paid one or not, there is a different logic on subscribing
            if is_paid_plan:
                # If current plan is a paid one, next subscription need to start on next billing cycle.
                start_date += timedelta(
                    hours=settings.BILLING_GRACE_PERIOD_FOR_PLAN_CHANGING)
                start_date += relativedelta(day=1, months=+1)
                start_date = start_date.date()
                charged_until = start_date

                # If there is any - delete a subscription that's yet to start (it wasn't charged)
                Subscription.objects.filter(
                    admin_id=admin.id, range__startswith=start_date).delete()

                # Check if last subscription is the same one as the one we want to subscribe to
                last_subscription = Subscription.objects.filter(
                    admin=admin).last()
                if last_subscription.plan_id == plan.id and last_subscription.commitment == commitment:
                    last_subscription.range = DateRange(
                        last_subscription.start, None)
                    last_subscription.save()
                    return Response(
                        SubscriptionSerializer(
                            last_subscription,
                            context=self.get_serializer_context()).data)
            else:
                # If current plan is a free one, start paid plan asap
                start_date = start_date.date()
                charged_until = start_date + relativedelta(day=1, months=+1)

                # Invalidate cached subscription as we are about to create a new one for current period
                Profile.invalidate_active_subscription(admin.id)

                # Calculate plan fee
                plan_fee = plan.get_plan_fee(commitment, start_date=start_date)
                # Charge invoice
                invoice = Invoice(
                    admin=admin,
                    plan_fee=plan_fee,
                    period=start_date.replace(day=1),
                    due_date=start_date +
                    timedelta(days=settings.BILLING_DEFAULT_DUE_DATE),
                    is_prorated=start_date.day != 1)
                invoice.save()
                charge_result = invoice.charge()

                InvoiceItem.objects.create(invoice=invoice,
                                           source=InvoiceItem.SOURCES.PLAN_FEE,
                                           quantity=1,
                                           price=plan_fee)

                # If charge failed, reverse everything done here, no paid plan for you!
                if charge_result is not True:
                    raise PaymentFailed(str(charge_result))

            # Finish current subscription
            if current_subscription:
                current_subscription.range = DateRange(
                    current_subscription.start, start_date)
                current_subscription.save()

            # Finally create subscription
            subscription = Subscription.objects.create(
                range=DateRange(start_date, None),
                commitment=commitment,
                admin=admin,
                charged_until=charged_until,
                plan=plan)

            return Response(
                SubscriptionSerializer(
                    subscription, context=self.get_serializer_context()).data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-29 00:02
from __future__ import unicode_literals
from datetime import date

from django.db import migrations

from psycopg2.extras import DateRange

DEFAULT_RUN_DATE = DateRange(date(2017, 1, 1), date(2017, 1, 4), '[)')


def provide_default_date_range(apps, schema_editor):
    ContentPlacement = apps.get_model('budget', 'ContentPlacement')

    for placement in ContentPlacement.objects.filter(run_date__isnull=True):
        placement.run_date = DEFAULT_RUN_DATE
        placement.save()


class Migration(migrations.Migration):

    dependencies = [
        ('budget', '0036_auto_20171028_1655'),
    ]

    operations = [
        migrations.RunPython(provide_default_date_range),
    ]
Ejemplo n.º 10
0
 def daterange(faker, field, *args, **kwargs):
     lower = faker.date_time().date()
     upper = faker.date_time_between_dates(datetime_start=lower).date()
     return DateRange(lower, upper)
Ejemplo n.º 11
0
 def get_queryset(self):
     qs = super().get_queryset()
     qs = qs.select_related('plan').filter(admin=self.request.user)
     # Filter out subscriptions that have already ended so we always get the current one on top of the list
     return qs.exclude(range__fully_lt=DateRange(date.today()))
Ejemplo n.º 12
0
 def compress(self, data_list):
     if data_list:
         start_date, stop_date = data_list
         return DateRange(start_date, stop_date)
Ejemplo n.º 13
0
    def get_periods_for_range(self,
                              start,
                              end=None,
                              include_drafts=False,
                              include_deleted=False,
                              period_type=None):
        """Returns the period, annotated with rotation metadata and prefetched opening hours, that determines the
        opening hours for each date in the range, or None

        Parameters:
        start (date): Starting date for requested date range
        end (date): Ending date for requested date range. If omitted, only return one date.
        include_drafts (bool): Whether non-published periods are taken into account, for preview purposes
        include_deleted (bool): Whether deleted periods are taken into account
        period_type (string): Only consider 'normal' or 'override' periods, or None (override overrides normal).

        Returns:
        OrderedDict[Period]: The period that determines opening hours for each date, with max_month and max_week
        metadata, and prefetched opening hours data.
        """
        if not end:
            # default only returns single day
            end = start
        potential_periods = self.periods.filter(
            period__overlap=DateRange(lower=start, upper=end, bounds='[]'))
        if period_type:
            if period_type == 'normal':
                potential_periods.filter(override=False)
            if period_type == 'override':
                potential_periods.filter(override=True)
        if not include_drafts:
            potential_periods = potential_periods.filter(published=True)
        if not include_deleted:
            potential_periods = potential_periods.filter(deleted=False)
        # 1 query + join all openings and linked hours
        periods = [
            p for p in potential_periods.prefetch_related(
                'openings__daily_hours')
        ]
        # store the rotation metadata per period
        for period in periods:
            # Weekly rotation is subordinate to monthly rotation, if present.
            # max_month 0 means no monthly rotation (only weekly rotation)
            period.max_month = period.openings.aggregate(
                Max('month'))['month__max']
            # max_week 0 means no weekly rotation (only monthly rotation)
            period.max_week = period.openings.aggregate(
                Max('week'))['week__max']
        # shorter periods always take precedence
        periods.sort(
            key=lambda x: (-x.override, x.period.upper - x.period.lower))
        dates = pd.date_range(start, end).date
        active_periods = OrderedDict()
        for date in dates:
            for period in periods:
                if date in period.period:
                    active_periods[date] = period
                    break
            else:
                active_periods[date] = None
        return active_periods
Ejemplo n.º 14
0
 def _test_range_overlaps(self, constraint):
     # Create exclusion constraint.
     self.assertNotIn(constraint.name,
                      self.get_constraints(HotelReservation._meta.db_table))
     with connection.schema_editor() as editor:
         editor.add_constraint(HotelReservation, constraint)
     self.assertIn(constraint.name,
                   self.get_constraints(HotelReservation._meta.db_table))
     # Add initial reservations.
     room101 = Room.objects.create(number=101)
     room102 = Room.objects.create(number=102)
     datetimes = [
         timezone.datetime(2018, 6, 20),
         timezone.datetime(2018, 6, 24),
         timezone.datetime(2018, 6, 26),
         timezone.datetime(2018, 6, 28),
         timezone.datetime(2018, 6, 29),
     ]
     reservation = HotelReservation.objects.create(
         datespan=DateRange(datetimes[0].date(), datetimes[1].date()),
         start=datetimes[0],
         end=datetimes[1],
         room=room102,
     )
     constraint.validate(HotelReservation, reservation)
     HotelReservation.objects.create(
         datespan=DateRange(datetimes[1].date(), datetimes[3].date()),
         start=datetimes[1],
         end=datetimes[3],
         room=room102,
     )
     HotelReservation.objects.create(
         datespan=DateRange(datetimes[3].date(), datetimes[4].date()),
         start=datetimes[3],
         end=datetimes[4],
         room=room102,
         cancelled=True,
     )
     # Overlap dates.
     with self.assertRaises(IntegrityError), transaction.atomic():
         reservation = HotelReservation(
             datespan=(datetimes[1].date(), datetimes[2].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room102,
         )
         msg = f"Constraint “{constraint.name}” is violated."
         with self.assertRaisesMessage(ValidationError, msg):
             constraint.validate(HotelReservation, reservation)
         reservation.save()
     # Valid range.
     other_valid_reservations = [
         # Other room.
         HotelReservation(
             datespan=(datetimes[1].date(), datetimes[2].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room101,
         ),
         # Cancelled reservation.
         HotelReservation(
             datespan=(datetimes[1].date(), datetimes[1].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room102,
             cancelled=True,
         ),
         # Other adjacent dates.
         HotelReservation(
             datespan=(datetimes[3].date(), datetimes[4].date()),
             start=datetimes[3],
             end=datetimes[4],
             room=room102,
         ),
     ]
     for reservation in other_valid_reservations:
         constraint.validate(HotelReservation, reservation)
     HotelReservation.objects.bulk_create(other_valid_reservations)
     # Excluded fields.
     constraint.validate(
         HotelReservation,
         HotelReservation(
             datespan=(datetimes[1].date(), datetimes[2].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room102,
         ),
         exclude={"room"},
     )
     constraint.validate(
         HotelReservation,
         HotelReservation(
             datespan=(datetimes[1].date(), datetimes[2].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room102,
         ),
         exclude={"datespan", "start", "end", "room"},
     )
Ejemplo n.º 15
0
class TestTableTypes(TrackedTable):
    name = 'test_table_types'
    default_values = OrderedDict([
        ('test_table_types_bool', True),
        ('test_table_types_real', 9.99),
        ('test_table_types_double', 9.99),
        ('test_table_types_smallint', 9),
        ('test_table_types_integer', 50000),
        ('test_table_types_bigint', 5000000000),
        ('test_table_types_numeric', Decimal('1.1')),
        ('test_table_types_varchar', 'hi there'),
        ('test_table_types_text', 'hi there'),
        ('test_table_types_bytea', b'hi there'),
        ('test_table_types_date', date(year=1991, month=11, day=11)),
        ('test_table_types_time', time(hour=11, minute=39, second=22)),
        ('test_table_types_timetz', time(hour=11, minute=39, second=22, tzinfo=pytz.utc)),
        ('test_table_types_timestamp', datetime(year=1991, month=11, day=11, hour=11, minute=39, second=22)),
        ('test_table_types_timestamptz', datetime(year=1991, month=11, day=11, hour=11, minute=39, second=22, tzinfo=pytz.utc)),
        ('test_table_types_interval', timedelta(hours=15)),
        ('test_table_types_array', ['a', 'b', 'c', 'd', 'e']),
        # ('test_table_types_hstore', {'a': 1, 'b': 2, 'c': 3}), this dict would be passed to test_table_types_hstore
        ('test_table_types_int4range', NumericRange(lower=1, upper=10)),
        ('test_table_types_int8range', NumericRange(lower=1, upper=50000)),
        ('test_table_types_numrange', NumericRange(lower=Decimal('0.1'), upper=Decimal('1.1'))),
        ('test_table_types_daterange', DateRange(
            lower=date(year=1991, month=11, day=11),
            upper=date(year=1991, month=11, day=21),
        )),
        ('test_table_types_tsrange', DateTimeRange(
            lower=datetime(year=1991, month=11, day=11, hour=11, minute=39, second=22),
            upper=datetime(year=1991, month=11, day=21, hour=11, minute=39, second=22),
        )),
        ('test_table_types_tstzrange', DateTimeTZRange(
            lower=datetime(year=1991, month=11, day=11, hour=11, minute=39, second=22, tzinfo=pytz.utc),
            upper=datetime(year=1991, month=11, day=21, hour=11, minute=39, second=22, tzinfo=pytz.utc),
        )),
        # ('test_table_types_uuid', UUID(bytes=b'1234567890123456')),
        # ('test_table_types_inet', ip_network('192.168.0.0')),
        # ('test_table_types_cidr', ip_network('192.168.0.0')),
        ('test_table_types_json', json.dumps(['a', {'b': 2}, 2])),
        ('test_table_types_jsonb', json.dumps(['a', {'b': 2}, 2])),
    ])

    def build(self, cursor=None):
        if not cursor:
            cursor = self.get_cursor()

        cursor.execute(
            "CREATE TABLE test_table_types ("
                "test_table_types_bool bool DEFAULT %s, "
                "test_table_types_real real DEFAULT %s, "
                "test_table_types_double double precision DEFAULT %s, "
                "test_table_types_smallint smallint DEFAULT %s, "
                "test_table_types_integer integer DEFAULT %s, "
                "test_table_types_bigint bigint DEFAULT %s, "
                "test_table_types_numeric numeric DEFAULT %s, "
                "test_table_types_varchar varchar DEFAULT %s, "
                "test_table_types_text text DEFAULT %s, "
                "test_table_types_bytea bytea DEFAULT %s, "
                "test_table_types_date date DEFAULT %s, "
                "test_table_types_time time DEFAULT %s, "
                "test_table_types_timetz timetz DEFAULT %s, "
                "test_table_types_timestamp timestamp DEFAULT %s, "
                "test_table_types_timestamptz timestamptz DEFAULT %s, "
                "test_table_types_interval interval DEFAULT %s, "
                "test_table_types_array text[] DEFAULT %s, "
                # "test_table_types_hstore hstore DEFAULT %s, " hstore is unused.
                "test_table_types_int4range int4range DEFAULT %s, "
                "test_table_types_int8range int8range DEFAULT %s, "
                "test_table_types_numrange numrange DEFAULT %s, "
                "test_table_types_daterange daterange DEFAULT %s, "
                "test_table_types_tsrange tsrange DEFAULT %s, "
                "test_table_types_tstzrange tstzrange DEFAULT %s, "
                # "test_table_types_uuid uuid DEFAULT %s, " uuid is unused.
                # "test_table_types_inet inet DEFAULT %s, " inet types are unused.
                # "test_table_types_cidr cidr DEFAULT %s, "
                "test_table_types_json json DEFAULT %s, "
                "test_table_types_jsonb jsonb DEFAULT %s "
            ")", list(self.default_values.values())
        )

        for i in range(1000):
            cursor.execute("INSERT INTO test_table_types DEFAULT VALUES")
Ejemplo n.º 16
0
 def date_range(in_row):
     d = datetime.datetime.strptime(in_row['date'], "%Y-%j")
     return DateRange(lower=d.date(),
                      upper=d.date(),
                      bounds='[]')
Ejemplo n.º 17
0
def buildGraphs():


    featureGraph = nx.Graph()
    
    # There are some polygon sources that we want to ignore, so we identify the sources to 
    excludeSourceRefs = list()
    sourceDict = {}
    sourceDict.update(API_META)
    sourceDict.update(CSV_META)
    sourceDict.update(GEOJSON_META)
    for sourceName in sourceDict:
        if not sourceDict[sourceName]['forConflict']:
            excludeSourceRefs.append(API_element.objects.get(api_name=sourceName).id)
    
    excludeStatuses = ['COMPLETED', 'COMPLETED', 'REQUESTED', 'COMPLETE', 'DENIED', 'CANCELED']

    
    
    filteredFeatures = Feature.objects\
        .exclude(canonical_daterange=None)\
        .exclude(canonical_daterange__isempty=True)\
        .exclude(neighborhood__isnull=True)\
        .exclude(source_ref__in=excludeSourceRefs)\
        .exclude(canonical_status__in=excludeStatuses)\
        .filter(canonical_daterange__overlap=DateRange(lower='2015-01-01', upper='2020-01-01'))
        
    print('filteredFeatures count', filteredFeatures.count())
    
    for idx, f1 in enumerate(filteredFeatures):
        print('idx', idx)
        for f2 in filteredFeatures[idx+1:]:
            if f1.id == f2.id:
                continue
            daysApart = getDayDiff(f1, f2)
            if daysApart < 60:
                featureGraph.add_nodes_from([f1.id, f2.id])
                featureGraph.add_edge(f1.id, f2.id, {'daysApart':daysApart})
            
        # if idx > 10:
        #     break

    print('nodecount', nx.number_of_nodes(featureGraph))
    print('edgecount', nx.number_of_edges(featureGraph))
    
    datedFeatureIDs = [f for f in featureGraph.nodes()]
    datedFeatures = Feature.objects.filter(pk__in=datedFeatureIDs)

    # for e in featureGraph.edges(data=True):
    #     print(e)

    counter = 0
    # print(datedFeatures.get(pk=46907))
    # print(featureGraph[46907])
    # print(featureGraph.neighbors(46907))
    
    for f1 in datedFeatures:
        
        connected = featureGraph.neighbors(f1.id)
        cids = [f for f in connected]
        connectedFeatures = Feature.objects.filter(pk__in=cids)

        counter += 1
        print('counter: {} of {}'.format(counter, datedFeatures.count()))
        for f2 in connectedFeatures.annotate(distance=Distance('geom', f1.geom)):
            # print(f1.id, f2.id)
            # print(f1.canonical_daterange, f2.canonical_daterange)            
            featureGraph.add_edge(f1.id, f2.id, distance=f2.distance.m)

    print('nodecount', nx.number_of_nodes(featureGraph))
    print('edgecount', nx.number_of_edges(featureGraph))

    cache.set('featureGraph', featureGraph, None)
Ejemplo n.º 18
0
 def date_range(in_row):
     return DateRange(lower=in_row[lower], upper=in_row[upper])
 def test_with_hypothesis_dates(self, a, b):
     a = DateRange(*a)
     b = DateRange(*b)
     cursor = connection.cursor()
     cursor.execute("SELECT %s::daterange && %s::daterange", [a, b])
     self.assertEqual(cursor.fetchone()[0], a & b, "{} && {}".format(a, b))
Ejemplo n.º 20
0
 def date_range(in_row):
     return DateRange(lower=in_row[columns[0]],
                      upper=in_row[columns[0]],
                      bounds='[]')
 def test_may_not_compare_different_range_types(self):
     with self.assertRaises(TypeError):
         NumericRange() & DateRange()
Ejemplo n.º 22
0
import datetime
from decimal import Decimal

from psycopg2.extras import DateRange
from sqlalchemy.sql.expression import and_, func
from pygotham_2019.meta import session
from pygotham_2019.model import DrugInfo, DrugPrice
from pygotham_2019.utils import print_table

if __name__ == "__main__":
    session.add_all([
        DrugInfo(
            id="1234567890",
            validity=DateRange(
                lower="1970-01-01",
                upper="2019-10-04",
            ),
            name="Lipitor",
            description="20mg tablet",
        ),
        DrugInfo(
            id="1234567890",
            validity=DateRange(
                lower="2019-10-04",
                upper="9999-12-31",
            ),
            name="Lipitor",
            description="20mg Tablet",
        ),
        DrugInfo(
            id="9999999999",
Ejemplo n.º 23
0
def get_opening_hours(time_zone, periods, begin, end=None):
    """
    Returns opening and closing times for a given date range

    Return value is a dict where keys are days on the range
        and values are a list of Day objects for that day's active period
        containing opening and closing hours

    :rtype : dict[str, list[dict[str, datetime.datetime]]]
    :type periods: list[Period]
    :type begin: datetime.date | datetime.datetime
    :type end: datetime.date | None
    """

    tz = pytz.timezone(time_zone)
    if begin is not None:
        if isinstance(begin, datetime.datetime):
            begin = datetime_to_date(begin, tz)
        assert isinstance(begin, datetime.date)

    if end is not None:
        if isinstance(end, datetime.datetime):
            end = datetime_to_date(end, tz)
        assert isinstance(end, datetime.date)

    if begin is None:
        begin = tz.localize(datetime.datetime.now()).date()
    if end is None:
        end = begin

    assert begin <= end

    if begin == end:
        d_range = DateRange(begin, end, '[]')
    else:
        d_range = DateRange(begin, end)

    # Periods are taken into account the shortest first.
    periods = periods.filter(duration__overlap=d_range)\
        .annotate(length=dbm.F('end')-dbm.F('start'))\
        .order_by('length')
    days = Day.objects.filter(period__in=periods)

    periods = list(periods)
    for period in periods:
        period.range_days = {
            day.weekday: day
            for day in days if day.period == period
        }

    date = begin
    dates = {}
    while date <= end:
        opens = None
        closes = None
        for period in periods:
            if period.start > date or period.end < date:
                continue
            # Currently the 'closed' field of periods do not
            # always contain sensible data. Ignore it for now.
            if False and period.closed:
                break
            day = period.range_days.get(date.weekday())
            if day is None or day.closed:
                break
            opens = combine_datetime(date, day.opens, tz)
            closes = combine_datetime(date, day.closes, tz)
            break

        dates[date] = [{'opens': opens, 'closes': closes}]
        date += datetime.timedelta(days=1)

    return dates
Ejemplo n.º 24
0
def get_opening_hours(begin, end, resources=None):
    """
    :type begin:datetime.date
    :type end:datetime.date
    :type resources: Resource | None
    :rtype: dict[datetime, dict[Resource, list[OpenHours]]]

    Find opening hours for all resources on a given time period.

    If resources is None, finds opening hours for all resources.

    This version goes through all regular periods and then all
    exception periods that are found overlapping the given
    time range. It builds a dict of days that has dict of
    resources with their active hours.

    TODO: There is couple optimization avenues worth exploring
    with prefetch or select_related for Periods'
    relational fields Unit, Resource and Day. This way all
    relevant information could be requested with one or two
    queries from the db.
    """
    if not resources:
        resources = Resource.objects.all()

    if not begin < end:
        end = begin + datetime.timedelta(days=1)

    d_range = DateRange(begin, end)

    periods = Period.objects.filter(
        djdbm.Q(resource__in=resources) | djdbm.Q(unit__in=resources.values("unit__pk")),
        duration__overlap=d_range).order_by('exception')

    begin_dt = datetime.datetime.combine(begin, datetime.time(0, 0))
    end_dt = datetime.datetime.combine(end, datetime.time(0, 0))

    # Generates a dict of time range's days as keys and values as active period's days

    # all requested dates are assumed closed
    dates = {r.date(): False for r in arrow.Arrow.range('day', begin_dt, end_dt)}

    for period in periods:

        if period.start < begin:
            start = begin_dt
        else:
            start = arrow.get(period.start)
        if period.end > end:
            end = end_dt
        else:
            end = arrow.get(period.end)

        if period.resource:
            period_resources = [period.resource]
        else:
            period_resources = period.unit.resources.filter(pk__in=resources)

        for res in period_resources:

            for r in arrow.Arrow.range('day', start, end):
                for day in period.days.all():
                    if day.weekday is r.weekday():
                        if not dates.get(r.date(), None):
                            dates[r.date] = {}
                        dates[r.date()].setdefault(
                            res, []).append(
                            OpenHours(day.opens, day.closes))

    return dates
Ejemplo n.º 25
0
def people(
    year='2012',
    cache_name=None,
    throttle=None,
    no_commit=False,
):
    from mptracker.scraper.people import MandateScraper

    http_session = create_session(
        cache_name=cache_name,
        throttle=throttle and float(throttle),
    )
    mandate_scraper = MandateScraper(http_session)

    mandate_patcher = TablePatcher(
        models.Mandate,
        models.db.session,
        key_columns=['year', 'cdep_number'],
    )

    with mandate_patcher.process() as add_mandate:
        for mandate in mandate_scraper.fetch(year):
            row = mandate.as_dict([
                'year',
                'cdep_number',
                'minority',
                'college',
                'constituency',
            ])
            if year == '2012':
                end_date = mandate.end_date or date.max
                row['interval'] = DateRange(TERM_2012_START, end_date)

            person = (
                models.Person.query
                    .filter_by(name=mandate.person_name)
                    .first())
            if person is None:
                raise RuntimeError("Can't find person named %r"
                                   % mandate.person_name)

            row['person_id'] = person.id

            if not mandate.minority:
                county = (
                    models.County.query
                        .filter_by(name=mandate.county_name)
                        .first())
                if county is None:
                    raise RuntimeError("Can't match county name %r"
                                       % mandate.county_name)
                row['county'] = county

            add_mandate(row)

    if no_commit:
        logger.warn("Rolling back the transaction")
        models.db.session.rollback()

    else:
        models.db.session.commit()
Ejemplo n.º 26
0
def get_availability(begin, end, resources=None, duration=None):
    """
    Availability is opening hours and free time between reservations

    This function calculates both for given time range

    Given a queryset of resources (even if just one) can calculate
    applicable opening hours and free time slots between
    begin and end of day and reservations for days that
    have reservations

    Does not currently check if resource is open shorter time
    than duration

    :param begin:
    :type begin:
    :param end:
    :type end:
    :param duration:
    :type duration:
    :param resources:
    :type resources:
    :return:
    :rtype:
    """
    if not resources:
        resources = Resource.objects.all()

    dt_range = DateTimeTZRange(begin, end)

    if not begin < end:
        end_d = begin + datetime.timedelta(days=1)
        d_range = DateRange(begin.date, end_d.date())
    else:
        d_range = DateRange(begin.date(), end.date())

    # Saved query for overlapping periods, fetching also their Day items
    qs_periods = Period.objects.filter(
        duration__overlap=d_range
    ).order_by('exception').prefetch_related('days')

    # Saved query for Unit's overlapping periods, fetching also their Day items
    qs_unit_periods = Unit.objects.filter(
        periods__duration__overlap=d_range
    ).order_by('periods__exception').prefetch_related('periods__days')

    # Saved query for overlapping reservations
    qs_reservations = Reservation.objects.filter(duration__overlap=dt_range)

    # Get all resources and prefetch to stated attributes to the items
    # their matching Period, Unit and Reservation
    # items according to queries defined above

    resources_during_time = resources.prefetch_related(
        Prefetch('periods', queryset=qs_periods, to_attr='overlapping_periods'),
        Prefetch('unit', queryset=qs_unit_periods, to_attr='overlapping_unit'),
        Prefetch('reservations', queryset=qs_reservations, to_attr='overlapping_reservations')
    )

    # NOTE: Resource's Period overrides Unit's Period

    opening_hours = {}
    availability = {}

    for res in resources_during_time:
        opening_hours[res] = periods_to_opening_hours(res, begin, end)

        if duration:
            availability[res] = calculate_availability(res, opening_hours[res], duration)

    return opening_hours, availability
Ejemplo n.º 27
0
 def test_valid_dates(self):
     field = pg_forms.DateRangeField()
     value = field.clean(['01/01/2014', '02/02/2014'])
     lower = datetime.date(2014, 1, 1)
     upper = datetime.date(2014, 2, 2)
     self.assertEqual(value, DateRange(lower, upper))
Ejemplo n.º 28
0
class QuarterCurrentFactory(QuarterFactory):
    period = DateRange((date.today() + timedelta(days=-1)),
                       (date.today() + timedelta(days=1)))
Ejemplo n.º 29
0
 def _test_range_overlaps(self, constraint):
     # Create exclusion constraint.
     self.assertNotIn(constraint.name, self.get_constraints(HotelReservation._meta.db_table))
     with connection.schema_editor() as editor:
         editor.add_constraint(HotelReservation, constraint)
     self.assertIn(constraint.name, self.get_constraints(HotelReservation._meta.db_table))
     # Add initial reservations.
     room101 = Room.objects.create(number=101)
     room102 = Room.objects.create(number=102)
     datetimes = [
         timezone.datetime(2018, 6, 20),
         timezone.datetime(2018, 6, 24),
         timezone.datetime(2018, 6, 26),
         timezone.datetime(2018, 6, 28),
         timezone.datetime(2018, 6, 29),
     ]
     HotelReservation.objects.create(
         datespan=DateRange(datetimes[0].date(), datetimes[1].date()),
         start=datetimes[0],
         end=datetimes[1],
         room=room102,
     )
     HotelReservation.objects.create(
         datespan=DateRange(datetimes[1].date(), datetimes[3].date()),
         start=datetimes[1],
         end=datetimes[3],
         room=room102,
     )
     # Overlap dates.
     with self.assertRaises(IntegrityError), transaction.atomic():
         reservation = HotelReservation(
             datespan=(datetimes[1].date(), datetimes[2].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room102,
         )
         reservation.save()
     # Valid range.
     HotelReservation.objects.bulk_create([
         # Other room.
         HotelReservation(
             datespan=(datetimes[1].date(), datetimes[2].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room101,
         ),
         # Cancelled reservation.
         HotelReservation(
             datespan=(datetimes[1].date(), datetimes[1].date()),
             start=datetimes[1],
             end=datetimes[2],
             room=room102,
             cancelled=True,
         ),
         # Other adjacent dates.
         HotelReservation(
             datespan=(datetimes[3].date(), datetimes[4].date()),
             start=datetimes[3],
             end=datetimes[4],
             room=room102,
         ),
     ])
Ejemplo n.º 30
0
    def get_calendar(self, operating_profile, operating_period):
        calendar_dates = [
            CalendarDate(start_date=date_range.start,
                         end_date=date_range.end,
                         dates=date_range.dates(),
                         operation=False)
            for date_range in operating_profile.nonoperation_days
        ]
        calendar_dates += [
            CalendarDate(start_date=date_range.start,
                         end_date=date_range.end,
                         dates=date_range.dates(),
                         special=True,
                         operation=True)
            for date_range in operating_profile.operation_days
        ]

        for holiday in operating_profile.operation_bank_holidays:
            if holiday in BANK_HOLIDAYS:
                if (holiday == 'AllBankHolidays' or holiday
                        == 'HolidayMondays') and self.region_id == 'S':
                    continue
                date = BANK_HOLIDAYS[holiday]
                dates = DateRange(date, date, '[]')
                if operating_period.contains(date):
                    calendar_dates.append(
                        CalendarDate(start_date=date,
                                     end_date=date,
                                     dates=dates,
                                     special=True,
                                     operation=True))
            else:
                self.undefined_holidays.add(holiday)

        for holiday in operating_profile.nonoperation_bank_holidays:
            if holiday in BANK_HOLIDAYS:
                if (holiday == 'AllBankHolidays' or holiday
                        == 'HolidayMondays') and self.region_id == 'S':
                    continue
                date = BANK_HOLIDAYS[holiday]
                dates = DateRange(date, date, '[]')
                if operating_period.contains(date):
                    calendar_dates.append(
                        CalendarDate(start_date=date,
                                     end_date=date,
                                     dates=dates,
                                     operation=False))
            else:
                self.undefined_holidays.add(holiday)

        if operating_profile.servicedorganisation:
            org = operating_profile.servicedorganisation

            nonoperation_days = (org.nonoperation_workingdays
                                 and org.nonoperation_workingdays.working_days
                                 or org.nonoperation_holidays
                                 and org.nonoperation_holidays.holidays)
            if nonoperation_days:
                calendar_dates += [
                    CalendarDate(start_date=date_range.start,
                                 end_date=date_range.end,
                                 dates=date_range.dates(),
                                 operation=False)
                    for date_range in nonoperation_days
                ]

            operation_days = (org.operation_workingdays
                              and org.operation_workingdays.working_days
                              or org.operation_holidays
                              and org.operation_holidays.holidays)
            if operation_days:
                calendar_dates += [
                    CalendarDate(start_date=date_range.start,
                                 end_date=date_range.end,
                                 dates=date_range.dates(),
                                 operation=True)
                    for date_range in operation_days
                ]

        # remove date ranges which end before they start?! etc
        calendar_dates = [
            dates for dates in calendar_dates
            if dates.relevant(operating_period)
        ]

        if not calendar_dates and not operating_profile.regular_days:
            return

        calendar_hash = f'{operating_profile.regular_days}{operating_period.dates()}'
        calendar_hash += ''.join(f'{date.dates}{date.operation}{date.special}'
                                 for date in calendar_dates)

        if calendar_hash in self.calendar_cache:
            return self.calendar_cache[calendar_hash]

        calendar = Calendar(mon=False,
                            tue=False,
                            wed=False,
                            thu=False,
                            fri=False,
                            sat=False,
                            sun=False,
                            start_date=operating_period.start,
                            end_date=operating_period.end,
                            dates=operating_period.dates())

        for day in operating_profile.regular_days:
            if day == 0:
                calendar.mon = True
            elif day == 1:
                calendar.tue = True
            elif day == 2:
                calendar.wed = True
            elif day == 3:
                calendar.thu = True
            elif day == 4:
                calendar.fri = True
            elif day == 5:
                calendar.sat = True
            elif day == 6:
                calendar.sun = True

        calendar.save()
        for date in calendar_dates:
            date.calendar = calendar
        CalendarDate.objects.bulk_create(calendar_dates)

        self.calendar_cache[calendar_hash] = calendar

        return calendar