Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

statistics: add tests, query and csv download button for librarian statistics #2661

Merged

Conversation

vgranata
Copy link
Contributor

@vgranata vgranata commented Jan 27, 2022

Co-Authored-by: Valeria Granata [email protected]

Why are you opening this PR?

https://tree.taiga.io/project/rero21-reroils/task/2371
Solves issue: #2697
Solves issue: #2675

How to test?

  • What command should I have to run to test your PR?
  • What should I test through the UI?

Code review check list

  • Commit message template compliance.
  • Commit message without typos.
  • File names.
  • Functions names.
  • Functions docstrings.
  • Unnecessary commited files?
  • Cypress tests successful?

@vgranata vgranata marked this pull request as ready for review January 27, 2022 16:26
@vgranata vgranata requested a review from jma January 27, 2022 16:26
rero_ils/modules/stats/api.py Outdated Show resolved Hide resolved
rero_ils/modules/stats/api.py Outdated Show resolved Hide resolved
rero_ils/modules/stats/permissions.py Outdated Show resolved Hide resolved
@vgranata vgranata changed the title statistics: add tests for librarian statistics statistics: librarian statistics Feb 15, 2022
@vgranata vgranata marked this pull request as draft February 16, 2022 07:40
@vgranata vgranata force-pushed the grv-2371-tests-statistics-librarian branch 2 times, most recently from b6e2411 to aaf9d61 Compare February 16, 2022 08:12
@vgranata vgranata changed the title statistics: librarian statistics statistics: add tests, query and csv download button for librarian statistics Feb 16, 2022
@PascalRepond PascalRepond added f: permissions Concerns the rights management and removed statistics labels Feb 18, 2022
@vgranata vgranata force-pushed the grv-2371-tests-statistics-librarian branch from 1f7b295 to 81a3fde Compare March 1, 2022 16:38
@github-actions github-actions bot added the f: statistics Related to the usage statistics either for pricing or for the libaries reports label Mar 1, 2022
@vgranata vgranata force-pushed the grv-2371-tests-statistics-librarian branch 2 times, most recently from c879d8c to 8f03db5 Compare March 10, 2022 14:49
@vgranata vgranata marked this pull request as ready for review March 10, 2022 14:50
@vgranata vgranata requested a review from jma March 10, 2022 14:51
@pronguen
Copy link
Contributor

pronguen commented Mar 17, 2022

  • I gave the "librarian" role to a patron (pid:46008). Then I cannot access the professional interface as this patron. This is working on the production.
    • Observed with Firefox 98.0.1 (64-bit). It works on Chrome.

"""Extract the stats librarian for one year and store them in db.

:param year: year of statistics
:param n: month up to which the statistics are calculated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n is not a good variable name. Please use something more explicit.

n += 1
else:
click.secho(f'ERROR: not a valid month')
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if n in range(1, 13):
n += 1
else:
click.secho(f'ERROR: not a valid month')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can display the message in red: click.secho(f'ERROR: not a valid month', fg='red')

def filter_stat_by_librarian(record):
"""Filter data for libraries of specific librarian/system_librarian.

:param record: Record to check.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do yo mean by Record? I think this can be more explicit.

@@ -28,38 +29,97 @@
class StatCSVSerializer(CSVSerializer):
"""Mixin serializing records as JSON."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this docstring?

</tr>
<tr>
<td class="col-xs-12">
<a href="{{url_for('invenio_records_ui.stats', pid_value=rec._source.pid)}}">View statistics</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"View statistics" should be translated.

</tr>
<tr>
<td>Loans of the transaction library by item location
<a class="btn btn-outline-secondary float-right" href="/stats/librarian/{{rec._source.pid}}/csv?query_id=1" role="button"><i class="fa fa-download"></i></a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

href can be replaced by an url_for.

{%- endfor %}
</div>
{% elif type=="librarian" %}
<table class="table table-hover border">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this table be responsive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is responsive.

@blueprint.route('/librarian/<record_pid>/csv')
@check_logged_as_librarian
def stats_librarian_queries(record_pid):
"""Download specific statistic query into csv file."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can yo describe the parameter and the return value?

"""Download specific statistic query into csv file."""
queries = {'1': 'loans_of_transaction_library_by_item_location'}
query_id = request.args.get('query_id', None)
if query_id not in queries:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that only 1 is allowed for the query_id parameter. If it is true this seems overkill.

Copy link
Contributor Author

@vgranata vgranata Mar 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is done to foresee the implementation of other queries in the future. Should I change it ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the usage url should be "/librarian/<record_pid>/csv?query_id=1" ?
Why not use exact term as query_id value ? ("/librarian/<record_pid>/csv?query_id= loans_of_transaction_library_by_item_location")

my option is that using "1" is less human relevant than a string argument " loans_of_transaction_library_by_item_location" when you read/write the URL.

@vgranata vgranata requested review from BadrAly and Garfield-fr March 21, 2022 08:51
@vgranata vgranata force-pushed the grv-2371-tests-statistics-librarian branch from 8f03db5 to 8f8a916 Compare March 21, 2022 15:13
@vgranata vgranata requested a review from zannkukai March 23, 2022 10:58
Copy link
Contributor

@zannkukai zannkukai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code seems correct. Great job 👏 . I just added some cosmetics comments/personnal reflexions

if 'librarian' in patron_data.roles:
for library_pid in patron_data.libraries:
library_pids.add(library_pid.pid)
if 'librarian' in current_librarian["roles"]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use Patron.ROLE_LIBRARIAN instead of "librarian" string. This isn't a wrong implementation, just a good practice in my opinion.

Comment on lines 345 to 346
for library in current_librarian.get('libraries', []):
library_pids.add(extracted_data_from_ref(library))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COSMETCI : better pythonic way

library_pids = set([extracted_data_from_ref(lib) for lib in current_librarian.get('libraries', [])])

organisation_libraries_pid = LibrariesSearch()\
.filter('term',
organisation__pid=patron_data.organisation.pid)\
if 'system_librarian' in current_librarian["roles"]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to use Patron.ROLE_SYSTEM_LIBRARIAN

Comment on lines 352 to 354
.filter(
'term',
organisation__pid=patron_organisation.pid)\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COSMETIC : single line ?

Comment on lines 356 to 357
for s in libraries_search:
library_pids.add(s.pid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

library_pids = library_pids.union(set([s.pid for s in libraries_search]))

or (to be tested)

library_pids = library_pids | set([s.pid for s in libraries_search])

Comment on lines 52 to 53
if 'type' in record['metadata'] and\
record['metadata']['type'] == 'librarian':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if record['metadata'].get('type') == Patron.ROLE_LIBRARIAN:

Comment on lines 55 to 56
headers = [key[0].upper()+key[1:].replace('_', ' ')
for key in self.ordered_keys]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use capitalize() --> headers = [key.capitalize().replace('_', '') for key in self.ordered_keys]

:return: response object, the csv file
"""
queries = {'1': 'loans_of_transaction_library_by_item_location'}
query_id = request.args.get('query_id', None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add an USAGE section into the function doc_string to explain query_id query string argument.

"""Download specific statistic query into csv file."""
queries = {'1': 'loans_of_transaction_library_by_item_location'}
query_id = request.args.get('query_id', None)
if query_id not in queries:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the usage url should be "/librarian/<record_pid>/csv?query_id=1" ?
Why not use exact term as query_id value ? ("/librarian/<record_pid>/csv?query_id= loans_of_transaction_library_by_item_location")

my option is that using "1" is less human relevant than a string argument " loans_of_transaction_library_by_item_location" when you read/write the URL.

Comment on lines 193 to 197
values = sorted(
dictionary,
key=lambda v: v['library']['name']
)
return values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge into single instruction : return sorted(....)

@vgranata vgranata force-pushed the grv-2371-tests-statistics-librarian branch from 8f8a916 to bb03aed Compare March 24, 2022 15:02
@PascalRepond PascalRepond merged commit 9956ab2 into rero:staging Mar 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: permissions Concerns the rights management f: statistics Related to the usage statistics either for pricing or for the libaries reports
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants