def test_client_create_many_dummy_entries_in_range(self): cbit = self.custom_feed_url(9, dt.today() - timedelta(days=7), dt.today()).lstrip('/') logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) self.assertEqual(models.Entry.objects.all().count(), 9)
def test_delete_empty_digest_entries(self): d = {'date_created': dt.today(), 'digest_feed': self.digestobj} de = models.DigestEntry(**d) de.save() self.assertEqual(1, logic.find_empty_digest_entries().count()) logic.delete_empty_digest_entries() self.assertEqual(0, logic.find_empty_digest_entries().count())
def test_find_empty_digests(self): """Creating an empty digest entry is supposedly impossible. Marking such an entry 'read' should delete it""" d = {'date_created': dt.today(), 'digest_feed': self.digestobj} de = models.DigestEntry(**d) de.save() self.assertEqual(1, logic.find_empty_digest_entries().count())
def create_digest_entry(digestobj, today=None, period=None): "Creates a DigestEntry object for the digestobj ONLY if there are entries for the given period." if not today: today = dt.today() entry_list = entries_for_digest(digestobj, today, period) if entry_list.count() == 0: logger.debug("no entries found for this period, returning None") return None logger.debug("found %s entries" % entry_list.count()) try: compobj = models.DigestEntry.objects.get(digest_feed=digestobj, date_created=today) logger.debug("found existing digest entry, using this one") except models.DigestEntry.DoesNotExist: logger.debug("no previous digest entry found, creating a new one") compobj = models.DigestEntry(digest_feed=digestobj) compobj.date_created = today compobj.save() logger.debug("updating entry list") compobj.entries = entry_list compobj.save() logger.debug("updating digest feed's last digest date") digestobj.date_last_digest = today digestobj.save() return compobj
def date_next_digest(digestobj, today=None, respect_future_dates=False): """Returns the datetime object of the next expected digest. Wraps `next_weekly_digest` and `next_daily_digest`.""" if not today: today = dt.today() func = next_daily_digest if digestobj.daily() else next_weekly_digest return func(digestobj, today, respect_future_dates)
def test_nondate_values(self): "Test that TypeErrors are raised when arguments of invalid types are passed." start_dt = "woooooooooooooo" end_dt = dt.today() self.assertRaises(TypeError, logic.dates_in_range, start_dt, end_dt) self.assertRaises(TypeError, logic.dates_in_range, end_dt, start_dt) self.assertRaises(TypeError, logic.dates_in_range, end_dt, end_dt, end_dt)
def test_mark_empty_digest_entry(self): "marking a digest entry with no entries read will delete the digest entry" d = {'date_created': dt.today(), 'digest_feed': self.digestobj} de = models.DigestEntry(**d) de.save() self.assertEqual(1, logic.find_empty_digest_entries().count()) logic.mark_digest_entry_read(self.get_user(), de) self.assertEqual(0, logic.find_empty_digest_entries().count())
def test_prev_daily_digest_date(self): today = dt.today() digestobj, created = dh.get_create_digest_feed(self.get_user(), self.feedobj, 'daily') digestobj.date_last_digest = today digestobj.save() prev_dt = dh.date_prev_digest(digestobj, today) self.assertEqual(prev_dt, today - timedelta(days=1))
def test_next_daily_digest_existing_digest(self): "The next digest date is correctly generated for a daily digest with a last published date in the present." today = dt.today() digestobj, created = dh.get_create_digest_feed(self.get_user(), self.feedobj, 'daily') digestobj.date_last_digest = today digestobj.save() self.assertEqual(dh.date_next_digest(digestobj), today + timedelta(days=1))
def test_weekly_custom_value(self): today = dt.today() - timedelta(days=123) res = dh.weekly(today) # whoa - why rd.SU? because to prevent overlap between periods # (ie: two periods sharing the same saturday) we only go # backwards 6 days in time. self.assertEqual(res[0], today + rd.relativedelta(weekday=rd.SU(-1))) self.assertEqual(res[1], today + rd.relativedelta(weekday=rd.SA)) self.assertEqual(res[2], today)
def test_next_daily_digest_existing_future_date(self): "The next digest date is correctly generated for a daily digest with a last published date in the future." today = dt.today() digestobj, created = dh.get_create_digest_feed(self.get_user(), self.feedobj, 'daily') digestobj.date_last_digest = today + timedelta( days=28) # a month from now a digest was/will be created digestobj.save() self.assertEqual(dh.date_next_digest(digestobj), today)
def test_next_daily_digest_existing_past_date(self): "The next digest date is correctly generated for a daily digest with a last published date in the past." today = dt.today() digestobj, created = dh.get_create_digest_feed(self.get_user(), self.feedobj, 'daily') digestobj.date_last_digest = today - timedelta( days=28) # no digest has been created for a month. tsk tsk. digestobj.save() self.assertEqual(dh.date_next_digest(digestobj), today)
def entries_for_digest(digestobj, today=None, period=None): "Returns a list of models.Entry objects for the current period." if not today: today = dt.today() if not period: period = digest_period(digestobj, today) logger.debug("searching for entries during period %s to %s for feed %s" % (period[0], period[1], digestobj)) return models.Entry.objects.filter(last_updated__range=period, feed=digestobj.feed)
def queryset_in_range(qs, dt_key, duration=30, start_dt=None): if not start_dt: start_dt = dt.today() if duration < 0 or duration > (365 * 2): raise ValueError("Duration must be greater than zero, less than 365 * 2") if not isinstance(start_dt, datetime): raise ValueError("Start datetime must be a datetime object.") key = '%s__range' % dt_key kwargs = {key: (start_dt - timedelta(days=duration), dt.max(start_dt))} return qs.filter(**kwargs)
def period_generator(today=None, span=1, day_of_week=None, bounds=(None, None), bit=4): """Yields the current period and the next or previous periods depending on the value of `span`. It will do this forever or until it encounters a boundary specified using `bounds`. """ if not today: today = dt.today() if bit < 0 or bit > 4: raise ValueError("`bit` argument must be either zero, one or two") if span == 0: raise ValueError("`span` argument cannot be zero") if day_of_week: func = partial(weekly, day_of_week=day_of_week) else: func = daily logger.debug("generator args: %s" % ({ 'today': today, 'span': span, 'dow': day_of_week, 'bounds': bounds, 'bit': bit })) while True: triplet = func(today) if bit == 0: yield (triplet[0]) # period start elif bit == 1: yield (triplet[1]) # period end elif bit == 2: yield (triplet[2]) # original date elif bit == 3: yield (triplet) # start, end, original date elif bit == 4: yield (triplet[:2]) # start, end today += timedelta(days=span) st, ed, mo = triplet b1, b2 = bounds if b1 and span < 1: # check start boundary because we're # going backwards in time if st <= b1: raise StopIteration() if b2 and span > 0: # check end boundary because we're # going forwards in time if ed >= b2: raise StopIteration()
def setUp(self): # creates 21 objects over 7 days (~3 objects per digest per day) today_sat = dt.today() + rd.relativedelta(weekday=rd.SA) start_dt, end_dt = today_sat - timedelta(days=7), today_sat cbit = self.custom_feed_url(21, start_dt, end_dt).lstrip('/') logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) feedobj = models.Feed.objects.get(pk=1) digestobj, created = dh.get_create_digest_feed(self.get_user(), feedobj, 'daily') dh.create_prev_digest_entries(digestobj, today=end_dt, until=start_dt)
def setUp(self): # creates 30 entries over 14 days period = 30 self.entry_count = 14 self.today = dt.today() self.start_dt = self.today - timedelta(days=period) self.end_dt = self.today cbit = self.custom_feed_url(self.entry_count, self.start_dt, self.end_dt).lstrip('/') res = logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) self.feedobj = models.Feed.objects.get(pk=1)
def test_create_dummy_data_with_kwargs(self): "Test that dummy data using custom kwargs are successfully passed through" kwargs = { 'author': 'Jane Doe', 'content': 'foo', 'guid': 'foo-bar', 'last_updated': dt.today() - timedelta(days=14), 'link': 'http://localhost', 'title': 'bar' } dummy = logic.dummy_entry_data(**kwargs) for key, val in kwargs.iteritems(): self.assertEqual(dummy[key], val) self.assertNotEqual(dummy[key], 'woooooooooooo')
def setUp(self): # create 28 entries over 14 days period = 14 self.today = dt.today() + rd.relativedelta(weekday=rd.SA(-1)) self.start_dt = self.today - timedelta(days=period) self.end_dt = self.today cbit = self.custom_feed_url(period * 2, self.start_dt, self.end_dt).lstrip('/') res = logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) feedobj = models.Feed.objects.get(pk=1) self.digestobj, created = dh.get_create_digest_feed( self.get_user(), feedobj, 'weekly', 'sat')
def setUp(self): # creates 14 entries over 14 days self.period = 14 today_sat = dt.today() + rd.relativedelta(weekday=rd.SA) self.start_dt = dt.min(today_sat - timedelta(days=self.period)) self.end_dt = dt.max(today_sat) cbit = self.custom_feed_url(self.period, self.start_dt, self.end_dt).lstrip('/') res = logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) self.feedobj = models.Feed.objects.get(pk=1) self.digestobj, created = dh.get_create_digest_feed( self.get_user(), self.feedobj, 'weekly', 'sat')
def setUp(self): # create 14 entries over 7 days period = 7 self.today = dt.today() self.start_dt = self.today - timedelta(days=period) self.end_dt = self.today cbit = self.custom_feed_url(period * 2, self.start_dt, self.end_dt).lstrip('/') res = logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) feedobj = models.Feed.objects.get(pk=1) self.digestobj, created = dh.get_create_digest_feed( self.get_user(), feedobj, 'daily')
def setUp(self): # create 14 entries over the last 14 days period = 14 today_sat = dt.today( ) # + rd.relativedelta(weekday=rd.SA(-1)) # last sat self.start_dt, self.end_dt = today_sat - timedelta( days=period), today_sat cbit = self.custom_feed_url(period, self.start_dt, self.end_dt).lstrip('/') logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, create_entries=True) self.feedobj = models.Feed.objects.get(pk=1) self.c = Client() self.assertTrue(self.c.login(username="******", password="******"))
def weekly(today=None, day_of_week='sat'): if not today: today = dt.today() x = { 'mon': rd.MO, 'tue': rd.TU, 'wed': rd.WE, 'thu': rd.TH, 'fri': rd.FR, 'sat': rd.SA, 'sun': rd.SU } dow = x[day_of_week] end_period = today + rd.relativedelta(weekday=dow) start_period = end_period - timedelta(days=6) return (start_period, end_period, today)
def create_digest_entries(digestobj, today=None, until=None): "creates all outstanding digest entries, including those for today" if not today: today = dt.today() return create_prev_digest_entries(digestobj, today, until, False)
def daily(today=None): if not today: today = dt.today() return (dt.min(today), dt.max(today), today)
def date_prev_digest(digestobj, today=None): "Returns date of previous digest from today." if not today: today = dt.today() return today - digestobj.negdelta()
def digest_period(digestobj, today=None): "Convenience. Returns the current daily or weekly digest period for today." if not today: today = dt.today() return next(digest_period_generator(digestobj, today))
def review_assignment_state_choices(): return [ (REVIEW_PENDING, 'Pending'), (REVIEW_DECLINED, 'Decline'), (REVIEW_ACCEPTED, 'Accepted'), (REVIEW_WITHDRAWN, 'Cancelled by reviewer'), (REVIEW_CANCELLED, 'Cancelled by editor'), (REVIEW_SUBMITTED, 'Submitted by reviewer'), (REVIEW_PASSED, 'Review accepted by editor'), (REVIEW_REFUSED, 'Review refused by editor'), ] default_due_date = lambda: dt.today() + timedelta(days=30) class ReviewAssignment(models.Model): submission = models.ForeignKey(Submission) reviewer = models.ForeignKey(DjangoUser) # shift to Discussion #reviewer_feedback = models.TextField(blank=True, null=True, help_text="if the reviewer has to cancel or decline their assignment, this is where the reason goes.") # shift to Discussion # editor_feedback = models.TextField(blank=True, null=True, help_text="if the editor has to cancel or withdraw a reviewers assignment, this is where the reason goes.") due_date = models.DateField(blank=True, null=True, default=default_due_date, help_text="when the review is required by.") state = models.CharField(max_length=50, default=REVIEW_PENDING,
def setUp(self): # creates 15 entries over 7 days period, entries = 7, 15 cbit = self.custom_feed_url(entries, dt.today() - timedelta(days=period), dt.today()).lstrip('/') logic.pull_feed("http://localhost:8000/endtimes/%s" % cbit, user=self.get_user(), create_entries=True) self.c = Client()
def test_client_dummy_feed_4(self): c = Client() resp = c.get( self.custom_feed_url(9, dt.today() - timedelta(days=7), dt.today())) self.assertEqual(resp.status_code, 200)