-
Notifications
You must be signed in to change notification settings - Fork 25
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
statistics: add tests, query and csv download button for librarian statistics #2661
Conversation
b6e2411
to
aaf9d61
Compare
1f7b295
to
81a3fde
Compare
c879d8c
to
8f03db5
Compare
|
rero_ils/modules/stats/cli.py
Outdated
"""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 |
There was a problem hiding this comment.
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.
rero_ils/modules/stats/cli.py
Outdated
n += 1 | ||
else: | ||
click.secho(f'ERROR: not a valid month') | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use a click.Abort
here: https://click.palletsprojects.com/en/7.x/api/#click.Abort
rero_ils/modules/stats/cli.py
Outdated
if n in range(1, 13): | ||
n += 1 | ||
else: | ||
click.secho(f'ERROR: not a valid month') |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.""" |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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"> |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is responsive.
rero_ils/modules/stats/views.py
Outdated
@blueprint.route('/librarian/<record_pid>/csv') | ||
@check_logged_as_librarian | ||
def stats_librarian_queries(record_pid): | ||
"""Download specific statistic query into csv file.""" |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
…atistics Co-Authored-by: Valeria Granata <[email protected]>
8f03db5
to
8f8a916
Compare
There was a problem hiding this 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
rero_ils/modules/stats/api.py
Outdated
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"]: |
There was a problem hiding this comment.
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.
rero_ils/modules/stats/api.py
Outdated
for library in current_librarian.get('libraries', []): | ||
library_pids.add(extracted_data_from_ref(library)) |
There was a problem hiding this comment.
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', [])])
rero_ils/modules/stats/api.py
Outdated
organisation_libraries_pid = LibrariesSearch()\ | ||
.filter('term', | ||
organisation__pid=patron_data.organisation.pid)\ | ||
if 'system_librarian' in current_librarian["roles"]: |
There was a problem hiding this comment.
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
rero_ils/modules/stats/api.py
Outdated
.filter( | ||
'term', | ||
organisation__pid=patron_organisation.pid)\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
COSMETIC : single line ?
rero_ils/modules/stats/api.py
Outdated
for s in libraries_search: | ||
library_pids.add(s.pid) |
There was a problem hiding this comment.
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])
if 'type' in record['metadata'] and\ | ||
record['metadata']['type'] == 'librarian': |
There was a problem hiding this comment.
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:
headers = [key[0].upper()+key[1:].replace('_', ' ') | ||
for key in self.ordered_keys] |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.
rero_ils/modules/stats/views.py
Outdated
values = sorted( | ||
dictionary, | ||
key=lambda v: v['library']['name'] | ||
) | ||
return values |
There was a problem hiding this comment.
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(....)
… query Co-Authored-by: Valeria Granata <[email protected]>
8f8a916
to
bb03aed
Compare
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?
Code review check list