示例#1
0
def congressesOfService(icpsr, chamber=""):
    if not isinstance(icpsr, str) or len(icpsr) < 6:
        icpsr = str(int(icpsr)).zfill(6)

    terms = memberLookup({"icpsr": icpsr}, 30)

    # No match for user
    if not "results" in terms:
        return []

    # No chamber information
    if not chamber or not len(chamber):
        if "congresses" in terms["results"][0]:
            return terms["results"][0]["congresses"]
    # House
    elif chamber == "House":
        if "congresses_house" in terms["results"][0]:
            return terms["results"][0]["congresses_house"]
    # Senate
    elif chamber == "Senate":
        if "congresses_senate" in terms["results"][0]:
            return terms["results"][0]["congresses_senate"]

    # Default case.
    return []
示例#2
0
def congressesOfService(icpsr, chamber=""):
	if not isinstance(icpsr, str) or len(icpsr) < 6:
		icpsr = str(int(icpsr)).zfill(6)

	terms = memberLookup({"icpsr": icpsr}, 30)

	# No match for user
	if not "results" in terms:
		return []

	# No chamber information
	if not chamber or not len(chamber):
		if "congresses" in terms["results"][0]:
			return terms["results"][0]["congresses"]
	# House
	elif chamber=="House":
		if "congresses_house" in terms["results"][0]:
			return terms["results"][0]["congresses_house"]
	# Senate
	elif chamber=="Senate":
		if "congresses_senate" in terms["results"][0]:
			return terms["results"][0]["congresses_senate"]

	# Default case.
	return []
示例#3
0
def checkForPartySwitch(person):
	if not "icpsr" in person or not person["icpsr"]:
		return -1

	baseIcpsr = str(person["icpsr"]).zfill(6)
	congresses = congressesOfService(person["icpsr"])
	searchBoundaries = [congresses[0][0]-1, congresses[0][0], congresses[-1][1], congresses[-1][1]+1]

	otherIcpsrs = []
	for congress in searchBoundaries:
		if "bioname" in person:
			lookup = memberLookup({'congress': congress, 'name': person["bioname"]},1)
		else:
			return {}

		if "errormessage" in lookup:
			continue
		else:
			result = lookup["results"][0]
			newIcpsr = str(result["icpsr"]).zfill(6)
			if levenshtein(baseIcpsr, newIcpsr)==1:
				otherIcpsrs.append(newIcpsr)

	if not len(otherIcpsrs):
		return {}
	else:
		return {"results": otherIcpsrs}
示例#4
0
def checkForOccupancy(person):
	if "occupancy" not in person or int(person["occupancy"]) == 0:
		return []

	return []

	if int(person["occupancy"]) > 1:
		prevICPSR = memberLookup({'congress': person["congress"], 'stateName': person["stateName"], 'district': person["district"], 'occupancy': person["occupancy"] - 1}, 1)
	else:
		prevICPSR = 0

	return []
示例#5
0
def checkForPartySwitch(person):
	if not "icpsr" in person or not person["icpsr"]:
		return {}

	if "bioguide_id" in person:
		q = {"bioguide_id": person["bioguide_id"]}

		lookup = memberLookup(q, 10, 1, "Check_Party_Switch")

		if "errormessage" in lookup:
			return {}

		other_icpsrs = [str(x["icpsr"]).zfill(6) for x in lookup["results"] if x["icpsr"] != person["icpsr"]]
		return {"results": other_icpsrs}
示例#6
0
def checkForPartySwitch(person):
    if not "icpsr" in person or not person["icpsr"]:
        return {}

    if "bioguide_id" in person:
        q = {"bioguide_id": person["bioguide_id"]}

        lookup = memberLookup(q, 10, 1, "Check_Party_Switch")

        if "errormessage" in lookup:
            return {}

        other_icpsrs = [
            str(x["icpsr"]).zfill(6) for x in lookup["results"]
            if x["icpsr"] != person["icpsr"]
        ]
        return {"results": other_icpsrs}
示例#7
0
def checkForOccupancy(person):
    if "occupancy" not in person or int(person["occupancy"]) == 0:
        return []

    return []

    if int(person["occupancy"]) > 1:
        prevICPSR = memberLookup(
            {
                'congress': person["congress"],
                'stateName': person["stateName"],
                'district': person["district"],
                'occupancy': person["occupancy"] - 1
            }, 1)
    else:
        prevICPSR = 0

    return []
示例#8
0
def congressesOfService(icpsr, chamber=""):
	if type(icpsr)!=type(str("")) or len(icpsr)<6:
		icpsr = str(icpsr).zfill(6)

	terms = memberLookup({"icpsr": icpsr},30)
	if not "results" in terms:
		return -1

	if not chamber or not len(chamber):
		if "congresses" in terms["results"][0]:
			return terms["results"][0]["congresses"]
	elif chamber=="House":
		if "congresses_house" in terms["results"][0]:
			return terms["results"][0]["congresses_house"]
		else:
			return []
	elif chamber=="Senate":
		if "congresses_senate" in terms["results"][0]:
			return terms["results"][0]["congresses_senate"]
		else:
			return []

	return []
	congressNums = sorted([x["congress"] for x in terms["results"]])
	congressChunks = []
	start=0
	last=0
	for congress in congressNums:
		if start==0:
			start = congress
			last = start
		elif congress<=last+1:
			last = congress
		else:
			congressChunks.append([start, last])
			start = congress
			last = start
	congressChunks.append([start, last])

	return congressChunks
示例#9
0
def assembleSearch(q, nextId, bottle):
    # First, get the current congress
    max_congress = current_congress()

    #Party search
    resultParties = []
    if q is not None and not nextId and not ":" in q and len(
            q.split()) < 4 and len(q):
        try:
            testQ = int(q)
            if testQ > 0 and testQ < 10000:
                partySearch = partyLookup({"id": q}, api="Web_FP_Search")
            else:
                partySearch = {}
        except:
            partySearch = partyLookup({"name": q}, api="Web_FP_Search")
        if "results" in partySearch:
            for party in partySearch["results"]:
                party["scoreMatch"] = fuzz.token_set_ratio(
                    party["fullName"].lower().replace(" party", ""),
                    q.lower().replace(" party", ""))
                if party["count"] > 1000:
                    party["scoreMatch"] += 25
                elif party["count"] > 100:
                    party["scoreMatch"] += 10
                party["seo_name"] = slugify(party["fullName"])
                party["min_year"] = congressToYear(party["minCongress"], 0)
                party["max_year"] = congressToYear(party["maxCongress"], 1)

                resultParties.append(party)
            resultParties.sort(
                key=lambda x: (-x["scoreMatch"], -x["maxCongress"]))

    # Member search
    resultMembers = []
    needScore = 1
    redirFlag = 0
    expandResults = 0
    suppressRollcalls = 0
    currentYear = str(datetime.datetime.now().year)
    memberSearch = {}

    # Building state delegation queries
    jobs = [
        "representatives", "reps", "senators", "members", "senate", "house",
        "house delegation", "senate delegation", "congressmen",
        "congresspersons", "congressional delegation", "congress delegation",
        "delegation"
    ]
    prepositions = ["of", "in", "from"]
    stateMap = {}
    abbrevStateName = []
    fullStateName = []
    stateQueries = []
    # Load the abbrev to full name map.
    stateSet = json.load(open("./model/states.json", "r"))
    for stateLabel in stateSet:
        abbrevStateName.append(stateLabel["state_abbrev"])
        fullStateName.append(stateLabel["name"])
        stateMap[stateLabel["name"]] = stateLabel["state_abbrev"]
        # First, add to the query list the exact names of states/abbrevs
        if stateLabel["name"].lower() != "washington":
            stateQueries.append(stateLabel["name"].lower())

        for job in jobs:
            for preposition in prepositions:
                # Then both current-prefixed and non-current prefixed versions of each combination for names and abbrevs.
                stateQueries.append("current " + job + " " + preposition +
                                    " " + stateLabel["state_abbrev"].lower())
                stateQueries.append("current " + job + " " + preposition +
                                    " " + stateLabel["name"].lower())
                stateQueries.append(job + " " + preposition + " " +
                                    stateLabel["state_abbrev"].lower())
                stateQueries.append(job + " " + preposition + " " +
                                    stateLabel["name"].lower())
    # Time period capture:
    rcSuffix = lambda n: "%d%s" % (n, "tsnrhtdd"[(n / 10 % 10 != 1) *
                                                 (n % 10 < 4) * n % 10::4])
    timePeriods = []
    for i in xrange(max_congress, 0, -1):
        timePeriods.append(str(i) + " congress")
        timePeriods.append("congress " + str(i))
        timePeriods.append(rcSuffix(i) + " congress")
        timePeriods.append("congress: " + str(i))

    stateQueries = list(set(stateQueries))
    if q is not None and not nextId and not ":" in q and len(q):
        try:
            # Search overrides for custom search use cases.
            # Vote by known ID
            if len(q.split()) == 1 and (q.upper().startswith("MH")
                                        or q.upper().startswith("MS")):
                memberSearch = memberLookup({"id": q},
                                            8,
                                            distinct=1,
                                            api="Web_FP_Search")
            # List all speakers
            elif q.strip().lower() in [
                    "speaker of the house", "speakers of the house",
                    "speaker: 1", "speaker:1", "house speaker"
            ]:
                memberSearch = memberLookup({
                    "speaker": 1,
                    "chamber": "house"
                },
                                            60,
                                            distinct=1,
                                            api="Web_FP_Search")
                needScore = 0
                expandResults = 1
            # List all presidents
            elif q.strip().lower() in [
                    "potus", "president of the united states", "president",
                    "the president", "president:1", "president: 1",
                    "presidents", "presidents of the united states",
                    "presidents of the united states of america",
                    "president of the united states of america"
            ]:
                memberSearch = memberLookup({"chamber": "President"},
                                            50,
                                            distinct=1,
                                            api="Web_FP_Search")
                needScore = 0
                expandResults = 1
            # List all freshmen
            elif q.strip().lower() in [
                    "freshmen", "freshman", "new hires", "first-years",
                    "just elected", "tenderfoot", "newly elected",
                    "class of " + currentYear
            ]:
                memberSearch = memberLookup({"freshman": 1},
                                            75,
                                            distinct=1,
                                            api="Web_FP_Search")
                needScore = 0
                expandResults = 1
            # List state delegation
            elif len(
                [s for s in stateQueries if s in q.strip().lower()]) or len([
                    s
                    for s in abbrevStateName if s.lower() == q.strip().lower()
                ]):
                # A priori assume that any query that hits here is a members-only query unless it's the exact state name.
                foundExact = 0

                # Which chamber do we think they're asking for?
                chamberFind = ""
                if "senators" in q.strip().lower() or "senate" in q.strip(
                ).lower():
                    chamberFind = "Senate"
                elif "representatives" in q.strip().lower(
                ) or "reps" in q.strip().lower() or "house" in q.strip().lower(
                ):
                    chamberFind = "House"

                # Which state do we think they're asking for?
                stateName = ""
                for state in fullStateName:
                    if state.lower() in q.strip().lower():
                        stateName = stateMap[state]
                        if state.lower() == q.strip().lower():
                            foundExact = 1
                        break
                if not stateName:
                    for state in abbrevStateName:
                        if any([
                                qs == state.lower()
                                for qs in q.strip().lower().split()
                        ]):
                            stateName = state
                            if state.lower() == q.strip().lower():
                                foundExact = 1
                            break

                # Which congress do we think they're asking for?
                congress = 0
                if "current" in q.strip().lower():
                    congress = max_congress
                else:
                    for timeP in timePeriods:
                        if timeP in q.strip().lower():
                            suppressRollcalls = 1
                            numeral = 0
                            for numeralTime in timeP.split(" "):
                                numeral = numeralTime.replace(
                                    "th", "").replace("nd",
                                                      "").replace("rd", "")
                                if numeral.isdigit():
                                    numeral = int(numeral)
                                    break
                            if numeral:
                                congress = numeral
                                break
                if not congress:
                    congress = max_congress

                if chamberFind and stateName and congress:
                    memberSearch = memberLookup(
                        {
                            "state_abbrev": stateName,
                            "congress": congress,
                            "chamber": chamberFind
                        },
                        100,
                        distinct=1,
                        api="Web_FP_Search")
                    suppressRollcalls = -1 * (foundExact - 1
                                              )  # Switch 1 to 0 or vice versa
                    needScore = 0
                    expandResults = 1
                elif stateName and congress:
                    memberSearch = memberLookup(
                        {
                            "state_abbrev": stateName,
                            "congress": congress
                        },
                        100,
                        distinct=1,
                        api="Web_FP_Search")
                    suppressRollcalls = -1 * (foundExact - 1
                                              )  # Switch 1 to 0 or vice versa
                    needScore = 0
                    expandResults = 1
                else:
                    print "Something failed in state delegation lookup."

            # ICPSR of user
            elif len(q.split()) == 1 and type(q) == type(0) and int(q):
                memberSearch = memberLookup({"icpsr": int(q)},
                                            5,
                                            distinct=1,
                                            api="Web_FP_Search")
                redirFlag = 1
            # Okay, probably a normal search then.
            elif len(q.split()) <= 5:
                memberSearch = memberLookup({"name": q},
                                            200,
                                            distinct=1,
                                            api="Web_FP_Search")
        except:
            print traceback.format_exc()
            memberSearch = memberLookup({"name": q},
                                        200,
                                        distinct=1,
                                        api="Web_FP_Search")

    # Biography search
    if q is not None and len(q) and len(
            q.split()) > 1 and q.lower().split()[0] == "biography:":
        bioSearch = " ".join(q.strip().lower().split()[1:])
        memberSearch = memberLookup({"biography": bioSearch},
                                    50,
                                    distinct=1,
                                    api="Web_FP_Search")
        suppressRollcalls = 1
        expandResults = 1

    if "results" in memberSearch:
        seen_bioguide_ids = []
        for member in memberSearch["results"]:
            if "bioguide_id" in member:
                if member["bioguide_id"] in seen_bioguide_ids:
                    continue
                seen_bioguide_ids.append(member["bioguide_id"])

            memName = ""
            if "bioname" in member and member["bioname"] is not None:
                memName = member["bioname"]
            else:
                memName = "Error, Invalid Name."

            try:
                memName = memName.replace(",", "").lower()
            except:
                memName = memName.lower()

            searchNameToScore = q.replace(",", "").lower()
            scoreBasic = fuzz.token_set_ratio(
                memName,
                q.replace(",", "").lower())  # Score base search
            scoreNick = fuzz.token_set_ratio(
                nicknameHelper(memName, searchNameToScore),
                nicknameHelper(
                    searchNameToScore))  # Come up with a best nickname match
            member["scoreMatch"] = max(scoreBasic, scoreNick)
            member["bonusMatch"] = 0

            # Exact last name bonus
            try:
                if len(q.split()
                       ) == 1 and "," in member["bioname"] and q.lower().strip(
                       ) == member["bioname"].lower().split(",")[0]:
                    member["bonusMatch"] += 25
            except:
                pass

            # Recency bonus
            if member["congress"] >= 114:
                member["bonusMatch"] += 15
            elif member["congress"] >= 100:
                member["bonusMatch"] += 10

            # Chamber bonus
            if member["chamber"] == "President":
                member["bonusMatch"] += 25
            if member["chamber"] == "Senate":
                member["bonusMatch"] += 10

            # Duration of service bonus
            if "congresses" in member:
                duration = 0
                for cong in member["congresses"]:
                    duration = duration + (cong[1] - cong[0])
                if duration >= 5:
                    member["bonusMatch"] += 7

            if not os.path.isfile("static/img/bios/" +
                                  str(member["icpsr"]).zfill(6) + ".jpg"):
                member["bioImg"] = "silhouette.png"
            else:
                member["bioImg"] = str(member["icpsr"]).zfill(6) + ".jpg"
            member["minElected"] = congressToYear(member["congresses"][0][0],
                                                  0)
            member["seo_name"] = slugify(member["bioname"])

            if "bioname" in member and len(
                    member["bioname"]) > 20 and "(" in member["bioname"]:
                member["bioname"] = member["bioname"].split(",")[
                    0] + ", " + member["bioname"].split("(")[1].split(")")[0]

            member["state"] = member["state"].replace("(", "").replace(")", "")

            resultMembers.append(member)

        if needScore:
            if len(resultMembers) and resultMembers[0]["scoreMatch"] >= 100:
                resultMembers = [
                    x for x in resultMembers if x["scoreMatch"] >= 100
                ]
            resultMembers.sort(
                key=lambda x: -(x["scoreMatch"] + x["bonusMatch"]))
        else:
            resultMembers.sort(key=lambda x: -x["congress"])
        if len(resultMembers) > 8 and not expandResults:
            resultMembers = resultMembers[0:8]

    if suppressRollcalls:
        bottle.response.headers["rollcall_number"] = 0
        bottle.response.headers["member_number"] = len(resultMembers)
        bottle.response.headers["party_number"] = 0

        if len(resultMembers) > 50:
            resultMembers = resultMembers[:50]

        out = bottle.template("views/search_results",
                              rollcalls=[],
                              errormessage="",
                              resultMembers=resultMembers,
                              resultParties=[])
        return out

    # Date facet
    startdate = defaultValue(bottle.request.params.fromDate)
    enddate = defaultValue(bottle.request.params.toDate)

    # Chamber facet
    try:
        chamber = bottle.request.params.getall("chamber")
        if len(chamber) > 1:
            chamber = None
        elif type(chamber) == type([]):
            chamber = chamber[0]
    except:
        chamber = None

    # Congress facet
    try:
        fromCongress = int(
            defaultValue(bottle.request.params["fromCongress"], 0))
        toCongress = int(defaultValue(bottle.request.params["toCongress"], 0))
        if (q is None or q == "") and (fromCongress or toCongress):
            q = ""

        if fromCongress or toCongress:
            if fromCongress == toCongress:
                q = q + " congress:" + str(fromCongress)
            elif fromCongress and not toCongress:
                q = q + " congress:[" + str(fromCongress) + " to ]"
            elif toCongress and not fromCongress:
                q = q + " congress:[ to " + str(toCongress) + "]"
            else:
                q = q + " congress:[" + str(fromCongress) + " to " + str(
                    toCongress) + "]"
    except:
        pass

    # Support facet
    try:
        support = bottle.request.params["support"]
        if (q is None or q == "") and (support):
            q = ""

        if "," in support:
            try:
                valMin, valMax = [int(x) for x in support.split(",")]
                if valMin != 0 or valMax != 100:
                    q = q + " support:[" + str(valMin) + " to " + str(
                        valMax) + "]"
            except:
                pass
        else:
            try:
                support = int(support)
                q = q + " support:[" + str(support -
                                           1) + " to " + str(support + 1) + "]"
            except:
                pass
    except:
        pass

    # Code facet
    try:
        clausen = bottle.request.params.getall("clausen")
    except:
        clausen = []

    try:
        keyvote = bottle.request.params.getall("keyvote")
        if len(keyvote):
            if q is None or q == "":
                q = "keyvote: 1"
            else:
                q += " keyvote: 1"
        else:
            pass
    except:
        pass

    try:
        peltzman = bottle.request.params.getall("peltzman")
    except:
        peltzman = []
    codeString = ""
    if len(clausen):
        for cCode in clausen:
            codeString += "codes.Clausen: " + cCode + " OR "
    if len(peltzman):
        for pCode in peltzman:
            codeString += "codes.Peltzman: " + pCode + " OR "
    if len(codeString):
        codeString = codeString[0:-4]
        if q is None or q == "":
            q = codeString
        else:
            q += " (" + codeString + ")"

    # Sort facet
    sortD = int(defaultValue(bottle.request.params.sortD, -1))
    try:
        if sortD != -1 and sortD != 1:
            sortD = -1
    except:
        sortD = -1

    sortScore = int(defaultValue(bottle.request.params.sortScore, 1))
    icpsr = defaultValue(bottle.request.params.icpsr)
    jsapi = 1
    rowLimit = 50
    res = query(q,
                startdate,
                enddate,
                chamber,
                icpsr=icpsr,
                rowLimit=rowLimit,
                jsapi=jsapi,
                sortDir=sortD,
                sortSkip=nextId,
                sortScore=sortScore,
                request=bottle.request)

    if "errormessage" in res:
        bottle.response.headers["rollcall_number"] = -999
        bottle.response.headers["member_number"] = 0
        bottle.response.headers["nextId"] = 0

        remainder = 50
        if len(resultParties) > 4:
            resultParties = resultParties[:4]
            remainder -= len(resultParties)

        if len(resultMembers) > remainder:
            resultMembers = resultMembers[:remainder]

        out = bottle.template("views/search_results",
                              rollcalls=[],
                              errormessage=res["errormessage"],
                              resultMembers=resultMembers,
                              resultParties=resultParties)
    else:
        if "fulltextSearch" in res:
            highlighter = res["fulltextSearch"]
        else:
            highlighter = ""

        if redirFlag == 1 and len(resultParties) == 0 and len(
                resultMembers) == 1 and (not "rollcalls" in res
                                         or len(res["rollcalls"]) == 0):
            bottle.response.headers["redirect_url"] = "/person/" + str(
                resultMembers[0]["icpsr"]) + "/" + resultMembers[0]["seo_name"]
        bottle.response.headers["rollcall_number"] = res["recordcountTotal"]
        bottle.response.headers["member_number"] = len(resultMembers)
        bottle.response.headers["party_number"] = len(resultParties)
        bottle.response.headers["nextId"] = res["nextId"]
        bottle.response.headers["need_score"] = res["needScore"]
        if not "rollcalls" in res:
            out = bottle.template("views/search_results",
                                  rollcalls=[],
                                  errormessage="",
                                  resultMembers=resultMembers,
                                  resultParties=resultParties)
        else:
            out = bottle.template("views/search_results",
                                  rollcalls=res["rollcalls"],
                                  highlighter=highlighter,
                                  errormessage="",
                                  resultMembers=resultMembers,
                                  resultParties=resultParties)

    return (out)
示例#10
0
def assemblePersonMeta(person, keith=0):
    # Default name
    person["bioname"] = person.get("bioname",
                                   "ERROR NO NAME IN DATABASE PLEASE FIX.")

    # Check if bio image exists
    default = "silhouette.png" if not keith else "keith.png"
    person["bioImg"], bioFound = getBioImage(person["icpsr"], default)

    # Get years of service
    person["yearsOfService"] = getYearsOfService(person, "")
    person["yearsOfServiceSenate"] = getYearsOfService(person, "Senate")
    person["yearsOfServiceHouse"] = getYearsOfService(person, "House")

    person["congressesOfService"] = person["congresses"]
    person["congressLabels"] = {}
    for congressChunk in person["congressesOfService"]:
        for cong in range(congressChunk[0], congressChunk[1] + 1):
            person["congressLabels"][cong] = str(cong) + "th Congress (" + str(
                congressToYear(cong, 0)) + "-" + str(congressToYear(cong,
                                                                    1)) + ")"

    # Find out if we have any other ICPSRs that are this person for another
    # party
    altICPSRs = checkForPartySwitch(person)
    if altICPSRs and "results" in altICPSRs:
        person["altPeople"] = []
        # Iterate through them
        for alt in altICPSRs["results"]:
            # Look up this one
            altPerson = memberLookup({"icpsr": alt}, 1)["results"][0]
            if not "errormessage" in altPerson:
                # Get their years of service
                altPerson["yearsOfService"] = getYearsOfService(altPerson, "")

                if not altPerson["icpsr"] in [
                        x["icpsr"] for x in person["altPeople"]
                ]:
                    person["altPeople"].append(altPerson)

    loyalty = getLoyalty(person["party_code"], person["congress"])

    person["party_loyalty"] = 100 * (
        1 - loyalty["party"]["nvotes_against_party"] /
        (loyalty["party"]["nvotes_yea_nay"] * 1.0))

    person["global_loyalty"] = 100 * (
        1 - loyalty["global"]["nvotes_against_party"] /
        (loyalty["global"]["nvotes_yea_nay"] * 1.0))

    # Quick hack to fix a minor annoying style choice in congressional bioguide.
    if "biography" in person:
        person["biography"] = person["biography"].replace(
            "a Representative", "Representative")

    # Biographical lived years string
    if "died" in person and person["yearsOfService"][-1][1] > person[
            "died"] and person["died"] is not None:
        person["yearsOfService"][-1][1] = person["died"]

    if "born" in person and "died" in person and person[
            "born"] is not None and person["died"] is not None:
        person["lifeString"] = "(%s-%s)" % (str(
            person["born"]), str(person["died"]))
    elif ("born" in person and person["born"] is not None) and (
            not "died" in person
            or person["died"] is None) and person["born"] < 1900:
        person["lifeString"] = "(%s-??)" % str(person["born"])
    elif ("born" in person and person["born"]
          is not None) and (not "died" in person or person["died"] is None):
        person["lifeString"] = "(%s-)" % str(person["born"])
    elif "died" in person and person["died"] is not None:
        person["lifeString"] = "(??-%s)" % str(person["died"])
    else:
        person["lifeString"] = ""

    # Fix their last name.
    person["last_name"] = person["bioname"].split(
        ",")[0].upper()[0] + person["bioname"].split(",")[0].lower()[1:]

    if person["state"] != "President":
        person[
            "stateText"] = " of %s <img src=\"/static/img/states/%s.png\" class=\"member_flag\">" % (
                person["state"], person["state_abbrev"])
    else:
        person[
            "stateText"] = ', President of the United States <img src="/static/img/states/US.png" class="member_flag">'

    person["plotIdeology"] = 1 if "nominate" in person and "dim1" in person[
        "nominate"] and person["nominate"]["dim2"] is not None else 0

    return person
示例#11
0
    # Fix their last name.
    person["last_name"] = person["bioname"].split(
        ",")[0].upper()[0] + person["bioname"].split(",")[0].lower()[1:]

    if person["state"] != "President":
        person[
            "stateText"] = " of %s <img src=\"/static/img/states/%s.png\" class=\"member_flag\">" % (
                person["state"], person["state_abbrev"])
    else:
        person[
            "stateText"] = ', President of the United States <img src="/static/img/states/US.png" class="member_flag">'

    person["plotIdeology"] = 1 if "nominate" in person and "dim1" in person[
        "nominate"] and person["nominate"]["dim2"] is not None else 0

    return person


def twitterCard(person):
    if not "twitter_card" in person:
        return None

    twitter_card = person["twitter_card"]
    twitter_card["icpsr"] = person["icpsr"]
    return twitter_card


if __name__ == "__main__":
    print checkForPartySwitch(memberLookup({'icpsr': 14910}, 1)["results"][0])
示例#12
0
def assemblePersonMeta(person, keith=0):
    # Default name
    person["bioname"] = person.get("bioname", "ERROR NO NAME IN DATABASE PLEASE FIX.")

    # Check if bio image exists
    default = "silhouette.png" if not keith else "keith.png"
    person["bioImg"], bioFound = getBioImage(person["icpsr"], default)

    # Get years of service
    person["yearsOfService"] = getYearsOfService(person, "")
    person["yearsOfServiceSenate"] = getYearsOfService(person, "Senate")
    person["yearsOfServiceHouse"] = getYearsOfService(person, "House")

    person["congressesOfService"] = person["congresses"]
    person["congressLabels"] = {}
    for congressChunk in person["congressesOfService"]:
        for cong in range(congressChunk[0], congressChunk[1] + 1):
            person["congressLabels"][cong] = str(cong) + "th Congress (" + str(
                congressToYear(cong, 0)) + "-" + str(congressToYear(cong, 1)) + ")"

    # Find out if we have any other ICPSRs that are this person for another
    # party
    altICPSRs = checkForPartySwitch(person)
    if altICPSRs and "results" in altICPSRs:
        person["altPeople"] = []
        # Iterate through them
        for alt in altICPSRs["results"]:
            # Look up this one
            altPerson = memberLookup({"icpsr": alt}, 1)["results"][0]
            if not "errormessage" in altPerson:
                # Get their years of service
                altPerson["yearsOfService"] = getYearsOfService(altPerson, "")

                if not altPerson["icpsr"] in [x["icpsr"] for x in person["altPeople"]]:
                    person["altPeople"].append(altPerson)

    loyalty = getLoyalty(person["party_code"], person["congress"])

    person["party_loyalty"] = 100 * (1 - loyalty["party"]["nvotes_against_party"] / (
        loyalty["party"]["nvotes_yea_nay"] * 1.0))

    person["global_loyalty"] = 100 * (1 - loyalty["global"][
                                      "nvotes_against_party"] / (loyalty["global"]["nvotes_yea_nay"] * 1.0))

    # Quick hack to fix a minor annoying style choice in congressional bioguide.
    if "biography" in person:
        person["biography"] = person["biography"].replace("a Representative", "Representative")

    # Biographical lived years string
    if "died" in person and person["yearsOfService"][-1][1]>person["died"] and person["died"] is not None:
        person["yearsOfService"][-1][1] = person["died"]

    if "born" in person and "died" in person and person["born"] is not None and person["died"] is not None:
        person["lifeString"] = "(%s-%s)" % (str(person["born"]), str(person["died"]))
    elif ("born" in person and person["born"] is not None) and (not "died" in person or person["died"] is None) and person["born"] < 1900:
        person["lifeString"] = "(%s-??)" % str(person["born"])
    elif ("born" in person and person["born"] is not None) and (not "died" in person or person["died"] is None):
        person["lifeString"] = "(%s-)" % str(person["born"])
    elif "died" in person and person["died"] is not None:
        person["lifeString"] = "(??-%s)" % str(person["died"])
    else:
        person["lifeString"] = ""

    # Fix their last name.
    person["last_name"] = person["bioname"].split(",")[0].upper()[0] + person["bioname"].split(",")[0].lower()[1:]

    if person["state"] != "President":
        person["stateText"] = " of %s <img src=\"/static/img/states/%s.png\" class=\"member_flag\">" % (person["state"], person["state_abbrev"])
    else:
        person["stateText"] = ', President of the United States <img src="/static/img/states/US.png" class="member_flag">'

    person["plotIdeology"] = 1 if "nominate" in person and "dim1" in person["nominate"] and person["nominate"]["dim2"] is not None else 0

    return person
示例#13
0
    elif ("born" in person and person["born"] is not None) and (not "died" in person or person["died"] is None):
        person["lifeString"] = "(%s-)" % str(person["born"])
    elif "died" in person and person["died"] is not None:
        person["lifeString"] = "(??-%s)" % str(person["died"])
    else:
        person["lifeString"] = ""

    # Fix their last name.
    person["last_name"] = person["bioname"].split(",")[0].upper()[0] + person["bioname"].split(",")[0].lower()[1:]

    if person["state"] != "President":
        person["stateText"] = " of %s <img src=\"/static/img/states/%s.png\" class=\"member_flag\">" % (person["state"], person["state_abbrev"])
    else:
        person["stateText"] = ', President of the United States <img src="/static/img/states/US.png" class="member_flag">'

    person["plotIdeology"] = 1 if "nominate" in person and "dim1" in person["nominate"] and person["nominate"]["dim2"] is not None else 0

    return person

def twitterCard(person):
	if not "twitter_card" in person:
		return None

	twitter_card = person["twitter_card"]
	twitter_card["icpsr"] = person["icpsr"]
	return twitter_card

if __name__=="__main__":
	print checkForPartySwitch(memberLookup({'icpsr': 14910},1)["results"][0])

示例#14
0
def assembleSearch(q, nextId, bottle):
	# First, get the current congress
	max_congress = current_congress()

	#Party search
	resultParties = []
	if q is not None and not nextId and not ":" in q and len(q.split())<4 and len(q):
		try:
			testQ = int(q)
			if testQ>0 and testQ<10000:
				partySearch = partyLookup({"id": q}, api="Web_FP_Search")
			else:
				partySearch = {}
		except:
			partySearch = partyLookup({"name": q}, api="Web_FP_Search")
		if "results" in partySearch:
			for party in partySearch["results"]:
				party["scoreMatch"] = fuzz.token_set_ratio(party["fullName"].lower().replace(" party",""), q.lower().replace(" party",""))
				if party["count"] > 1000:
					party["scoreMatch"] += 25
				elif party["count"] > 100:
					party["scoreMatch"] += 10
				party["seo_name"] = slugify(party["fullName"])
				party["min_year"] = congressToYear(party["minCongress"], 0)
				party["max_year"] = congressToYear(party["maxCongress"], 1)

				resultParties.append(party)
			resultParties.sort(key=lambda x: (-x["scoreMatch"], -x["maxCongress"]))

	# Member search
	resultMembers = []
	needScore=1
	redirFlag=0
	expandResults=0
	suppressRollcalls=0
	currentYear = str(datetime.datetime.now().year)
	memberSearch = {}

	# Building state delegation queries
	jobs = ["representatives", "reps", "senators", "members", "senate", "house", "house delegation", "senate delegation", "congressmen", "congresspersons", "congressional delegation", "congress delegation", "delegation"]
	prepositions = ["of", "in", "from"]
	stateMap = {}
	abbrevStateName = []
	fullStateName = []
	stateQueries = []
	# Load the abbrev to full name map.
	stateSet = json.load(open("./model/states.json","r"))
	for stateLabel in stateSet:
		abbrevStateName.append(stateLabel["state_abbrev"])
		fullStateName.append(stateLabel["name"])
		stateMap[stateLabel["name"]] = stateLabel["state_abbrev"]
		# First, add to the query list the exact names of states/abbrevs
		if stateLabel["name"].lower()!="washington":
			stateQueries.append(stateLabel["name"].lower())

		for job in jobs:
			for preposition in prepositions:
				# Then both current-prefixed and non-current prefixed versions of each combination for names and abbrevs.
				stateQueries.append("current "+job+" "+preposition+" "+stateLabel["state_abbrev"].lower())
				stateQueries.append("current "+job+" "+preposition+" "+stateLabel["name"].lower())
				stateQueries.append(job+" "+preposition+" "+stateLabel["state_abbrev"].lower())
				stateQueries.append(job+" "+preposition+" "+stateLabel["name"].lower())
	# Time period capture:
	rcSuffix = lambda n: "%d%s" % (n,"tsnrhtdd"[(n/10%10!=1)*(n%10<4)*n%10::4])
	timePeriods = []
	for i in xrange(max_congress, 0, -1):
		timePeriods.append(str(i) + " congress")
		timePeriods.append("congress " + str(i))
		timePeriods.append(rcSuffix(i) + " congress")
		timePeriods.append("congress: " + str(i))

	stateQueries = list(set(stateQueries))
	if q is not None and not nextId and not ":" in q and len(q):
		try:
			# Search overrides for custom search use cases.
			# Vote by known ID
			if len(q.split())==1 and (q.upper().startswith("MH") or q.upper().startswith("MS")):
				memberSearch = memberLookup({"id": q}, 8, distinct=1, api="Web_FP_Search")
			# List all speakers
			elif q.strip().lower() in ["speaker of the house","speakers of the house","speaker: 1", "speaker:1","house speaker"]:
				memberSearch = memberLookup({"speaker": 1, "chamber": "house"}, 60, distinct=1, api="Web_FP_Search")
				needScore=0
				expandResults=1
			# List all presidents
			elif q.strip().lower() in ["potus", "president of the united states", "president", "the president", "president:1", "president: 1","presidents","presidents of the united states","presidents of the united states of america","president of the united states of america"]:
				memberSearch = memberLookup({"chamber": "President"}, 50, distinct=1, api="Web_FP_Search")
				needScore=0
				expandResults=1
			# List all freshmen
			elif q.strip().lower() in ["freshmen", "freshman", "new hires", "first-years", "just elected", "tenderfoot", "newly elected", "class of "+currentYear]:
				memberSearch = memberLookup({"freshman": 1}, 75, distinct=1, api="Web_FP_Search")
				needScore=0
				expandResults=1
			# List state delegation
			elif len([s for s in stateQueries if s in q.strip().lower()]) or len([s for s in abbrevStateName if s.lower()==q.strip().lower()]):
				# A priori assume that any query that hits here is a members-only query unless it's the exact state name.
				foundExact = 0

				# Which chamber do we think they're asking for?
				chamberFind=""
				if "senators" in q.strip().lower() or "senate" in q.strip().lower():
					chamberFind="Senate"
				elif "representatives" in q.strip().lower() or "reps" in q.strip().lower() or "house" in q.strip().lower():
					chamberFind="House"

				# Which state do we think they're asking for?
				stateName = ""
				for state in fullStateName:
					if state.lower() in q.strip().lower():
						stateName = stateMap[state]
						if state.lower()==q.strip().lower():
							foundExact=1
						break
				if not stateName:
					for state in abbrevStateName:
						if any([qs == state.lower() for qs in q.strip().lower().split()]):
							stateName = state
							if state.lower()==q.strip().lower():
								foundExact=1
							break

				# Which congress do we think they're asking for?
				congress = 0
				if "current" in q.strip().lower():
					congress = max_congress
				else:
					for timeP in timePeriods:
						if timeP in q.strip().lower():
							suppressRollcalls=1
							numeral = 0
							for numeralTime in timeP.split(" "):
								numeral = numeralTime.replace("th","").replace("nd","").replace("rd","")
								if numeral.isdigit():
									numeral = int(numeral)
									break
							if numeral:
								congress = numeral
								break
				if not congress:
					congress = max_congress

				if chamberFind and stateName and congress:
					memberSearch = memberLookup({"state_abbrev": stateName, "congress": congress, "chamber": chamberFind}, 100, distinct=1, api="Web_FP_Search") 
					suppressRollcalls = -1*(foundExact-1) # Switch 1 to 0 or vice versa
					needScore=0
					expandResults=1
				elif stateName and congress:
					memberSearch = memberLookup({"state_abbrev": stateName, "congress": congress}, 100, distinct=1, api="Web_FP_Search") 
					suppressRollcalls = -1*(foundExact-1) # Switch 1 to 0 or vice versa
					needScore=0
					expandResults=1
				else:
					print "Something failed in state delegation lookup."

			# ICPSR of user
			elif len(q.split())==1 and type(q)==type(0) and int(q):
				memberSearch = memberLookup({"icpsr": int(q)}, 5, distinct=1, api="Web_FP_Search")
				redirFlag=1
			# Okay, probably a normal search then.
			elif len(q.split())<=5:
				memberSearch = memberLookup({"name": q}, 200, distinct=1, api="Web_FP_Search")
		except:
			print traceback.format_exc()
			memberSearch = memberLookup({"name": q}, 200, distinct=1, api="Web_FP_Search")

	# Biography search
	if q is not None and len(q) and len(q.split())>1 and q.lower().split()[0]=="biography:":
		bioSearch = " ".join(q.strip().lower().split()[1:])
		memberSearch = memberLookup({"biography": bioSearch}, 50, distinct=1, api="Web_FP_Search")
		suppressRollcalls = 1
		expandResults = 1

	if "results" in memberSearch:
		seen_bioguide_ids = []
		for member in memberSearch["results"]:
			if "bioguide_id" in member:
				if member["bioguide_id"] in seen_bioguide_ids:
					continue
				seen_bioguide_ids.append(member["bioguide_id"])

			memName = ""
			if "bioname" in member and member["bioname"] is not None:
				memName = member["bioname"]
			else:
				memName = "Error, Invalid Name."

			try:
				memName = memName.replace(",","").lower()
			except:
				memName = memName.lower()

			searchNameToScore = q.replace(",","").lower()
			scoreBasic = fuzz.token_set_ratio(memName, q.replace(",","").lower()) # Score base search
			scoreNick = fuzz.token_set_ratio(nicknameHelper(memName, searchNameToScore), nicknameHelper(searchNameToScore)) # Come up with a best nickname match
			member["scoreMatch"] = max(scoreBasic, scoreNick)
			member["bonusMatch"] = 0

			# Exact last name bonus
			try:
				if len(q.split())==1 and "," in member["bioname"] and q.lower().strip()==member["bioname"].lower().split(",")[0]:
					member["bonusMatch"] += 25
			except:
				pass

			# Recency bonus
			if member["congress"]>=114:
				member["bonusMatch"] += 15
			elif member["congress"]>=100:
				member["bonusMatch"] += 10

			# Chamber bonus
			if member["chamber"]=="President":
				member["bonusMatch"] += 25
			if member["chamber"]=="Senate":
				member["bonusMatch"] += 10

			# Duration of service bonus
			if "congresses" in member:
				duration = 0
				for cong in member["congresses"]:
					duration = duration+(cong[1]-cong[0])
				if duration>=5:
					member["bonusMatch"] += 7

			if not os.path.isfile("static/img/bios/"+str(member["icpsr"]).zfill(6)+".jpg"):
				member["bioImg"] = "silhouette.png"
			else:
				member["bioImg"] = str(member["icpsr"]).zfill(6)+".jpg"
			member["minElected"] = congressToYear(member["congresses"][0][0], 0)
			member["seo_name"] = slugify(member["bioname"])

			if "bioname" in member and len(member["bioname"]) > 20 and "(" in member["bioname"]:
				member["bioname"] = member["bioname"].split(",")[0] + ", " + member["bioname"].split("(")[1].split(")")[0]

			member["state"] = member["state"].replace("(", "").replace(")", "")

			resultMembers.append(member)

		if needScore:
			if len(resultMembers) and resultMembers[0]["scoreMatch"]>=100:
				resultMembers = [x for x in resultMembers if x["scoreMatch"]>=100]
			resultMembers.sort(key=lambda x: -(x["scoreMatch"] + x["bonusMatch"]))
		else:
			resultMembers.sort(key=lambda x: -x["congress"])
		if len(resultMembers)>8 and not expandResults:
			resultMembers=resultMembers[0:8]

	if suppressRollcalls:
		bottle.response.headers["rollcall_number"] = 0
		bottle.response.headers["member_number"] = len(resultMembers)
		bottle.response.headers["party_number"] = 0

		if len(resultMembers) > 50:
			resultMembers = resultMembers[:50]

		out = bottle.template("views/search_results", rollcalls = [], errormessage="", resultMembers=resultMembers, resultParties=[])
		return out

	# Date facet
	startdate = defaultValue(bottle.request.params.fromDate)
	enddate = defaultValue(bottle.request.params.toDate)

	# Chamber facet
	try:
		chamber = bottle.request.params.getall("chamber")
		if len(chamber)>1:
			chamber = None
		elif type(chamber)==type([]):
			chamber = chamber[0]
	except:
		chamber = None

	# Congress facet
	try:
		fromCongress = int(defaultValue(bottle.request.params["fromCongress"],0))
		toCongress = int(defaultValue(bottle.request.params["toCongress"],0))
		if (q is None or q=="") and (fromCongress or toCongress):
			q = ""

		if fromCongress or toCongress:
			if fromCongress == toCongress:
				q = q + " congress:"+str(fromCongress)
			elif fromCongress and not toCongress:
				q = q + " congress:["+str(fromCongress)+" to ]"
			elif toCongress and not fromCongress:
				q = q + " congress:[ to "+str(toCongress)+"]"
			else:
				q = q + " congress:["+str(fromCongress)+" to "+str(toCongress)+"]"
	except:
		pass

	# Support facet
	try:
		support = bottle.request.params["support"]
		if (q is None or q=="") and (support):
			q = ""

		if "," in support:
			try:
				valMin, valMax = [int(x) for x in support.split(",")]
				if valMin!=0 or valMax!=100:
					q = q + " support:["+str(valMin)+" to "+str(valMax)+"]"
			except:
				pass
		else:
			try:
				support = int(support)
				q = q + " support:["+str(support-1)+" to "+str(support+1)+"]"
			except:
				pass
	except:
		pass

	# Code facet
	try:
		clausen = bottle.request.params.getall("clausen")
	except:
		clausen = []

	try:
		keyvote = bottle.request.params.getall("keyvote")
		if len(keyvote):
			if q is None or q=="":
				q = "keyvote: 1"
			else:
				q += " keyvote: 1"
		else:
			pass
	except:
		pass

	try:
		peltzman = bottle.request.params.getall("peltzman")
	except:
		peltzman = []
	codeString = ""
	if len(clausen):
		for cCode in clausen:
			codeString += "codes.Clausen: "+cCode+" OR "
	if len(peltzman):
		for pCode in peltzman:
			codeString += "codes.Peltzman: "+pCode+" OR "
	if len(codeString):
		codeString = codeString[0:-4]
		if q is None or q=="":
			q = codeString
		else:
			q += " ("+codeString+")"

	# Sort facet
	sortD = int(defaultValue(bottle.request.params.sortD,-1))
	try:
		if sortD!=-1 and sortD!=1:
			sortD = -1
	except:
		sortD = -1

	sortScore = int(defaultValue(bottle.request.params.sortScore,1))
	icpsr = defaultValue(bottle.request.params.icpsr)
	jsapi = 1
	rowLimit = 50
	res = query(q, startdate, enddate, chamber, icpsr=icpsr, rowLimit=rowLimit, jsapi=jsapi, sortDir=sortD, sortSkip=nextId, sortScore=sortScore, request=bottle.request)

	if "errormessage" in res:
		bottle.response.headers["rollcall_number"] = -999
		bottle.response.headers["member_number"] = 0
		bottle.response.headers["nextId"] = 0

		remainder = 50
		if len(resultParties) > 4:
			resultParties = resultParties[:4]
			remainder -= len(resultParties)

		if len(resultMembers) > remainder:
			resultMembers = resultMembers[:remainder]

		out = bottle.template("views/search_results", rollcalls = [], errormessage=res["errormessage"], resultMembers=resultMembers, resultParties=resultParties)
	else:
		if "fulltextSearch" in res:
			highlighter = res["fulltextSearch"]
		else:
			highlighter = ""

		if redirFlag==1 and len(resultParties)==0 and len(resultMembers)==1 and (not "rollcalls" in res or len(res["rollcalls"])==0):
			bottle.response.headers["redirect_url"] = "/person/"+str(resultMembers[0]["icpsr"])+"/"+resultMembers[0]["seo_name"]
		bottle.response.headers["rollcall_number"] = res["recordcountTotal"]
		bottle.response.headers["member_number"] = len(resultMembers)
		bottle.response.headers["party_number"] = len(resultParties)
		bottle.response.headers["nextId"] = res["nextId"]
		bottle.response.headers["need_score"] = res["needScore"]
		if not "rollcalls" in res:
			out = bottle.template("views/search_results", rollcalls = [], errormessage="", resultMembers=resultMembers, resultParties=resultParties)
		else:
			out = bottle.template("views/search_results", rollcalls = res["rollcalls"], highlighter=highlighter, errormessage="", resultMembers=resultMembers, resultParties=resultParties) 

	return(out)