def get_committee(self, args, page_num, per_page, committee_id, candidate_id): if committee_id is not None: committees = CommitteeDetail.query committees = committees.filter_by(**{'committee_id': committee_id}) if candidate_id is not None: committees = CommitteeDetail.query.join(CandidateCommitteeLink).filter(CandidateCommitteeLink.candidate_id==candidate_id) for argname in ['designation', 'organization_type', 'committee_type']: if args.get(argname): if ',' in args[argname]: committees = committees.filter(getattr(Committee, argname).in_(args[argname].split(','))) else: committees = committees.filter(getattr(Committee, argname)==args[argname]) # default year filtering if args.get('year') is None: earliest_year = int(sorted(default_year().split(','))[0]) # still going or expired after the earliest year we are looking for committees = committees.filter(or_(extract('year', CommitteeDetail.expire_date) >= earliest_year, CommitteeDetail.expire_date == None)) # Should this handle a list of years to make it consistent with /candidate ? elif args.get('year') and args['year'] != '*': # before expiration committees = committees.filter(or_(extract('year', CommitteeDetail.expire_date) >= int(args['year']), CommitteeDetail.expire_date == None)) # after origination committees = committees.filter(extract('year', CommitteeDetail.original_registration_date) <= int(args['year'])) count = committees.count() return count, committees.order_by(CommitteeDetail.name).paginate(page_num, per_page, False).items
class ReportsView(Resource): parser = reqparse.RequestParser() parser.add_argument('page', type=inputs.natural, default=1, help='For paginating through results, starting at page 1') parser.add_argument('per_page', type=inputs.natural, default=20, help='The number of results returned per page. Defaults to 20.') # TODO: change to filter on report_year and add a separate filter for cycle parser.add_argument('year', type=str, default=default_year(), dest='cycle', help="Year in which a candidate runs for office") parser.add_argument('fields', type=str, help='Choose the fields that are displayed') def get(self, **kwargs): committee_id = kwargs['id'] args = self.parser.parse_args(strict=True) # pagination page_num = args.get('page', 1) per_page = args.get('per_page', 20) committee = Committee.query.filter_by(committee_id=committee_id).one() if committee.committee_type == 'P': reports_class = CommitteeReportsPresidential results_fields = merge_dicts(common_fields, presidential_fields) elif committee.committee_type in ['H', 'S']: reports_class = CommitteeReportsHouseOrSenate results_fields = merge_dicts(common_fields, house_senate_fields) else: reports_class = CommitteeReportsPacOrParty results_fields = merge_dicts(common_fields, pac_party_fields) count, reports = self.get_reports(committee_id, reports_class, args, page_num, per_page) data = { 'api_version': '0.2', 'pagination': { 'page': page_num, 'per_page': per_page, 'count': count, 'pages': int(ceil(count / per_page)), }, 'results': reports } reports_view_fields = { 'api_version': fields.Fixed(1), 'pagination': fields.Nested(pagination_fields), 'results': fields.Nested(results_fields), } return marshal(data, reports_view_fields) def get_reports(self, committee_id, reports_class, args, page_num, per_page): reports = reports_class.query.filter_by(committee_id=committee_id) if args['cycle'] != '*': reports = reports.filter(reports_class.cycle.in_(args['cycle'].split(','))) count = reports.count() return count, reports.order_by(desc(reports_class.coverage_end_date)).paginate(page_num, per_page, True).items
def get_committees(self, args, page_num, per_page, candidate_id=None): committees = Committee.query if candidate_id: committees = committees.filter(Committee.candidate_ids.overlap(candidate_id.split(','))) elif args.get('q'): fulltext_qry = """SELECT cmte_sk FROM dimcmte_fulltext WHERE fulltxt @@ to_tsquery(:findme) ORDER BY ts_rank_cd(fulltxt, to_tsquery(:findme)) desc""" findme = ' & '.join(args['q'].split()) committees = committees.filter(Committee.committee_key.in_( db.session.query("cmte_sk").from_statement(text(fulltext_qry)).params(findme=findme))) for argname in ['committee_id', 'designation', 'organization_type', 'state', 'party', 'committee_type']: if args.get(argname): if ',' in args[argname]: committees = committees.filter(getattr(Committee, argname).in_(args[argname].split(','))) else: committees = committees.filter(getattr(Committee, argname)==args[argname]) if args.get('name'): committees = committees.filter(Committee.name.ilike('%{}%'.format(args['name']))) # default year filtering if args.get('year') is None: earliest_year = int(sorted(default_year().split(','))[0]) # still going or expired after the earliest year we are looking for committees = committees.filter(or_(extract('year', Committee.expire_date) >= earliest_year, Committee.expire_date == None)) # Should this handle a list of years to make it consistent with /candidate ? elif args.get('year') and args['year'] != '*': # before expiration committees = committees.filter(or_(extract('year', Committee.expire_date) >= int(args['year']), Committee.expire_date == None)) # after origination committees = committees.filter(extract('year', Committee.original_registration_date) <= int(args['year'])) count = committees.count() return count, committees.order_by(Committee.name).paginate(page_num, per_page, False).items
class CandidateList(Resource): parser = reqparse.RequestParser() parser.add_argument('q', type=str, help='Text to search all fields for') parser.add_argument('candidate_id', type=str, help="Candidate's FEC ID") parser.add_argument('fec_id', type=str, help="Candidate's FEC ID") parser.add_argument( 'page', type=inputs.natural, default=1, help='For paginating through results, starting at page 1') parser.add_argument( 'per_page', type=inputs.natural, default=20, help='The number of results returned per page. Defaults to 20.') parser.add_argument('name', type=str, help="Candidate's name (full or partial)") parser.add_argument('office', type=str, help='Governmental office candidate runs for') parser.add_argument('state', type=str, help='U. S. State candidate is registered in') parser.add_argument( 'party', type=str, help= "Three letter code for the party under which a candidate ran for office" ) parser.add_argument( 'year', type=str, default=default_year(), dest='election_year', help= "Fileter records to only those that were applicable to a given year") parser.add_argument('district', type=str, help='Two digit district number') parser.add_argument( 'candidate_status', type=str, help= 'One letter code explaining if the candidate is a present, future or past candidate' ) parser.add_argument( 'incumbent_challenge', type=str, help= 'One letter code explaining if the candidate is an incumbent, a challenger, or if the seat is open.' ) @marshal_with(candidate_list_fields) def get(self, **kwargs): args = self.parser.parse_args(strict=True) # pagination page_num = args.get('page', 1) per_page = args.get('per_page', 20) count, candidates = self.get_candidates(args, page_num, per_page) page_data = Pagination(page_num, per_page, count) data = { 'api_version': '0.2', 'pagination': page_data.as_json(), 'results': candidates } return data def get_candidates(self, args, page_num, per_page): candidates = Candidate.query fulltext_qry = """SELECT cand_sk FROM dimcand_fulltext WHERE fulltxt @@ to_tsquery(:findme) ORDER BY ts_rank_cd(fulltxt, to_tsquery(:findme)) desc""" if args.get('q'): findme = ' & '.join(args['q'].split()) candidates = candidates.filter( Candidate.candidate_key.in_( db.session.query("cand_sk").from_statement( text(fulltext_qry)).params(findme=findme))) for argname in [ 'candidate_id', 'candidate_status', 'district', 'incumbent_challenge', 'office', 'party', 'state' ]: if args.get(argname): # this is not working and doesn't look like it would work for _short if ',' in args[argname]: candidates = candidates.filter( getattr(Candidate, argname).in_(args[argname].split(','))) else: candidates = candidates.filter_by( **{argname: args[argname]}) if args.get('name'): candidates = candidates.filter( Candidate.name.ilike('%{}%'.format(args['name']))) if args.get('election_year') and args['election_year'] != '*': candidates = candidates.filter( Candidate.election_years.overlap( [int(x) for x in args['election_year'].split(',')])) count = candidates.count() return count, candidates.order_by(Candidate.name).paginate( page_num, per_page, False).items
class TotalsView(Resource): parser = reqparse.RequestParser() parser.add_argument( 'page', type=inputs.natural, default=1, help='For paginating through results, starting at page 1') parser.add_argument( 'per_page', type=inputs.natural, default=20, help='The number of results returned per page. Defaults to 20.') parser.add_argument('year', type=str, default=default_year(), dest='cycle', help="Year in which a candidate runs for office") parser.add_argument('fields', type=str, help='Choose the fields that are displayed') def get(self, **kwargs): committee_id = kwargs['id'] args = self.parser.parse_args(strict=True) # pagination page_num = args.get('page', 1) per_page = args.get('per_page', 20) page_data = Pagination(page_num, per_page, 1) committee = Committee.query.filter_by(committee_id=committee_id).one() if committee.committee_type == 'P': totals_class = CommitteeTotalsPresidential results_fields = merge_dicts(common_fields, presidential_fields) elif committee.committee_type in ['H', 'S']: totals_class = CommitteeTotalsHouseOrSenate results_fields = merge_dicts(common_fields, house_senate_fields) else: totals_class = CommitteeTotalsPacOrParty results_fields = merge_dicts(common_fields, pac_party_fields) totals = self.get_totals(committee_id, totals_class, args, page_num, per_page) data = { 'api_version': '0.2', 'pagination': page_data.as_json(), 'results': totals } totals_view_fields = { 'api_version': fields.Fixed(1), 'pagination': fields.Nested(pagination_fields), 'results': fields.Nested(results_fields), } return marshal(data, totals_view_fields) def get_totals(self, committee_id, totals_class, args, page_num, per_page): totals = totals_class.query.filter_by(committee_id=committee_id) if args['cycle'] != '*': totals = totals.filter( totals_class.cycle.in_(args['cycle'].split(','))) totals = totals.order_by(totals_class.cycle) return totals.paginate(page_num, per_page, True).items