Exemple #1
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)
Exemple #2
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)
 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
 def get_rating_stats(self):
     work_id = extract_numeric_id_from_olid(self.key)
     rating_stats = Ratings.get_rating_stats(work_id)
     if rating_stats and rating_stats['num_ratings'] > 0:
         return {
             'avg_rating': round(rating_stats['avg_rating'], 2),
             'num_ratings': rating_stats['num_ratings']
         }
Exemple #5
0
 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)
     }
 def get_rating_stats(self):
     work_id = extract_numeric_id_from_olid(self.key)
     rating_stats = Ratings.get_rating_stats(work_id)
     if rating_stats and rating_stats['num_ratings'] > 0:
         return {
         'avg_rating': round(rating_stats['avg_rating'],2),
         'num_ratings': rating_stats['num_ratings']
         }
 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)
     }
Exemple #8
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
Exemple #9
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
Exemple #10
0
    def POST(self, work_id):
        """Registers new ratings for this work"""
        user = accounts.get_current_user()
        i = web.input(
            edition_id=None,
            rating=None,
            redir=False,
            redir_url=None,
            page=None,
            ajax=False,
        )
        key = (i.redir_url if i.redir_url else
               i.edition_id if i.edition_id else ('/works/OL%sW' % work_id))
        edition_id = (int(extract_numeric_id_from_olid(i.edition_id))
                      if i.edition_id else None)

        if not user:
            raise web.seeother('/account/login?redirect=%s' % key)

        username = user.key.split('/')[2]

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

        if i.rating is None:
            models.Ratings.remove(username, work_id)
            r = response('removed rating')

        else:
            try:
                rating = int(i.rating)
                if rating not in models.Ratings.VALID_STAR_RATINGS:
                    raise ValueError
            except ValueError:
                return response('invalid rating', status="error")

            models.Ratings.add(username=username,
                               work_id=work_id,
                               rating=rating,
                               edition_id=edition_id)
            r = response('rating added')

        if i.redir and not i.ajax:
            p = h.safeint(i.page, 1)
            query_params = f'?page={p}' if p > 1 else ''
            if i.page:
                raise web.seeother(f'{key}{query_params}')

            raise web.seeother(key)
        return r
Exemple #11
0
    def POST(self, work_id):
        """
        Add a note to a work (or a work and an edition)
        GET params:
        - edition_id str (optional)
        - redir bool: if patron not logged in, redirect back to page after login

        :param str work_id: e.g. OL123W
        :rtype: json
        :return: the note
        """
        user = accounts.get_current_user()
        i = web.input(notes=None, edition_id=None, redir=None)
        edition_id = int(
            extract_numeric_id_from_olid(i.edition_id)) if i.edition_id else -1

        if not user:
            raise web.seeother('/account/login?redirect=/works/%s' % work_id)

        username = user.key.split('/')[2]

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

        if i.notes is None:
            Booknotes.remove(username, work_id, edition_id=edition_id)
            return response('removed note')

        Booknotes.add(
            username=username,
            work_id=work_id,
            notes=i.notes,
            edition_id=edition_id
        )

        if i.redir:
            raise web.seeother("/works/%s" % work_id)

        return response('note added')
Exemple #12
0
    def POST(self, work_id):
        """Registers new ratings for this work"""
        user = accounts.get_current_user()
        i = web.input(edition_id=None, rating=None, redir=False)
        key = i.edition_id if i.edition_id else ('/works/OL%sW' % work_id)
        edition_id = int(extract_numeric_id_from_olid(
            i.edition_id)) if i.edition_id else None

        if not user:
            raise web.seeother('/account/login?redirect=%s' % key)

        username = user.key.split('/')[2]

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

        if i.rating is None:
            models.Ratings.remove(username, work_id)
            r = response('removed rating')

        else:
            try:
                rating = int(i.rating)
                if rating not in models.Ratings.VALID_STAR_RATINGS:
                    raise ValueError
            except ValueError:
                return response('invalid rating', status="error")

            models.Ratings.add(username=username,
                               work_id=work_id,
                               rating=rating,
                               edition_id=edition_id)
            r = response('rating added')

        if i.redir:
            raise web.seeother(key)
        return r
Exemple #13
0
    def POST(self, work_id):
        """Registers new ratings for this work"""
        user = accounts.get_current_user()
        i = web.input(edition_id=None, rating=None, redir=False)
        key = i.edition_id if i.edition_id else ('/works/OL%sW' % work_id)
        edition_id = int(extract_numeric_id_from_olid(i.edition_id)) if i.edition_id else None

        if not user:
            raise web.seeother('/account/login?redirect=%s' % key)

        username = user.key.split('/')[2]

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

        if i.rating is None:
            models.Ratings.remove(username, work_id)
            r = response('removed rating')

        else:
            try:
                rating = int(i.rating)
                if rating not in models.Ratings.VALID_STAR_RATINGS:
                    raise ValueError
            except ValueError:
                return response('invalid rating', status="error")

            models.Ratings.add(
                username=username, work_id=work_id,
                rating=rating, edition_id=edition_id)
            r = response('rating added')

        if i.redir:
            raise web.seeother(key)
        return r
Exemple #14
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)
Exemple #15
0
 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
Exemple #16
0
 def get_users_rating(self, username):
     if not username:
         return None
     work_id = extract_numeric_id_from_olid(self.key)
     rating = Ratings.get_users_rating_for_work(username, work_id)
     return rating
Exemple #17
0
 def get_users_rating(self, username):
     if not username:
         return None
     work_id = extract_numeric_id_from_olid(self.key)
     rating = Ratings.get_users_rating_for_work(username, work_id)
     return rating
Exemple #18
0
def test_extract_numeric_id_from_olid():
    assert extract_numeric_id_from_olid('/works/OL123W') == '123'
    assert extract_numeric_id_from_olid('OL123W') == '123'
Exemple #19
0
def get_observation_metrics(work_olid):
    """
    Returns a dictionary of observation statistics for the given work.  Statistics
    will be used to populate a book's "Reader Observations" component.

    Dictionary will have the following structure:
    {
        'work_id': 12345,
        'total_respondents': 100,
        'observations': [
            {
                'label': 'pace',
                'description': 'What is the pace of this book?',
                'multi_choice': False,
                'total_respondents_for_type': 10,
                'values': [
                    {
                        'value': 'fast',
                        'count': 6
                    },
                    {
                        'value': 'medium',
                        'count': 4
                    }
                ]
            }
            ... Other observations omitted for brevity ... 
        ]
    }

    If no observations were made for a specific type, that type will be excluded from
    the 'observations' list.  Items in the 'observations.values' list will be
    ordered from greatest count to least.

    return: A dictionary of observation statistics for a work.
    """
    work_id = extract_numeric_id_from_olid(work_olid)
    total_respondents = Observations.total_unique_respondents(work_id)

    metrics = {}
    metrics['work_id'] = work_id
    metrics['total_respondents'] = total_respondents
    metrics['observations'] = []

    if total_respondents > 0:
        respondents_per_type_dict = Observations.count_unique_respondents_by_type(
            work_id)
        observation_totals = Observations.count_observations(work_id)

        current_type_id = observation_totals[0]['type_id']
        observation_item = next((o for o in OBSERVATIONS['observations']
                                 if current_type_id == o['id']))

        current_observation = {
            'label':
            observation_item['label'],
            'description':
            observation_item['description'],
            'multi_choice':
            observation_item['multi_choice'],
            'total_respondents_for_type':
            respondents_per_type_dict[current_type_id],
            'values': []
        }

        for i in observation_totals:
            if i['type_id'] != current_type_id:
                metrics['observations'].append(current_observation)
                current_type_id = i['type_id']
                observation_item = next((o
                                         for o in OBSERVATIONS['observations']
                                         if current_type_id == o['id']))
                current_observation = {
                    'label':
                    observation_item['label'],
                    'description':
                    observation_item['description'],
                    'multi_choice':
                    observation_item['multi_choice'],
                    'total_respondents_for_type':
                    respondents_per_type_dict[current_type_id],
                    'values': []
                }
            current_observation['values'].append({
                'value':
                next((v['name'] for v in observation_item['values']
                      if v['id'] == i['value_id'])),
                'count':
                i['total']
            })

        metrics['observations'].append(current_observation)
    return metrics
Exemple #20
0
def test_extract_numeric_id_from_olid():
    assert extract_numeric_id_from_olid('/works/OL123W') == '123'
    assert extract_numeric_id_from_olid('OL123W') == '123'
Exemple #21
0
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)