def test_send_updates_work_with_updated_feeds(self): feed = Feed.objects.get(pk=1) last_hour = tz_utcnow() - timedelta(hours=1) Feed.objects.filter(pk=1).update(last_updated=last_hour) Item.objects.create(feed=feed, pubdate=tz_utcnow()) send_updates() self.assertEqual(len(mail.outbox), 1)
def setUp(self): super(FeedUpdatesTasksTest, self).setUp() forced_update = tz_utcnow() - timedelta(hours=1) qs = UserProfile.objects.filter(user__pk=1) qs.update(scheduled_update=forced_update) Subscription.objects.create(user=User.objects.get(pk=1), feed=Feed.objects.get(pk=1), subscribed_at=tz_utcnow())
def test_send_updates_schedule_next_update(self): # add a new item to the feed so send_updates find it and decides # to schedule the next update feed = Feed.objects.get(pk=1) last_hour = tz_utcnow() - timedelta(hours=1) Feed.objects.filter(pk=1).update(last_updated=last_hour) Item.objects.create(feed=feed, pubdate=tz_utcnow()) current = UserProfile.objects.get(user__pk=1).scheduled_update send_updates() next_update = UserProfile.objects.get(user__pk=1).scheduled_update self.assertTrue(next_update > current)
def add_feed(request): if request.method == 'POST': form = FeedForm(request.POST) if form.is_valid(): url = urlparse(form.clean_url()) feed_hash = md5.new(url.netloc) # pylint: disable-msg=E1101 feed_hash.update(url.path) # pylint: disable-msg=E1101 if url.username: feed_hash.update(url.username) feed_hash = feed_hash.hexdigest() try: feed = Feed.objects.get(hash=feed_hash) except Feed.DoesNotExist: feed = form.save(commit=False) feed.hash = feed_hash feed.save() Subscription.objects.create(feed=feed, user=request.user, subscribed_at=tz_utcnow()) # work around bs4.element.NavigableString not being serializable feed.title = unicode(feed.title) send_task("feedmanager.prepare_preview_email", (request.user, feed)) messages.success(request, 'New feed added successfully. Check ' 'your inbox for a preview of this feed!') else: messages.error(request, 'Only RSS and ATOM URLs/feeds are ' 'currently supported.') return HttpResponseRedirect(reverse('feedmanager:feeds'))
def test_preview_lists_up_to_5_newest_items(self): user = User.objects.get(email='*****@*****.**') feed = Feed.objects.get(pk=1) now = tz_utcnow() for counter in xrange(10): pubdate = now + timedelta(hours=counter) title = 'Item #%s' % (counter,) Item.objects.create(feed=feed, pubdate=pubdate, title=title) prepare_preview_email(user, feed) self.assertIn('Item #9', mail.outbox[0].body)
def update_feed(feed, callback=None): new_items = False parsed_feed = feedparser.parse(feed.url, modified=feed.last_updated) if parsed_feed.bozo: error = None exception = parsed_feed.bozo_exception if isinstance(exception, URLError): if exception.reason.errno == -2: error = "ETIMEOUT" elif exception.reason.errno == 110: error = "ESERVICE" elif isinstance(error, SAXParseException): error = "EPARSER" else: error = "EUNKNOWN" for item in parsed_feed.entries: try: Item.objects.get(feed=feed, guid=item.guid) except Item.DoesNotExist: new_items = True try: date = datetime(*(item.published_parsed[0:6]), tzinfo=utc) except AttributeError: date = datetime(*(item.updated_parsed[0:6]), tzinfo=utc) Item.objects.create( feed=feed, pubdate=date, title=item.title, link=item.link, description=item.summary, guid=item.id ) feed.last_checked = tz_utcnow() if new_items: feed.last_updated = tz_utcnow() # reset the error field as we've successfully updated the feed feed.error = None feed.save() if callback: subtask(callback).delay()
def send_updates(): now = tz_utcnow() users = User.objects.filter(userprofile__scheduled_update__lte=now).all() for user in users: feeds = {} profile = UserProfile.objects.get(user=user) update_frequency = timedelta(hours=profile.email_frequency) last_update = profile.scheduled_update - update_frequency updated_feeds = user.feed_set.filter(last_updated__gt=last_update) if not updated_feeds: continue for feed in updated_feeds: items = Item.objects.filter(feed=feed, pubdate__range=[last_update, now]) if not items: continue feeds[feed] = items send_email.delay(user, feeds, callback=reschedule_update.subtask((profile, now)))
def save(self, *args, **kwargs): if not self.scheduled_update: scheduled = tz_utcnow() + timedelta(hours=self.email_frequency) self.scheduled_update = scheduled super(UserProfile, self).save(*args, **kwargs)