0001-api-new-formdef-popularity-count-method-47889.patch
tests/test_api.py | ||
---|---|---|
420 | 420 |
assert resp1.json['err'] == 0 |
421 | 421 |
assert len(resp1.json['data']) == 0 |
422 | 422 | |
423 |
formdef.data_class().wipe() |
|
424 | ||
425 |
# a draft |
|
426 |
formdata = formdef.data_class()() |
|
427 |
formdata.data = {} |
|
428 |
formdata.just_created() |
|
429 |
formdata.status = 'draft' |
|
430 |
formdata.store() |
|
431 | ||
432 |
other_formdef = FormDef() |
|
433 |
other_formdef.name = 'test 2' |
|
434 |
other_formdef.fields = [] |
|
435 |
other_formdef.store() |
|
436 |
other_formdata = other_formdef.data_class()() |
|
437 |
other_formdata.data = {} |
|
438 |
other_formdata.just_created() |
|
439 |
other_formdata.store() |
|
440 | ||
441 |
# formdata created: |
|
442 |
# - 1 day ago (=3*4) |
|
443 |
# - 7 days ago (=2*2) |
|
444 |
# - 29 days ago (=1*1) |
|
445 |
# - 31 days ago (=0) |
|
446 |
for days in [1, 1, 1, 7, 7, 29, 31]: |
|
447 |
formdata = formdef.data_class()() |
|
448 |
formdata.data = {} |
|
449 |
formdata.just_created() |
|
450 |
formdata.receipt_time = (datetime.datetime.now() - datetime.timedelta(days=days)).timetuple() |
|
451 |
formdata.store() |
|
452 | ||
453 |
resp = get_app(pub).get(sign_uri('/api/formdefs/?include-count=on')) |
|
454 |
if not pub.is_using_postgresql(): |
|
455 |
assert resp.json['data'][0]['count'] == 8 |
|
456 |
else: |
|
457 |
# 3*4 + 2*2 + 1*1 |
|
458 |
assert resp.json['data'][0]['count'] == 17 |
|
459 | ||
423 | 460 | |
424 | 461 |
def test_limited_formdef_list(pub, local_user): |
425 | 462 |
Role.wipe() |
wcs/api.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU General Public License |
15 | 15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import datetime |
|
17 | 18 |
import json |
18 | 19 |
import re |
19 | 20 |
import time |
20 | 21 | |
21 | 22 |
from quixote import get_request, get_publisher, get_response, get_session |
22 |
from quixote.errors import MethodNotAllowedError, QueryError
|
|
23 |
from quixote.errors import MethodNotAllowedError |
|
23 | 24 |
from quixote.directory import Directory |
24 | 25 | |
25 | 26 |
from django.utils.encoding import force_text |
... | ... | |
573 | 574 |
if include_count: |
574 | 575 |
# we include the count of submitted forms so it's possible to sort |
575 | 576 |
# them by "popularity" |
576 |
formdict['count'] = formdef.data_class().count() |
|
577 |
if get_publisher().is_using_postgresql(): |
|
578 |
from wcs import sql |
|
579 |
# 4 * number of submitted forms of last 2 days |
|
580 |
# + 2 * number of submitted forms of last 8 days |
|
581 |
# + 1 * number of submitted forms of last 30 days |
|
582 |
# exclude drafts |
|
583 |
criterias = [Equal('formdef_id', formdef.id), NotEqual('status', 'draft')] |
|
584 |
d_now = datetime.datetime.now() |
|
585 |
count = 4 * sql.get_period_total( |
|
586 |
period_start=d_now - datetime.timedelta(days=2), include_start=True, |
|
587 |
criterias=criterias) |
|
588 |
count += 2 * sql.get_period_total( |
|
589 |
period_start=d_now - datetime.timedelta(days=8), include_start=True, |
|
590 |
period_end=d_now - datetime.timedelta(days=2), include_end=False, |
|
591 |
criterias=criterias) |
|
592 |
count += sql.get_period_total( |
|
593 |
period_start=d_now - datetime.timedelta(days=30), include_start=True, |
|
594 |
period_end=d_now - datetime.timedelta(days=8), include_end=False, |
|
595 |
criterias=criterias) |
|
596 |
else: |
|
597 |
# naive count |
|
598 |
count = formdef.data_class().count() |
|
599 |
formdict['count'] = count |
|
577 | 600 | |
578 | 601 |
formdict['functions'] = {} |
579 | 602 |
formdef_workflow_roles = formdef.workflow_roles or {} |
wcs/sql.py | ||
---|---|---|
2525 | 2525 |
formdatas[0].load_all_evolutions(formdatas) |
2526 | 2526 | |
2527 | 2527 | |
2528 |
def get_period_query(period_start=None, period_end=None, criterias=None, parameters=None):
|
|
2528 |
def get_period_query(period_start=None, include_start=True, period_end=None, include_end=True, criterias=None, parameters=None):
|
|
2529 | 2529 |
clause = [NotNull('receipt_time')] |
2530 | 2530 |
table_name = 'wcs_all_forms' |
2531 | 2531 |
if criterias: |
... | ... | |
2539 | 2539 |
continue |
2540 | 2540 |
clause.append(criteria) |
2541 | 2541 |
if period_start: |
2542 |
clause.append(GreaterOrEqual('receipt_time', period_start)) |
|
2542 |
if include_start: |
|
2543 |
clause.append(GreaterOrEqual('receipt_time', period_start)) |
|
2544 |
else: |
|
2545 |
clause.append(Greater('receipt_time', period_start)) |
|
2543 | 2546 |
if period_end: |
2544 |
clause.append(LessOrEqual('receipt_time', period_end)) |
|
2547 |
if include_end: |
|
2548 |
clause.append(LessOrEqual('receipt_time', period_end)) |
|
2549 |
else: |
|
2550 |
clause.append(Less('receipt_time', period_end)) |
|
2545 | 2551 |
where_clauses, params, func_clause = parse_clause(clause) |
2546 | 2552 |
parameters.update(params) |
2547 | 2553 |
statement = ' FROM %s ' % table_name |
... | ... | |
2589 | 2595 |
conn, cur = get_connection_and_cursor() |
2590 | 2596 |
statement = '''SELECT DATE_PART('dow', receipt_time) AS weekday, COUNT(*)''' |
2591 | 2597 |
parameters = {} |
2592 |
statement += get_period_query(period_start, period_end, criterias, parameters)
|
|
2598 |
statement += get_period_query(period_start=period_start, period_end=period_end, criterias=criterias, parameters=parameters)
|
|
2593 | 2599 |
statement += ' GROUP BY weekday ORDER BY weekday''' |
2594 | 2600 |
cur.execute(statement, parameters) |
2595 | 2601 | |
... | ... | |
2612 | 2618 |
conn, cur = get_connection_and_cursor() |
2613 | 2619 |
statement = '''SELECT DATE_PART('hour', receipt_time) AS hour, COUNT(*)''' |
2614 | 2620 |
parameters = {} |
2615 |
statement += get_period_query(period_start, period_end, criterias, parameters)
|
|
2621 |
statement += get_period_query(period_start=period_start, period_end=period_end, criterias=criterias, parameters=parameters)
|
|
2616 | 2622 |
statement += ' GROUP BY hour ORDER BY hour' |
2617 | 2623 |
cur.execute(statement, parameters) |
2618 | 2624 | |
... | ... | |
2636 | 2642 |
conn, cur = get_connection_and_cursor() |
2637 | 2643 |
statement = '''SELECT DATE_TRUNC('month', receipt_time) AS month, COUNT(*) ''' |
2638 | 2644 |
parameters = {} |
2639 |
statement += get_period_query(period_start, period_end, criterias, parameters)
|
|
2645 |
statement += get_period_query(period_start=period_start, period_end=period_end, criterias=criterias, parameters=parameters)
|
|
2640 | 2646 |
statement += ' GROUP BY month ORDER BY month''' |
2641 | 2647 |
cur.execute(statement, parameters) |
2642 | 2648 | |
... | ... | |
2665 | 2671 |
conn, cur = get_connection_and_cursor() |
2666 | 2672 |
statement = '''SELECT DATE_TRUNC('year', receipt_time) AS year, COUNT(*)''' |
2667 | 2673 |
parameters = {} |
2668 |
statement += get_period_query(period_start, period_end, criterias, parameters)
|
|
2674 |
statement += get_period_query(period_start=period_start, period_end=period_end, criterias=criterias, parameters=parameters)
|
|
2669 | 2675 |
statement += ' GROUP BY year ORDER BY year' |
2670 | 2676 |
cur.execute(statement, parameters) |
2671 | 2677 | |
... | ... | |
2688 | 2694 |
return result |
2689 | 2695 | |
2690 | 2696 | |
2697 |
@guard_postgres |
|
2698 |
def get_period_total(period_start=None, include_start=True, period_end=None, include_end=True, criterias=None): |
|
2699 |
conn, cur = get_connection_and_cursor() |
|
2700 |
statement = '''SELECT COUNT(*)''' |
|
2701 |
parameters = {} |
|
2702 |
statement += get_period_query( |
|
2703 |
period_start=period_start, include_start=include_start, |
|
2704 |
period_end=period_end, include_end=include_end, |
|
2705 |
criterias=criterias, parameters=parameters) |
|
2706 |
cur.execute(statement, parameters) |
|
2707 | ||
2708 |
result = int(cur.fetchone()[0]) |
|
2709 | ||
2710 |
conn.commit() |
|
2711 |
cur.close() |
|
2712 | ||
2713 |
return result |
|
2714 | ||
2715 | ||
2691 | 2716 |
# latest migration, number + description (description is not used |
2692 | 2717 |
# programmaticaly but will make sure git conflicts if two migrations are |
2693 | 2718 |
# separately added with the same number) |
2694 |
- |