Example #1
0
    def test_update_username(self):
        before_where = {"username": "******"}
        after_where = {"username": "******"}

        assert len(
            list(self.db.select("bookshelves_books", where=before_where))) == 2
        Bookshelves.update_username("@kilgore_trout", "@anonymous")
        assert len(
            list(self.db.select("bookshelves_books", where=before_where))) == 0
        assert len(list(self.db.select("bookshelves_books",
                                       where=after_where))) == 2

        assert len(list(self.db.select("booknotes", where=before_where))) == 1
        Booknotes.update_username("@kilgore_trout", "@anonymous")
        assert len(list(self.db.select("booknotes", where=before_where))) == 0
        assert len(list(self.db.select("booknotes", where=after_where))) == 1

        assert len(list(self.db.select("ratings", where=before_where))) == 1
        Ratings.update_username("@kilgore_trout", "@anonymous")
        assert len(list(self.db.select("ratings", where=before_where))) == 0
        assert len(list(self.db.select("ratings", where=after_where))) == 1

        assert len(list(self.db.select("observations",
                                       where=before_where))) == 1
        Observations.update_username("@kilgore_trout", "@anonymous")
        assert len(list(self.db.select("observations",
                                       where=before_where))) == 0
        assert len(list(self.db.select("observations",
                                       where=after_where))) == 1
Example #2
0
    def main(self, test=False):
        params = web.input(key='', test='')

        # Provide an escape hatch to let POST requests preview
        if test is False and params.test:
            test = True

        summary = {'key': params.key, 'redirect_chain': [], 'resolved_key': None}
        if params.key:
            redirect_chain = Work.get_redirect_chain(params.key)
            summary['redirect_chain'] = [
                {
                    "key": thing.key,
                    "occurrences": {},
                    "updates": {}
                } for thing in redirect_chain
            ]
            summary['resolved_key'] = redirect_chain[-1].key

            for r in summary['redirect_chain']:
                olid = r['key'].split('/')[-1][2:-1]
                new_olid = summary['resolved_key'].split('/')[-1][2:-1]

                # count reading log entries
                r['occurrences']['readinglog'] = len(
                    Bookshelves.get_works_shelves(olid))
                r['occurrences']['ratings'] = len(
                    Ratings.get_all_works_ratings(olid))
                r['occurrences']['booknotes'] = len(
                    Booknotes.get_booknotes_for_work(olid))
                r['occurrences']['observations'] = len(
                    Observations.get_observations_for_work(olid))

                # track updates
                r['updates']['readinglog'] = Bookshelves.update_work_id(
                    olid, new_olid, _test=test
                )
                r['updates']['ratings'] = Ratings.update_work_id(
                    olid, new_olid, _test=test
                )
                r['updates']['booknotes'] = Booknotes.update_work_id(
                    olid, new_olid, _test=test
                )
                r['updates']['observations'] = Observations.update_work_id(
                    olid, new_olid, _test=test
                )

        return delegate.RawText(
            json.dumps(summary), content_type="application/json")
Example #3
0
    def test_delete_all_by_username(self):
        assert len(list(self.db.select("bookshelves_books"))) == 3
        Bookshelves.delete_all_by_username("@kilgore_trout")
        assert len(list(self.db.select("bookshelves_books"))) == 1

        assert len(list(self.db.select("booknotes"))) == 2
        Booknotes.delete_all_by_username('@kilgore_trout')
        assert len(list(self.db.select("booknotes"))) == 1

        assert len(list(self.db.select("ratings"))) == 2
        Ratings.delete_all_by_username("@kilgore_trout")
        assert len(list(self.db.select("ratings"))) == 1

        assert len(list(self.db.select("observations"))) == 2
        Observations.delete_all_by_username("@kilgore_trout")
        assert len(list(self.db.select("observations"))) == 1
Example #4
0
 def has_book_note(self, username, edition_olid):
     if not username:
         return False
     work_id = extract_numeric_id_from_olid(self.key)
     edition_id = extract_numeric_id_from_olid(edition_olid)
     return (len(
         Booknotes.get_patron_booknote(
             username, work_id, edition_id=edition_id)) > 0)
Example #5
0
 def get_users_notes(self, username, edition_olid=None):
     if not username:
         return None
     work_id = extract_numeric_id_from_olid(self.key)
     edition_id = extract_numeric_id_from_olid(
         edition_olid) if edition_olid else -1
     return Booknotes.get_patron_booknote(username,
                                          work_id,
                                          edition_id=edition_id)
Example #6
0
 def test_no_allow_delete_on_conflict(self):
     rows = [
         {"username": "******", "work_id": 1, "edition_id": 1, "notes": "Jimmeny"},
         {"username": "******", "work_id": 2, "edition_id": 1, "notes": "Cricket"},
     ]
     self.db.multiple_insert("booknotes", rows)
     resp = Booknotes.update_work_id("1", "2")
     assert resp == {'rows_changed': 0, 'rows_deleted': 0, 'failed_deletes': 1}
     assert [dict(row) for row in self.db.select("booknotes")] == rows
Example #7
0
    def resolve_redirect_chain(cls,
                               work_key: str,
                               test: bool = False) -> dict[str, Any]:
        summary: dict[str, Any] = {
            'key': work_key,
            'redirect_chain': [],
            'resolved_key': None,
        }
        redirect_chain = cls.get_redirect_chain(work_key)
        summary['redirect_chain'] = [{
            "key": thing.key,
            "occurrences": {},
            "updates": {}
        } for thing in redirect_chain]
        summary['resolved_key'] = redirect_chain[-1].key

        for r in summary['redirect_chain']:
            olid = r['key'].split('/')[-1][2:-1]  # 'OL1234x' --> '1234'
            new_olid = summary['resolved_key'].split('/')[-1][2:-1]

            # count reading log entries
            r['occurrences']['readinglog'] = len(
                Bookshelves.get_works_shelves(olid))
            r['occurrences']['ratings'] = len(
                Ratings.get_all_works_ratings(olid))
            r['occurrences']['booknotes'] = len(
                Booknotes.get_booknotes_for_work(olid))
            r['occurrences']['observations'] = len(
                Observations.get_observations_for_work(olid))

            # track updates
            r['updates']['readinglog'] = Bookshelves.update_work_id(olid,
                                                                    new_olid,
                                                                    _test=test)
            r['updates']['ratings'] = Ratings.update_work_id(olid,
                                                             new_olid,
                                                             _test=test)
            r['updates']['booknotes'] = Booknotes.update_work_id(olid,
                                                                 new_olid,
                                                                 _test=test)
            r['updates']['observations'] = Observations.update_work_id(
                olid, new_olid, _test=test)
        return summary
Example #8
0
    def generate_book_notes(self, username: str) -> str:
        def format_booknote(booknote: Mapping) -> dict:
            escaped_note = booknote['notes'].replace('"', '""')
            return {
                "work_id": f"OL{booknote['work_id']}W",
                "edition_id": f"OL{booknote['edition_id']}M",
                "note": f'"{escaped_note}"',
                "created_on": booknote['created'].strftime(self.date_format),
            }

        return csv_string(Booknotes.select_all_by_username(username),
                          format_booknote)
Example #9
0
    def get_notes(self, limit=RESULTS_PER_PAGE, page=1):
        notes = Booknotes.get_notes_grouped_by_work(
            self.username, limit=limit, page=page
        )

        for entry in notes:
            entry['work_key'] = f"/works/OL{entry['work_id']}W"
            entry['work'] = self._get_work(entry['work_key'])
            entry['work_details'] = self._get_work_details(entry['work'])
            entry['notes'] = {i['edition_id']: i['notes'] for i in entry['notes']}
            entry['editions'] = {
                k: web.ctx.site.get(f'/books/OL{k}M')
                for k in entry['notes']
                if k != Booknotes.NULL_EDITION_VALUE
            }
        return notes
Example #10
0
    def generate_book_notes(self, username):
        csv = []
        csv.append('Work ID,Edition ID,Note,Created On')
        notes = Booknotes.select_all_by_username(username)

        for note in notes:
            escaped_note = note['notes'].replace('"', '""')
            row = [
                f"OL{note['work_id']}W",
                f"OL{note['edition_id']}M",
                f'"{escaped_note}"',
                note['created'].strftime(self.date_format)
            ]
            csv.append(','.join(row))

        return '\n'.join(csv)
Example #11
0
    def anonymize(self, test=False):
        # Generate new unique username for patron:
        # Note: Cannot test get_activation_link() locally
        uuid = (self.get_activation_link()['code']
                if self.get_activation_link() else generate_uuid())
        new_username = f'anonymous-{uuid}'
        results = {'new_username': new_username}

        # Delete all of the patron's book notes:
        results['booknotes_count'] = Booknotes.delete_all_by_username(
            self.username, _test=test)

        # Anonymize patron's username in OL DB tables:
        results['ratings_count'] = Ratings.update_username(self.username,
                                                           new_username,
                                                           _test=test)
        results['observations_count'] = Observations.update_username(
            self.username, new_username, _test=test)
        results['bookshelves_count'] = Bookshelves.update_username(
            self.username, new_username, _test=test)

        if not test:
            patron = self.get_user()
            email = self.email
            username = self.username

            # Remove patron from all usergroups:
            for grp in patron.usergroups:
                grp.remove_user(patron.key)

            # Set preferences to default:
            patron.save_preferences({'updates': 'no', 'public_readlog': 'no'})

            # Clear patron's profile page:
            data = {'key': patron.key, 'type': '/type/delete'}
            patron.set_data(data)

            # Remove account information from store:
            del web.ctx.site.store[f'account/{username}']
            del web.ctx.site.store[f'account/{username}/verify']
            del web.ctx.site.store[f'account/{username}/password']
            del web.ctx.site.store[f'account-email/{email}']

        return results
Example #12
0
 def get_counts(cls, username):
     return {
         'notes': Booknotes.count_works_with_notes_by_user(username),
         'observations': Observations.count_distinct_observations(username),
     }
Example #13
0
 def get_users_notes(self, username):
     if not username:
         return None
     work_id = extract_numeric_id_from_olid(self.key)
     return Booknotes.get_patron_booknote(username, work_id)