Example #1
0
    def test_search_with_before_and_filter(self):
        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        to_filter = ['testfeed2']
        unfiltered = [f for f in self._feeds if f not in to_filter]

        num_filtered = len(
            [e for e in events if e.feed['short_name'] in to_filter]
        )

        self.assertTrue(num_filtered > 0)

        es = store.get_events_by_search("changed", to_filter=to_filter)

        self.assertEqual(es.count, num_filtered)
        self.assertEqual(len(es), num_filtered)

        before = es.latest + datetime.timedelta(microseconds=1)

        # add new event

        new_time = datetime.datetime(2012, 4, 24, 0, 0, 0, 0)

        event_dict = events_create_single(self._feeds[2], new_time)
        event_dict['title'] = 'changed to %d' % (num)

        e = Event.from_dict(event_dict)

        store.add_events([e])

        # the same search would now also return the new entry
        es = store.get_events_by_search("changed", to_filter=to_filter)

        self.assertEqual(es.count, num_filtered + 1)

        # with time limit it shouldn't
        es = store.get_events_by_search(
            "changed",
            before=before,
            to_filter=to_filter
        )

        self.assertEqual(es.count, num_filtered)
        self.assertEqual(len(es), num_filtered)

        for _ in range(es.num_pages):
            for e in es.page():
                self.assertTrue(e.occurred != new_time)
                self.assertTrue(e.occurred < before)
                self.assertNotIn(e.feed['short_name'], unfiltered)
Example #2
0
    def test_search_with_after(self):
        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        es = store.get_events_by_search("changed")

        initial_count = len(events)

        self.assertEqual(es.count, initial_count)
        self.assertEqual(len(es), initial_count)

        after = datetime.datetime(2012, 2, 1, 0, 0, 0, 0)

        expected_num = 0

        for e in events:
            if e.occurred > after:
                expected_num += 1

        self.assertTrue(expected_num > 0)

        es = store.get_events_by_search("changed", after=after)

        # start using results to trigger reading of metadata, first page
        p = es.page()

        # add new event
        new_time = datetime.datetime(2012, 4, 24, 0, 0, 0, 0)

        event_dict = events_create_single(self._feeds[0], new_time)
        event_dict['title'] = 'changed to %d' % (num)

        e = Event.from_dict(event_dict)

        store.add_events([e])

        # original search should not contain the new event
        self.assertEqual(len(es), expected_num)

        for _ in range(es.num_pages):
            for e in es.page():
                self.assertTrue(e.occurred > after)

        # new search should include new event
        self.assertEqual(
            len(store.get_events_by_search("changed", after=after)),
            expected_num + 1
        )
Example #3
0
    def test_search_with_mask(self):
        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        to_mask = ['testfeed3', 'testfeed5']

        num_masked = len(
            [e for e in events if e.feed['short_name'] in to_mask]
        )
        num_un_masked = len(events) - num_masked

        self.assertTrue(num_masked > 0)
        self.assertTrue(num_un_masked > 0)

        es = store.get_events_by_search("changed", to_mask=to_mask)

        self.assertEqual(es.count, num_un_masked)

        for _ in range(es.num_pages):
            for e in es.page():
                self.assertNotIn(e.feed['short_name'], to_mask)
Example #4
0
    def test_get_events_by_date_local(self):
        d = datetime.datetime(2012, 11, 24, 0, 0, 0, 0)

        tz = 'America/Toronto'

        es = store.get_events_by_date(d, timezone=tz)

        self.assertTrue(es.count > 0)

        from_store = [e.dict() for e in es]

        expected = []

        for e in self._events:
            new_time = utc_datetime_to_local(e.occurred, pytz.timezone(tz))

            if new_time.date() == d.date():

                new_event_dict = e.dict()
                to_pg_datetime_str(new_event_dict, 'occurred')

                if new_event_dict['related'] is not None:
                    for r in new_event_dict['related']:
                        to_pg_datetime_str(r, 'occurred')

                new_event = Event.from_dict(new_event_dict)  # need a copy
                new_event.localize(tz)
                expected.append(new_event)

        expected.sort(key=lambda x: x.occurred)
        expected.reverse()
        expected = [e.dict() for e in expected]

        for i in range(len(expected)):
            self.assertDictEqual(from_store[i], expected[i])
Example #5
0
    def page(self, cursor=None):

        # move cursor if provided
        if cursor is not None:
            self._cursor = cursor

        # set query cursor
        self._eventquery.set_cursor(self._cursor)

        # set query limit
        self._eventquery.set_limit(self.pagesize)

        # perform query
        with self._pool.connect() as cur:
            cur.execute(self._eventquery.query, self._eventquery.params)

            events = [Event.from_dict(r[0]) for r in cur]

        # if there were at least pagesize events, set up next page
        if len(events) == self.pagesize:
            self._cursor = ByTimeRangeCursor(events[-1].occurred,
                                             events[-1].id)

        # otherwise, indicate there is no next page, and reset internal cursor
        else:
            self._cursor = None

        return Page(events, self._cursor, timezone=self.timezone)
Example #6
0
    def _search_page(self):

        if self._cursor is None:
            # set initial cursor
            self._cursor = BySearchCursor(1)

        with self._index.searcher() as searcher:

            # search!
            hits = searcher.search_page(self._parsed_query,
                                        self._cursor.page,
                                        filter=self._filter_terms,
                                        mask=self._mask_terms,
                                        pagelen=self.pagesize)

            if not hits and self._cursor.page == 1:
                return []
            elif not hits:
                raise InvalidPage

            event_ids = tuple([hit["id"] for hit in hits])

            events = {}

            # get events from db
            with self._pool.connect() as cur:
                cur.execute(self._eventquery.query, (event_ids, ))

                # maintain ordering by score
                for r in cur:
                    e = Event.from_dict(r[0])
                    events[e.id] = e

            return [events[i] for i in event_ids]
Example #7
0
    def test_search_with_filter(self):
        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        to_filter = ['testfeed2']
        unfiltered = [f for f in self._feeds if f not in to_filter]

        num_filtered = len(
            [e for e in events if e.feed['short_name'] in to_filter]
        )

        self.assertTrue(num_filtered > 0)

        es = store.get_events_by_search("changed", to_filter=to_filter)

        self.assertEqual(es.count, num_filtered)
        self.assertEqual(len(es), num_filtered)

        for _ in range(es.num_pages):
            for e in es.page():
                self.assertNotIn(e.feed['short_name'], unfiltered)
Example #8
0
    def test_search_with_before(self):
        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        es = store.get_events_by_search("changed")

        initial_count = len(events)

        self.assertEqual(es.count, initial_count)
        self.assertEqual(len(es), initial_count)

        before = es.latest + datetime.timedelta(microseconds=1)

        # add new event

        new_time = datetime.datetime(2012, 4, 24, 0, 0, 0, 0)

        event_dict = events_create_single(self._feeds[0], new_time)
        event_dict['title'] = 'changed to %d' % (num)

        e = Event.from_dict(event_dict)

        store.add_events([e])

        # the same search would now also return the new entry
        es = store.get_events_by_search("changed")

        self.assertEqual(es.count, initial_count + 1)

        # with time limit it shouldn't
        es = store.get_events_by_search("changed", before=before)

        self.assertEqual(es.count, initial_count)
        self.assertEqual(len(es), initial_count)

        for _ in range(es.num_pages):
            for e in es.page():
                self.assertTrue(e.occurred != new_time)
                self.assertTrue(e.occurred < before)
Example #9
0
    def test_delete_non_existent_events(self):
        e = Event.from_dict(
            events_create_single(
                self._feeds[0],
                datetime.datetime(2012, 1, 12, 0, 0, 0, 0)
            )
        )

        # should be a no-op
        store.remove_events(events=[e])
Example #10
0
    def test_add_event_with_existing_related_event(self):
        related = Event.from_dict(
            events_create_single(
                self._feeds[0],
                datetime.datetime(2012, 1, 12, 0, 0, 0, 0)
            )
        )

        store.add_events([related])

        # remove feed data on related event to match what is retrieved from the
        # store
        related.feed = None

        e = Event.from_dict(
            events_create_single(
                self._feeds[0],
                datetime.datetime(2012, 1, 11, 0, 0, 0, 0)
            )
        )
        e.add_related(related)

        store.add_events([e])

        es = store.get_events_by_ids([e.id])

        self.assertEqual(es.count, 1)

        from_store = es.page().events[0]

        self.assertEqual(len(from_store.related), 1)

        related_dict = related.dict()
        related_dict['feed'] = None

        self.assertEqual(from_store.related[0].dict(), related_dict)

        es = store.get_events_by_ids([related.id])

        related_from_store = es.page().events[0]

        self.assertIsNotNone(related_from_store.feed)
Example #11
0
    def test_update_events_with_nonexistent(self):
        e = Event.from_dict(
            events_create_single(
                self._feeds[0],
                datetime.datetime(2012, 1, 12, 0, 0, 0, 0)
            )
        )

        self.assertRaises(
            MissingEventIDException,
            store.update_events,
            [e]
        )
Example #12
0
    def test_search_with_timezone(self):
        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        tz = 'America/Toronto'

        es = store.get_events_by_search("changed", timezone=tz)

        from_store = list(es)
        from_store.sort(key=lambda x: x.occurred)
        from_store = [e.dict() for e in from_store]

        expected = []

        for e in events:
            new_event_dict = e.dict()
            to_pg_datetime_str(new_event_dict, 'occurred')
            new_event_dict['related'] = None

            new_event = Event.from_dict(new_event_dict)  # need a copy
            new_event.localize(tz)
            expected.append(new_event)

        expected.sort(key=lambda x: x.occurred)
        expected = [e.dict() for e in expected]

        self.assertEqual(len(expected), len(from_store))

        for i in range(len(expected)):
            self.assertDictEqual(from_store[i], expected[i])
Example #13
0
    def test_add_event_bad_id_value(self):
        e = Event.from_dict(
            events_create_single(
                self._feeds[0],
                datetime.datetime(2012, 1, 12, 0, 0, 0, 0)
            )
        )
        e.id = 7

        self.assertRaises(
            psycopg2.Error,
            store.add_events,
            [e]
        )
Example #14
0
    def _add_events(self, dry=False):
        distribution = [(json.dumps(feed), 3) for feed in self._feeds]

        event_dicts = events_create_fake(
            distribution,
            datetime.datetime(2012, 1, 12, 0, 0, 0, 0),
            datetime.datetime(2012, 3, 24, 0, 0, 0, 0)
        )
        event_dicts.reverse()

        events = [Event.from_dict(d) for d in event_dicts]

        store.add_events(events, dry=dry)

        return event_dicts, events
Example #15
0
    def test_delete_event_with_bad_id(self):
        e = Event.from_dict(
            events_create_single(
                self._feeds[0],
                datetime.datetime(2012, 1, 12, 0, 0, 0, 0)
            )
        )

        e.id = 7

        self.assertRaises(
            Exception,
            store.remove_events,
            [e]
        )
Example #16
0
    def __iter__(self):
        # reset query limit
        self._eventquery.set_limit(None)

        with self._pool.connect() as cur:

            # executing as iterable, get all
            cur.execute(self._eventquery.query, self._eventquery.params)

            for r in cur:
                e = Event.from_dict(r[0])

                if self.timezone is not None:
                    e.localize(self.timezone)

                yield e
Example #17
0
    def test_get_all_with_timezone(self):
        event_dicts, events = self._add_events()

        tz = 'America/Toronto'

        es = store.get_events_by_timerange(timezone=tz)

        from_store = []

        # use pages to iterate
        for i in range(1, es.num_pages + 1):
            p = es.page()
            data = list(p)

            if i < es.num_pages:
                self.assertEqual(data[-1].occurred, p.next.occurred)

            from_store += [e.dict() for e in data]

        expected = []

        for e in events:
            new_event_dict = e.dict()
            to_pg_datetime_str(new_event_dict, 'occurred')

            # need to convert related as well
            if new_event_dict['related'] is not None:
                for r in new_event_dict['related']:
                    r['feed'] = None
                    to_pg_datetime_str(r, 'occurred')

            new_event = Event.from_dict(new_event_dict)  # need a copy
            new_event.localize(tz)
            expected.append(new_event)

        expected = [e.dict() for e in expected]

        self.assertEqual(len(expected), len(from_store))

        for i in range(len(expected)):
            self.assertDictEqual(from_store[i], expected[i])
Example #18
0
    def test_update_events_change_title(self):

        event_dicts, events = self._add_events()

        num = 1
        for d in event_dicts:
            d['title'] = 'changed to %d' % (num)
            num += 1

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events)

        es = store.get_events_by_timerange()

        from_store = list(es)

        events_compare(self, event_dicts, from_store)

        es = store.get_events_by_search("changed")

        self.assertEqual(es.count, len(event_dicts))
Example #19
0
    def test_update_events_change_title_dry(self):

        event_dicts, events = self._add_events()

        for i, d in enumerate(event_dicts):
            d['title'] = 'changed to %d' % (i)

        events = [Event.from_dict(d) for d in event_dicts]

        store.update_events(events, dry=True)

        es = store.get_events_by_timerange()

        from_store = list(es)

        for e in from_store:
            if e.title is not None:
                self.assertNotIn('changed', e.title)

        es = store.get_events_by_search("changed")

        self.assertEqual(es.count, 0)
Example #20
0
    def setUpClass(cls):
        TestStoreWithDBBase.setUpClass()

        # add our events
        distribution = [(json.dumps(feed), 30) for feed in cls._feeds]

        event_dicts = events_create_fake(
            distribution,
            datetime.datetime(2012, 1, 12, 0, 0, 0, 0),
            datetime.datetime(2013, 3, 24, 0, 0, 0, 0)
        )

        cls._events = [Event.from_dict(d) for d in event_dicts]
        cls._events.sort(key=lambda x: x.occurred)
        cls._events.reverse()

        store.add_events(cls._events)

        # need to stub out feeds in related events
        for e in cls._events:
            if e.related is not None:
                for r in e.related:
                    r.feed = None