def latLongToDistrictCodes(lat, lng):
    geoClient = client["district_geog"]
    gquery = {"geometry": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [lng, lat]}}}}
    res = []
    for r in db.districts.find(gquery, {"properties": 1}):
        rec = [r["properties"][f] for f in ("statename", "district", "startcong", "endcong")]
        # if int(rec[1]):
        for cng in range(rec[2], rec[3] + 1):
            res.append([stateNameToAbbrev(rec[0])["state_abbrev"], cng, int(rec[1])])
    return res
    pass
def latLongToDistrictCodes(request, lat, lng):
	quotaCheck = logQuota.checkQuota(request) # Are we over quota?
	if quotaCheck["status"]: # Yes, so error out
		return {"status": 1, "error_message": quotaCheck["errormessage"]}

	geoClient = client["district_geog"]
	res = []
	isDC = 0
	gquery = {"geometry":{"$geoIntersects":{"$geometry":{"type":"Point","coordinates":[lng, lat]}}}}

	for r in db.districts.find(gquery,{'properties':1}):
		rec = [r['properties'][f] for f in ('statename','district','startcong','endcong')]
		if stateNameToAbbrev(rec[0])["state_abbrev"]=="DC":
			isDC = 1
			continue
		for cng in range(int(rec[2]),int(rec[3])+1):
			res.append( [stateNameToAbbrev(rec[0])["state_abbrev"],cng,int(rec[1])] )

	logQuota.addQuota(request, 2) # Costlier because it's more intense on our side.
	return {"isDC": isDC, "results": res}
	pass
Exemple #3
0
def memberLookup(qDict, maxResults=50, distinct=0, api="Web"):
	# Setup so that the bottle call to this API doesn't need to know parameters we accept explicitly
	name = qDict["name"] if "name" in qDict else ""
	icpsr = qDict["icpsr"] if "icpsr" in qDict else ""
	state_abbrev = qDict["state_abbrev"] if "state_abbrev" in qDict else ""
	congress = qDict["congress"] if "congress" in qDict else ""
	chamber = qDict["chamber"] if "chamber" in qDict else ""
	party_code = qDict["party_code"] if "party_code" in qDict else ""
	bioguide_id = qDict["bioguide_id"] if "bioguide_id" in qDict else ""
	district_code = qDict["district_code"] if "district_code" in qDict else ""
	id = qDict["id"] if "id" in qDict else ""
	speaker = qDict["speaker"] if "speaker" in qDict else ""
	freshman = qDict["freshman"] if "freshman" in qDict else ""
	idIn = qDict["idIn"] if "idIn" in qDict else []
	biography = qDict["biography"] if "biography" in qDict else ""

	if api == "R":
		maxResults = 5000

	# Check to make sure there's a query
	if not name and not icpsr and not state_abbrev and not congress and not district_code and not chamber and not id and not party_code and not bioguide_id and not speaker and not idIn and not freshman and not biography:
		return({'errormessage': 'No search terms provided'})

	# Fold search query into dict
	searchQuery = {}
	if api=="districtLookup":
		searchQuery["id"] = {"$in": qDict["idIn"]}

	if icpsr:
		try:
			icpsr = int(icpsr)
			searchQuery["icpsr"] = icpsr
		except:
			try:
				if icpsr[0]=="M":
					for r in db.voteview_members.find({'id': icpsr}, {'icpsr': 1, '_id': 0}):
						searchQuery["icpsr"] = r["icpsr"]
						break
			except:
				return({"errormessage": "Invalid ICPSR number supplied."})

	if id:
		try:
			if id.upper().startswith("MH") or id.upper().startswith("MS"):
				searchQuery["id"] = id
			else:
				return({"errormessage": "Invalid ID supplied1."})
		except:
			return({"errormessage": "Invalid ID supplied2."})

	if state_abbrev:
		state = str(state_abbrev)
		if len(state) == 2 or state.upper() == "USA":
			searchQuery["state_abbrev"] = state.upper() # States are all stored upper-case
		else:
			searchQuery["state_abbrev"] = stateNameToAbbrev(state.upper())

	if biography:
		searchQuery["biography"] = {"$regex": biography, "$options": i}

	if congress:
		try:
			if isinstance(congress, int): # already a number
				searchQuery["congress"] = congress
			elif not " " in congress: # congress is just a number
				congress = int(congress)
				searchQuery["congress"] = congress
			elif "[" in congress and "]" in congress and "to" in congress: # congress is a range
				valText = congress[1:-1]
				min, maxC = valText.split(" to ")
				searchQuery["congress"] = {}
				if len(min):
					searchQuery["congress"]["$gte"] = int(min) # From min
				if len(maxC):
					searchQuery["congress"]["$lte"] = int(maxC) # To max
			else: # congress is a series of integers, use $in
				vals = [int(val) for val in congress.split(" ")]
				searchQuery["congress"] = {}
				searchQuery["congress"]["$in"] = vals
		except:
			print traceback.format_exc()
			return({"errormessage": "Invalid congress ID supplied."})

	if name:
		if ", " in name: # Last, First
			last, rest = name.split(", ",1)
			searchQuery["$text"] = {"$search": rest+" "+last}
		else:
			searchQuery["$text"] = {"$search": name}

	if speaker:
		searchQuery["served_as_speaker"] = 1

	if freshman:
		try:
			maxCongress = json.load(open("static/config.json","r"))["maxCongress"]
		except:
			try:
				maxCongress = json.load(open("../static/config.json","r"))["maxCongress"]
			except:
				maxCongress = 116

		searchQuery["congresses.0.0"] = maxCongress

	if party_code:
		if isinstance(party_code, dict):
			searchQuery["party_code"] = party_code
		else:
			searchQuery["party_code"] = int(party_code)

	if bioguide_id:
		searchQuery["bioguide_id"] = bioguide_id

	if district_code and state_abbrev:
		searchQuery["district_code"] = district_code

	if chamber:
		chamber = chamber.capitalize()
		if chamber=="Senate" or chamber=="House" or chamber=="President":
			searchQuery["chamber"] = chamber
		else:
			return({"errormessage": "Invalid chamber provided. Please select House or Senate."})

	response = []
	errormessage = ""
	i = 0

	# Field return specifications, allows us to return less than all our data to searches.
	if api=="Web_PI":
		fieldSet = {"nominate.dim1": 1, "party_code": 1, "district_code": 1, "icpsr": 1, "chamber":1, "nvotes_yea_nay": 1, "nvotes_against_party": 1, "nvotes_abs": 1, "_id": 0}
	elif api=="Web_FP_Search":
		fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "_id": 0, "congresses": 1, "chamber": 1, "bioguide_id": 1}
	elif api == "Check_Party_Switch":
		fieldSet = {"icpsr": 1, "_id": 0}
	elif api=="Web_Congress":
		if chamber:
			fieldName = "elected_"+chamber.lower()
			fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "_id": 0, "bioImgURL": 1, "minElected": 1, "nominate.dim1": 1, "nominate.dim2": 1, "congresses": 1, fieldName: 1}
		else:
			fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "_id": 0, "bioImgURL": 1, "minElected": 1, "nominate.dim1": 1, "nominate.dim2": 1, "congresses": 1, "state_abbrev": 1, "elected_senate": 1, "elected_house": 1}
	elif api=="Web_Party":
		fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "_id": 0, "bioImgURL": 1, "minElected": 1, "nominate.dim1": 1, "nominate.dim2": 1, "congresses": 1, "chamber": 1}
	elif api=="R":
		fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "id": 1, "_id": 0, "nominate.dim1": 1, "nominate.dim2": 1, "nominate.geo_mean_probability": 1, "cqlabel": 1, "district_code": 1, "chamber": 1, "congresses": 1}
        elif api=="exportCSV" or api == "exportORD":
                fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "id": 1, "_id": 0, "nominate": 1, "district_code": 1, "chamber": 1, "state_name_trunc": 1, "last_means": 1, "occupancy": 1, "name": 1}
	elif api=="districtLookup":
		fieldSet = {"bioname": 1, "party_code": 1, "icpsr": 1, "state_abbrev": 1, "congress": 1, "id": 1, "nominate.dim1": 1, "nominate.dim2": 1, "district_code": 1, "_id": 0, "chamber": 1, "congresses": 1}
        else:
		fieldSet = {"_id": 0, "personid": 0}
	if "$text" in searchQuery:
		fieldSet["score"] = {"$meta": "textScore"}

	res = db.voteview_members.find(searchQuery, fieldSet)
	# Try to induce regex if a name search fails?
	hypotheticalCount = res.count()
	if "$text" in searchQuery and hypotheticalCount==0:
		print "No results from a name search, fall back to regex"
		del searchQuery["$text"]
		searchQuery["bioname"] = {'$regex': name, '$options': 'i'}
		res = db.voteview_members.find(searchQuery, fieldSet)

        if "$text" in searchQuery:
		sortedRes = res.sort([('score', {'$meta': 'textScore'})])
	elif api=="exportORD":
                db.voteview_members.ensure_index([('state_abbrev', 1), ('district_code', 1), ('icpsr', 1)], name="ordIndex")
                sortedRes = res.sort([('state_abbrev', 1), ('district_code', 1), ('icpsr', 1)])
        else:
		sortedRes = res.sort('congress', -1)
		if sortedRes.count()>1000 and api != "R" and api!= "Web_Party":
			return({"errormessage": "Too many results found."})
		elif sortedRes.count()>5000 and api!= "Web_Party":
			return({"errormessage": "Too many results found."})

	currentICPSRs = []
	for m in sortedRes:
		if m["icpsr"] in currentICPSRs and distinct==1:
			continue
		else:
			currentICPSRs.append(m["icpsr"])
		newM = m

		if "state_abbrev" in newM:
			newM["state"] = stateName(newM["state_abbrev"])
                        if api=="exportORD":
                                newM["state_icpsr"] = stateIcpsr(newM["state_abbrev"])
		if "district_code" in newM and "state_abbrev" in newM:
                        newM["cqlabel"] = cqlabel(newM["state_abbrev"], newM["district_code"])

		if "party_code" in newM:
                        newM["party_name"] = partyName(newM["party_code"])
                        if api not in ["exportORD", "exportCSV", "R"]:
			        newM["party_noun"] = noun(newM["party_code"])
			        newM["party_color"] = partyColor(newM["party_code"])
			        newM["party_short_name"] = shortName(newM["party_code"])

		# Check if an image exists.
		if os.path.isfile("/var/www/voteview/static/img/bios/"+str(newM["icpsr"]).zfill(6)+".jpg"):
			newM["bioImgURL"] = str(newM["icpsr"]).zfill(6)+".jpg"
		else:
			newM["bioImgURL"] = "silhouette.png"

                if api in ["exportCSV", "exportORD"]:
                        if 'bioname' in newM:
                                newM['bioname'] = newM['bioname'].encode('utf-8')
                        if "nominate" in newM:
                                for k,v in newM["nominate"].iteritems():
                                        if k == 'log_likelihood':
                                                newM[k] = round(v, 5)
                                        else:
                                                newM[k] = round(v, 3)
                                del newM["nominate"]

		try:
			newM["seo_name"] = slugify(newM["bioname"])
		except:
			pass

		response.append(newM)
		i=i+1
		if i>=maxResults:
			break

	if len(response)>maxResults and maxResults>1: # For regular searches get mad if we have more than max results.
		errormessage = "Capping number of responses at "+str(maxResults)+"."

	if len(response)==0:
		return({'errormessage': 'No members found matching your search query.', 'query': qDict})
	elif errormessage:
		return({'errormessage': errormessage, 'results': response})
	else:
		return({'results': response})