コード例 #1
0
 def test_update_collision(self):
     existing_book = {
         "username": "******",
         "work_id": "2",
         "edition_id": "2",
         "bookshelf_id": "1",
     }
     self.db.insert("bookshelves_books", **existing_book)
     assert len(list(self.db.select("bookshelves_books"))) == 2
     Bookshelves.update_work_id(self.source_book['work_id'],
                                existing_book['work_id'])
     assert len(
         list(
             self.db.select(
                 "bookshelves_books",
                 where={
                     "username": "******",
                     "work_id": "2",
                     "edition_id": "2"
                 },
             ))), "failed to update 1 to 2"
     assert not len(
         list(
             self.db.select(
                 "bookshelves_books",
                 where={
                     "username": "******",
                     "work_id": "1",
                     "edition_id": "1"
                 },
             ))), "old work_id 1 present"
コード例 #2
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
コード例 #3
0
    def add(cls, username, work_id, rating, edition_id=None):
        from openlibrary.core.bookshelves import Bookshelves

        oldb = db.get_db()
        work_id = int(work_id)
        data = {'work_id': work_id, 'username': username}

        if rating not in cls.VALID_STAR_RATINGS:
            return None

        # Vote implies user read book; Update reading log status as "Already Read"
        users_read_status_for_work = Bookshelves.get_users_read_status_of_work(
            username, work_id
        )
        if users_read_status_for_work != Bookshelves.PRESET_BOOKSHELVES['Already Read']:
            Bookshelves.add(
                username,
                Bookshelves.PRESET_BOOKSHELVES['Already Read'],
                work_id,
                edition_id=edition_id,
            )

        users_rating_for_work = cls.get_users_rating_for_work(username, work_id)
        if not users_rating_for_work:
            return oldb.insert(
                'ratings',
                username=username,
                work_id=work_id,
                rating=rating,
                edition_id=edition_id,
            )
        else:
            where = "work_id=$work_id AND username=$username"
            return oldb.update('ratings', where=where, rating=rating, vars=data)
コード例 #4
0
ファイル: code.py プロジェクト: mheiman/openlibrary
    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")
コード例 #5
0
 def get_already_read(self, page=1, limit=RESULTS_PER_PAGE):
     return self.process_logged_books(
         Bookshelves.get_users_logged_books(
             self.user.get_username(),
             bookshelf_id=Bookshelves.PRESET_BOOKSHELVES['Already Read'],
             page=page,
             limit=limit))
コード例 #6
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
コード例 #7
0
ファイル: models.py プロジェクト: tanyaguru/openlibrary
 def get_users_read_status(self, username):
     if not username:
         return None
     work_id = self.key.split('/')[2][2:-1]
     status_id = Bookshelves.get_users_read_status_of_work(
         username, work_id)
     return status_id
コード例 #8
0
ファイル: models.py プロジェクト: parallaxisjones/openlibrary
 def get_users_read_status(self, username):
     if not username:
         return None
     work_id = extract_numeric_id_from_olid(self.key)
     status_id = Bookshelves.get_users_read_status_of_work(
         username, work_id)
     return status_id
コード例 #9
0
ファイル: account.py プロジェクト: lukasklein/openlibrary
 def reading_log_counts(self):
     counts = Bookshelves.count_total_books_logged_by_user_per_shelf(
         self.user.get_username())
     return {
         'want-to-read': counts.get(Bookshelves.PRESET_BOOKSHELVES['Want to Read'], 0),
         'currently-reading': counts.get(Bookshelves.PRESET_BOOKSHELVES['Currently Reading'], 0),
         'already-read': counts.get(Bookshelves.PRESET_BOOKSHELVES['Already Read'], 0)
     }
コード例 #10
0
ファイル: models.py プロジェクト: internetarchive/openlibrary
 def get_num_users_by_bookshelf(self):
     work_id = extract_numeric_id_from_olid(self.key)
     num_users_by_bookshelf = Bookshelves.get_num_users_by_bookshelf_by_work_id(work_id)
     return {
         'want-to-read': num_users_by_bookshelf.get(Bookshelves.PRESET_BOOKSHELVES['Want to Read'], 0),
         'currently-reading': num_users_by_bookshelf.get(Bookshelves.PRESET_BOOKSHELVES['Currently Reading'], 0),
         'already-read': num_users_by_bookshelf.get(Bookshelves.PRESET_BOOKSHELVES['Already Read'], 0)
     }
コード例 #11
0
 def reading_log_counts(self):
     counts = Bookshelves.count_total_books_logged_by_user_per_shelf(
         self.user.get_username())
     return {
         'want-to-read': counts.get(Bookshelves.PRESET_BOOKSHELVES['Want to Read'], 0),
         'currently-reading': counts.get(Bookshelves.PRESET_BOOKSHELVES['Currently Reading'], 0),
         'already-read': counts.get(Bookshelves.PRESET_BOOKSHELVES['Already Read'], 0)
     }
コード例 #12
0
ファイル: models.py プロジェクト: ritik-07/openlibrary
 def get_num_users_by_bookshelf(self):
     work_id = extract_numeric_id_from_olid(self.key)
     num_users_by_bookshelf = Bookshelves.get_num_users_by_bookshelf_by_work_id(work_id)
     return {
         'want-to-read': num_users_by_bookshelf.get(Bookshelves.PRESET_BOOKSHELVES['Want to Read'], 0),
         'currently-reading': num_users_by_bookshelf.get(Bookshelves.PRESET_BOOKSHELVES['Currently Reading'], 0),
         'already-read': num_users_by_bookshelf.get(Bookshelves.PRESET_BOOKSHELVES['Already Read'], 0)
     }
コード例 #13
0
 def get_already_read(self, page=1, limit=RESULTS_PER_PAGE):
     work_ids = [
         '/works/OL%sW' % i['work_id']
         for i in Bookshelves.get_users_logged_books(
             self.user.get_username(),
             bookshelf_id=Bookshelves.PRESET_BOOKSHELVES['Already Read'],
             page=page,
             limit=limit)
     ]
     return web.ctx.site.get_many(work_ids)
コード例 #14
0
ファイル: account.py プロジェクト: tonyqui/openlibrary
 def get_want_to_read(self, page=1, limit=100):
     work_ids = [
         '/works/OL%sW' % i['work_id']
         for i in Bookshelves.get_users_logged_books(
             self.user.get_username(),
             bookshelf_id=Bookshelves.PRESET_BOOKSHELVES['Want to Read'],
             page=page,
             limit=limit)
     ]
     return web.ctx.site.get_many(work_ids)
コード例 #15
0
ファイル: models.py プロジェクト: cdrini/openlibrary
    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
コード例 #16
0
ファイル: mybooks.py プロジェクト: khabdrick/openlibrary
 def get_already_read(
     self, page=1, limit=RESULTS_PER_PAGE, sort='created', sort_order='desc'
 ):
     return self.process_logged_books(
         Bookshelves.get_users_logged_books(
             self.user.get_username(),
             bookshelf_id=Bookshelves.PRESET_BOOKSHELVES['Already Read'],
             page=page,
             limit=limit,
             sort=sort + ' ' + sort_order,
         )
     )
コード例 #17
0
def add_read_statuses(username, works):
    work_ids = [
        extract_numeric_id_from_olid(work.key.split('/')[-1]) for work in works
    ]
    results = Bookshelves.get_users_read_status_of_works(username, work_ids)
    results_map = {}
    for result in results:
        results_map[f"OL{result['work_id']}W"] = result['bookshelf_id']
    for work in works:
        work_olid = work.key.split('/')[-1]
        work['readinglog'] = results_map.get(work_olid, None)
    return works
コード例 #18
0
ファイル: account.py プロジェクト: milotype/openlibrary
 def generate_reading_log(self, username):
     books = Bookshelves.get_users_logged_books(username, limit=10000)
     csv = []
     csv.append('Work Id,Edition Id,Bookshelf\n')
     mapping = {1: 'Want to Read', 2: 'Currently Reading', 3: 'Already Read'}
     for book in books:
         row = [
             'OL{}W'.format(book['work_id']),
             'OL{}M'.format(book['edition_id']) if book['edition_id'] else '',
             '{}\n'.format(mapping[book['bookshelf_id']]),
         ]
         csv.append(','.join(row))
     return ''.join(csv)
コード例 #19
0
 def GET(self):
     user = accounts.get_current_user()
     username = user.key.split('/')[-1]
     books = Bookshelves.get_users_logged_books(username, limit=10000)
     csv = []
     csv.append('Work Id,Edition Id,Bookshelf\n')
     mapping = {1:'Want to Read', 2:'Currently Reading', 3:'Already Read'}
     for book in books:
         row = [
             'OL{}W'.format(book['work_id']),
             'OL{}M'.format(book['edition_id']) if book['edition_id'] else '',
             '{}\n'.format(mapping[book['bookshelf_id']])
         ]
         csv.append(','.join(row))
     web.header('Content-Type','text/csv')
     web.header('Content-disposition', 'attachment; filename=OpenLibrary_ReadingLog.csv')
     csv = ''.join(csv)
     return delegate.RawText(csv, content_type="text/csv")
コード例 #20
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
コード例 #21
0
 def test_update_simple(self):
     assert len(list(self.db.select("bookshelves_books"))) == 1
     Bookshelves.update_work_id(self.source_book['work_id'], "2")
コード例 #22
0
ファイル: mybooks.py プロジェクト: khabdrick/openlibrary
def get_read_status(work_key, username):
    work_id = extract_numeric_id_from_olid(work_key.split('/')[-1])
    return Bookshelves.get_users_read_status_of_work(username, work_id)
コード例 #23
0
ファイル: models.py プロジェクト: randomecho/openlibrary
 def get_users_read_status(self, username):
     if not username:
         return None
     work_id = self.key.split('/')[2][2:-1]
     status_id = Bookshelves.get_users_read_status_of_work(username, work_id)
     return status_id
コード例 #24
0
ファイル: account.py プロジェクト: lukasklein/openlibrary
 def get_already_read(self, page=1, limit=100):
     work_ids = ['/works/OL%sW' % i['work_id'] for i in Bookshelves.get_users_logged_books(
         self.user.get_username(), bookshelf_id=Bookshelves.PRESET_BOOKSHELVES['Already Read'],
         page=page, limit=limit)]
     return web.ctx.site.get_many(work_ids)
コード例 #25
0
class export_books(delegate.page):
    path = "/account/export"

    date_format = '%Y-%m-%d %H:%M:%S'

    @require_login
    def GET(self):
        i = web.input(type='')
        filename = ''

        user = accounts.get_current_user()
        username = user.key.split('/')[-1]

        if i.type == 'reading_log':
            data = self.generate_reading_log(username)
            filename = 'OpenLibrary_ReadingLog.csv'
        elif i.type == 'book_notes':
            data = self.generate_book_notes(username)
            filename = 'OpenLibrary_BookNotes.csv'
        elif i.type == 'reviews':
            data = self.generate_reviews(username)
            filename = 'OpenLibrary_Reviews.csv'
        elif i.type == 'lists':
            with elapsed_time("user.get_lists()"):
                lists = user.get_lists(limit=1000)
            with elapsed_time("generate_list_overview()"):
                data = self.generate_list_overview(lists)
            filename = 'Openlibrary_ListOverview.csv'
        elif i.type == 'ratings':
            data = self.generate_star_ratings(username)
            filename = 'OpenLibrary_Ratings.csv'

        web.header('Content-Type', 'text/csv')
        web.header('Content-disposition', f'attachment; filename={filename}')
        return delegate.RawText('' or data, content_type="text/csv")

    def generate_reading_log(self, username: str) -> str:
        from openlibrary.plugins.upstream.models import Work  # Avoid a circular import

        bookshelf_map = {
            1: 'Want to Read',
            2: 'Currently Reading',
            3: 'Already Read'
        }

        def get_subjects(work: Work, subject_type: str) -> str:
            return " | ".join(
                s.title.replace(",", ";")
                for s in work.get_subject_links(subject_type))

        def format_reading_log(book: dict) -> dict:
            """
            Adding, deleting, renaming, or reordering the fields of the dict returned
            below will automatically be reflected in the CSV that is generated.
            """
            work_key = f"/works/OL{book['work_id']}W"
            work: Work = web.ctx.site.get(work_key)
            if not work:
                raise ValueError(f"No Work found for {work_key}.")
            if edition_id := book.get("edition_id") or "":
                edition_id = f"OL{edition_id}M"
            ratings = work.get_rating_stats() or {"average": "", "count": ""}
            ratings_average, ratings_count = ratings.values()
            return {
                "work_id": work_key.split("/")[-1],
                "title": work.title,
                "authors": " | ".join(work.get_author_names()),
                "first_publish_year": work.first_publish_year,
                "edition_id": edition_id,
                "edition_count": work.edition_count,
                "bookshelf":
                bookshelf_map[work.get_users_read_status(username)],
                "my_ratings": work.get_users_rating(username) or "",
                "ratings_average": ratings_average,
                "ratings_count": ratings_count,
                "has_ebook": work.has_ebook(),
                "subjects": get_subjects(work=work, subject_type="subject"),
                "subject_people": get_subjects(work=work,
                                               subject_type="person"),
                "subject_places": get_subjects(work=work,
                                               subject_type="place"),
                "subject_times": get_subjects(work=work, subject_type="time"),
            }

        books = Bookshelves.iterate_users_logged_books(username)
        return csv_string(books, format_reading_log)
コード例 #26
0
ファイル: models.py プロジェクト: internetarchive/openlibrary
 def get_users_read_status(self, username):
     if not username:
         return None
     work_id = extract_numeric_id_from_olid(self.key)
     status_id = Bookshelves.get_users_read_status_of_work(username, work_id)
     return status_id