示例#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
示例#2
0
    def get_users_observations(self, username):
        if not username:
            return None
        work_id = extract_numeric_id_from_olid(self.key)
        raw_observations = Observations.get_patron_observations(username, work_id)
        formatted_observations = defaultdict(list)

        for r in raw_observations:
            kv_pair = Observations.get_key_value_pair(r['type'], r['value'])
            formatted_observations[kv_pair.key].append(kv_pair.value)

        return formatted_observations
示例#3
0
    def DELETE(self, work_id):
        user = accounts.get_current_user()
        username = user.key.split('/')[2]

        if not user:
            raise web.seeother('/account/login')

        Observations.remove_observations(username, work_id)

        def response(msg, status="success"):
            return delegate.RawText(json.dumps({status: msg}),
                                    content_type="application/json")

        return response('Observations removed')
示例#4
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")
示例#5
0
    def POST(self, work_id):
        user = accounts.get_current_user()

        if not user:
            raise web.seeother('/account/login')

        data = json.loads(web.data())

        Observations.persist_observation(data['username'], work_id,
                                         data['observation'], data['action'])

        def response(msg, status="success"):
            return delegate.RawText(json.dumps({status: msg}),
                                    content_type="application/json")

        return response('Observations added')
示例#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
    def GET(self, work_id):
        user = accounts.get_current_user()

        if not user:
            raise web.seeother('/account/login')

        username = user.key.split('/')[2]
        existing_records = Observations.get_patron_observations(
            username, work_id)

        patron_observations = defaultdict(list)

        for r in existing_records:
            kv_pair = Observations.get_key_value_pair(r['type'], r['value'])
            patron_observations[kv_pair.key].append(kv_pair.value)

        return delegate.RawText(json.dumps(patron_observations),
                                content_type="application/json")
示例#8
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
示例#9
0
    def generate_reviews(self, username: str) -> str:
        def format_observation(observation: Mapping) -> dict:
            return {
                "work_id": f"OL{observation['work_id']}W",
                "review_category": f'"{observation["observation_type"]}"',
                "review_value": f'"{observation["observation_value"]}"',
                "created_on":
                observation['created'].strftime(self.date_format),
            }

        observations = Observations.select_all_by_username(username)
        return csv_string(observations, format_observation)
示例#10
0
    def get_observations(self, limit=RESULTS_PER_PAGE, page=1):
        observations = Observations.get_observations_grouped_by_work(
            self.username, limit=limit, page=page)

        for entry in observations:
            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'])
            ids = {}
            for item in entry['observations']:
                ids[item['observation_type']] = item['observation_values']
            entry['observations'] = convert_observation_ids(ids)
        return observations
示例#11
0
    def generate_reviews(self, username):
        csv = []
        csv.append('Work ID,Review Category,Review Value,Created On')
        observations = Observations.select_all_by_username(username)

        for o in observations:
            row = [
                f"OL{o['work_id']}W",
                f'"{o["observation_type"]}"',
                f'"{o["observation_value"]}"',
                o['created'].strftime(self.date_format)
            ]
            csv.append(','.join(row))

        return '\n'.join(csv)
示例#12
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
示例#13
0
 def get_counts(cls, username):
     return {
         'notes': Booknotes.count_works_with_notes_by_user(username),
         'observations': Observations.count_distinct_observations(username),
     }