|
45 | 45 | import assign_lib |
46 | 46 |
|
47 | 47 | ## db |
48 | | -from sqlalchemy import func, desc, distinct, or_, text |
| 48 | +from sqlalchemy import func, desc, distinct, and_, or_, text |
49 | 49 | from sqlalchemy.sql import select |
50 | 50 |
|
51 | 51 | ## app-specific |
@@ -573,13 +573,19 @@ def adj(): |
573 | 573 | """Initial rendering for adjudication page.""" |
574 | 574 |
|
575 | 575 | ## TODO: These are placeholders which will be gathered from queries later |
576 | | - query1 = 'Chicago' |
577 | | - query2 = '2016年05月24日' |
| 576 | + filter_field1 = 'start_date' |
| 577 | + filter_compare1 = '__eq__' |
| 578 | + filter_value1 = '2016年05月24日' |
578 | 579 |
|
579 | | - ## perform the query on the web |
580 | | - search_events = db_session.query(EventMetadata).\ |
581 | | - filter(EventMetadata.location.like('%{}%'.format(query1)), |
582 | | - EventMetadata.start_date == query2).all() |
| 580 | + filter_field2 = 'location' |
| 581 | + filter_compare2 = 'like' |
| 582 | + filter_value2 = 'Chicago' |
| 583 | + |
| 584 | + filter_expr1 = getattr(getattr(EventMetadata, filter_field1), filter_compare1)(filter_value1) |
| 585 | + filter_expr2 = getattr(getattr(EventMetadata, filter_field2), filter_compare2)('%{}%'.format(filter_value2)) |
| 586 | + |
| 587 | + ## perform the query and get the results |
| 588 | + search_events = db_session.query(EventMetadata).filter(filter_expr1, filter_expr2).all() |
583 | 589 |
|
584 | 590 | ## Get five recent events |
585 | 591 | recent_events = [x[0] for x in db_session.query(EventMetadata, RecentEvent).\ |
@@ -653,13 +659,99 @@ def do_search(): |
653 | 659 | which meet the search criteria.""" |
654 | 660 | search_params = request.args.to_dict() |
655 | 661 |
|
656 | | - filter_field = search_params.get('filter_field') |
657 | | - filter_value = search_params.get('filter_value') |
658 | | - filter_compare = search_params.get('filter_compare') |
| 662 | + filter_field = search_params.get('adj-filter-field') |
| 663 | + filter_value = search_params.get('adj-filter-value') |
| 664 | + filter_compare = search_params.get('adj-filter-compare') |
| 665 | + |
| 666 | + search_str = search_params.get('adj-search-input') |
| 667 | + |
| 668 | + sort_field = search_params.get('adj-sort-field') |
| 669 | + sort_order = search_params.get('adj-sort-order') |
| 670 | + |
| 671 | + ## TODO: Need to account for multiple different filters and sorting terms. |
| 672 | + |
| 673 | + filter_expr = None |
| 674 | + if filter_field and filter_value and filter_compare: |
| 675 | + ## Translate the filter compare to a SQLAlchemy expression. |
| 676 | + if filter_compare == 'eq': |
| 677 | + filter_expr = getattr(getattr(EventMetadata, filter_field), '__eq__')(filter_value) |
| 678 | + elif filter_compare == 'ne': |
| 679 | + filter_expr = getattr(getattr(EventMetadata, filter_field), '__ne__')(filter_value) |
| 680 | + elif filter_compare == 'lt': |
| 681 | + filter_expr = getattr(getattr(EventMetadata, filter_field), '__lt__')(filter_value) |
| 682 | + elif filter_compare == 'le': |
| 683 | + filter_expr = getattr(getattr(EventMetadata, filter_field), '__le__')(filter_value) |
| 684 | + elif filter_compare == 'gt': |
| 685 | + filter_expr = getattr(getattr(EventMetadata, filter_field), '__gt__')(filter_value) |
| 686 | + elif filter_compare == 'ge': |
| 687 | + filter_expr = getattr(getattr(EventMetadata, filter_field), '__ge__')(filter_value) |
| 688 | + elif filter_compare == 'like': |
| 689 | + filter_expr = getattr(getattr(EventMetadata, filter_field), 'like')('%{}%'.format(filter_value)) |
| 690 | + elif filter_compare == 'startswith': |
| 691 | + filter_expr = getattr(getattr(EventMetadata, filter_field), 'like')('{}%'.format(filter_value)) |
| 692 | + elif filter_compare == 'endswith': |
| 693 | + filter_expr = getattr(getattr(EventMetadata, filter_field), 'like')('%{}'.format(filter_value)) |
| 694 | + else: |
| 695 | + raise Exception('Invalid filter compare: {}'.format(filter_compare)) |
| 696 | + |
| 697 | + search_expr = None |
| 698 | + if search_str: |
| 699 | + ## Get all fields that are searchable. |
| 700 | + search_fields = EventMetadata.__table__.columns.keys() |
| 701 | + search_fields.remove('id') |
| 702 | + |
| 703 | + ## Build the search expression. For now, it can only do an AND or OR search. |
| 704 | + operator = and_ |
| 705 | + if ' AND ' in search_str: |
| 706 | + search_terms = search_str.split(' AND ') |
| 707 | + operator = and_ |
| 708 | + elif ' OR ' in search_str: |
| 709 | + search_terms = search_str.split(' OR ') |
| 710 | + operator = or_ |
| 711 | + else: |
| 712 | + search_terms = [search_str] |
| 713 | + |
| 714 | + ## Build the search by creating an expression for each search term and search field. |
| 715 | + search_expr = [] |
| 716 | + for term in search_terms: |
| 717 | + term_expr = [] |
| 718 | + for field in search_fields: |
| 719 | + term_expr.append(getattr(getattr(EventMetadata, field), 'like')('%{}%'.format(term))) |
| 720 | + search_expr.append(or_(*term_expr)) |
| 721 | + search_expr = operator(*search_expr) |
| 722 | + |
| 723 | + ## Sort by the specified field. |
| 724 | + sort_expr = None |
| 725 | + if sort_field and sort_order: |
| 726 | + sort_expr = getattr(getattr(EventMetadata, sort_field), sort_order)() |
| 727 | + |
| 728 | + print(sort_expr) |
| 729 | + |
| 730 | + a_filter_expr = None |
| 731 | + if filter_expr is not None and search_expr is not None: |
| 732 | + a_filter_expr = and_(filter_expr, search_expr) |
| 733 | + elif filter_expr is not None: |
| 734 | + a_filter_expr = filter_expr |
| 735 | + elif search_expr is not None: |
| 736 | + a_filter_expr = search_expr |
| 737 | + else: |
| 738 | + return make_response("Please enter a search term or a filter.", 400) |
| 739 | + |
| 740 | + search_events = db_session.query(EventMetadata).\ |
| 741 | + filter(a_filter_expr).\ |
| 742 | + order_by(sort_expr).all() |
| 743 | + |
| 744 | + ## TODO: Eventually need to load candidate events |
| 745 | + response = make_response( |
| 746 | + render_template('adj-search-block.html', |
| 747 | + search_events = search_events, |
| 748 | + cand_events = {}) |
| 749 | + ) |
| 750 | + |
| 751 | + ## make and return results. add in the number of results to update the button. |
| 752 | + response.headers['Search-Results'] = len(search_events) |
| 753 | + return response |
659 | 754 |
|
660 | | - ## TODO: Do the filtering. Find a way to translate the filter compare |
661 | | - ## to a SQLAlchemy expression. |
662 | | - pass |
663 | 755 |
|
664 | 756 | @app.route('/adj_search/<function>', methods = ['POST']) |
665 | 757 | @login_required |
|
0 commit comments