<commit_before>import re
import traceback
import os
import datetime
import time
import json
import bottle
from fuzzywuzzy import fuzz

from model.searchVotes import query
import model.downloadVotes # Namespace issue
from model.emailContact import sendEmail
from model.searchMembers import memberLookup, getMembersByCongress, getMembersByParty
from model.searchParties import partyLookup
from model.bioData import yearsOfService, checkForPartySwitch, congressesOfService, congressToYear
import model.downloadXLS
import model.stashCart
import model.partyData

# Turn this off on production:
devserver = int(open("server.txt","r").read().strip())
if devserver:
	bottle.debug(True)
else:
	bottle.debug(False)

# Setup
app = application = bottle.Bottle()

# Debug timing to improve speed
timeLabels = []
timeNums = []
def clearTime():
    timeLabels = []
    timeNums = []


def timeIt(label):
    timeLabels.append(label)
    timeNums.append(time.time())


def zipTimes():
    tN = []
    for i in xrange(0,len(timeNums)):
        if i==0:
            tN.append(0)
        else:
            tN.append(round(timeNums[i] - timeNums[i-1],3))
    return zip(timeLabels, tN)


# Helper function for handling bottle arguments and setting defaults:
def defaultValue(x,value = None):
    return x is not "" and x or value


#
# Web pages
#
# Pass through static content -- nginx should handle this, but if it doesn't, bottle will
@app.route('/static/<path:path>')
def callback(path):
    return bottle.static_file(path,"./static")


# Index
@app.route("/")
@app.route("/search/")
def index():
    clearTime()
    timeIt("begin")

    try:
        argDict = {}
        for k,v in bottle.request.params.iteritems():
            argDict[k] = v
    except:
        pass

    timeIt("assembleArgs")

    try:
        if "fromDate" in argDict:
            argDict["fromDate"] = argDict["fromDate"].replace("/","-")
            argDict["fromDate"] = re.sub(r"[^0-9\-\ ]", "", argDict["fromDate"])
        if "toDate" in argDict:
            argDict["toDate"] = argDict["toDate"].replace("/","-")
            argDict["toDate"] = re.sub(r"[^0-9\-\ ]", "", argDict["toDate"])
        if "fromCongress" in argDict:
            argDict["fromCongress"] = int(argDict["fromCongress"])
        if "toCongress" in argDict:
            argDict["toCongress"] = int(argDict["toCongress"])
        if "support" in argDict and "," in argDict["support"]:
            try:
                argDict["supportMin"], argDict["supportMax"] = [int(x) for x in argDict["support"].split(",")]
            except:
                pass
        elif "support" in argDict:
            try:
                support = int(argDict["support"])
                argDict["supportMin"] = support - 1
                argDict["supportMax"] = support + 1
            except:
                pass
        timeIt("doneAssembly")
        output = bottle.template("views/search", args=argDict, timeSet=zipTimes())
    except:
        output = bottle.template("views/error", errorMessage = traceback.format_exc())
        #errorMessage="Error: One or more of the parameters you used to call this page was misspecified.")

    return output

# Static Pages with no arguments, just passthrough the template.
# Really we should just cache these, but anyway.
@app.route("/about")
def about():
    output = bottle.template('views/about')
    return output


@app.route("/data")
def data():
    output = bottle.template("views/data")
    return output


@app.route("/research")
def research():
    output = bottle.template("views/research")
    return output


# Pages that have arguments
@app.route("/explore")
@app.route("/explore/<chamber:re:house|senate>")
def explore(chamber="house"):
    if chamber!="senate": # Security to prevent the argument being passed through being malicious.
        chamber = "house"

    output = bottle.template("views/explore",chamber=chamber)
    return output


@app.route("/congress")
@app.route("/congress/<chamber:re:house|senate>")
def congress(chamber="senate"):
    if chamber!="senate":
        chamber = "house"

    maxCongress = json.load(open("static/config.json","r"))["maxCongress"]
    congress = defaultValue(bottle.request.params.congress,maxCongress)

    output = bottle.template("views/congress", chamber=chamber, congress=congress, maxCongress=maxCongress)
    return output


@app.route("/parties")
@app.route("/parties/<party>/<congStart>")
@app.route("/parties/<party>")
def parties(party=200, congStart=-1):
	# Just default for now
	try:
		party = int(party)
	except:
		if party=="all":
			maxCongress = json.load(open("static/config.json","r"))["maxCongress"]
			output = bottle.template("views/partiesGlance", maxCongress=maxCongress)
			return output
		else:
			party = 200

	if congStart==-1:
		congStart = int(json.load(open("static/config.json","r"))["maxCongress"])
	else:
		try:
			congStart = int(congStart)
		except:
			congStart = 0

	if party not in xrange(0, 50001):
		party = 200
	partyData = model.partyData.getPartyName(party)
	if "fullName" in partyData:
		partyNameFull = partyData["fullName"]
	else:
		partyNameFull = ""
	
	output = bottle.template("views/parties", party=party, partyNameFull=partyNameFull, congStart=congStart)
	return output

def parties(party=200):
    # Just default for now
    try:
        party = int(party)
    except:
        if party=="all":<commit_msg>Changes default behaviour for /parties/ to go to the parties at a glance page, in case someone mistypes or directly edits the URL. Thanks Luke.<commit_after>import re
import traceback
import os
import datetime
import time
import json
import bottle
from fuzzywuzzy import fuzz

from model.searchVotes import query
import model.downloadVotes # Namespace issue
from model.emailContact import sendEmail
from model.searchMembers import memberLookup, getMembersByCongress, getMembersByParty
from model.searchParties import partyLookup
from model.bioData import yearsOfService, checkForPartySwitch, congressesOfService, congressToYear
import model.downloadXLS
import model.stashCart
import model.partyData

# Turn this off on production:
devserver = int(open("server.txt","r").read().strip())
if devserver:
	bottle.debug(True)
else:
	bottle.debug(False)

# Setup
app = application = bottle.Bottle()

# Debug timing to improve speed
timeLabels = []
timeNums = []
def clearTime():
    timeLabels = []
    timeNums = []


def timeIt(label):
    timeLabels.append(label)
    timeNums.append(time.time())


def zipTimes():
    tN = []
    for i in xrange(0,len(timeNums)):
        if i==0:
            tN.append(0)
        else:
            tN.append(round(timeNums[i] - timeNums[i-1],3))
    return zip(timeLabels, tN)


# Helper function for handling bottle arguments and setting defaults:
def defaultValue(x,value = None):
    return x is not "" and x or value


#
# Web pages
#
# Pass through static content -- nginx should handle this, but if it doesn't, bottle will
@app.route('/static/<path:path>')
def callback(path):
    return bottle.static_file(path,"./static")


# Index
@app.route("/")
@app.route("/search/")
def index():
    clearTime()
    timeIt("begin")

    try:
        argDict = {}
        for k,v in bottle.request.params.iteritems():
            argDict[k] = v
    except:
        pass

    timeIt("assembleArgs")

    try:
        if "fromDate" in argDict:
            argDict["fromDate"] = argDict["fromDate"].replace("/","-")
            argDict["fromDate"] = re.sub(r"[^0-9\-\ ]", "", argDict["fromDate"])
        if "toDate" in argDict:
            argDict["toDate"] = argDict["toDate"].replace("/","-")
            argDict["toDate"] = re.sub(r"[^0-9\-\ ]", "", argDict["toDate"])
        if "fromCongress" in argDict:
            argDict["fromCongress"] = int(argDict["fromCongress"])
        if "toCongress" in argDict:
            argDict["toCongress"] = int(argDict["toCongress"])
        if "support" in argDict and "," in argDict["support"]:
            try:
                argDict["supportMin"], argDict["supportMax"] = [int(x) for x in argDict["support"].split(",")]
            except:
                pass
        elif "support" in argDict:
            try:
                support = int(argDict["support"])
                argDict["supportMin"] = support - 1
                argDict["supportMax"] = support + 1
            except:
                pass
        timeIt("doneAssembly")
        output = bottle.template("views/search", args=argDict, timeSet=zipTimes())
    except:
        output = bottle.template("views/error", errorMessage = traceback.format_exc())
        #errorMessage="Error: One or more of the parameters you used to call this page was misspecified.")

    return output

# Static Pages with no arguments, just passthrough the template.
# Really we should just cache these, but anyway.
@app.route("/about")
def about():
    output = bottle.template('views/about')
    return output


@app.route("/data")
def data():
    output = bottle.template("views/data")
    return output


@app.route("/research")
def research():
    output = bottle.template("views/research")
    return output


# Pages that have arguments
@app.route("/explore")
@app.route("/explore/<chamber:re:house|senate>")
def explore(chamber="house"):
    if chamber!="senate": # Security to prevent the argument being passed through being malicious.
        chamber = "house"

    output = bottle.template("views/explore",chamber=chamber)
    return output


@app.route("/congress")
@app.route("/congress/<chamber:re:house|senate>")
def congress(chamber="senate"):
    if chamber!="senate":
        chamber = "house"

    maxCongress = json.load(open("static/config.json","r"))["maxCongress"]
    congress = defaultValue(bottle.request.params.congress,maxCongress)

    output = bottle.template("views/congress", chamber=chamber, congress=congress, maxCongress=maxCongress)
    return output


@app.route("/parties")
@app.route("/parties/<party>/<congStart>")
@app.route("/parties/<party>")
def parties(party=200, congStart=-1):
	# Just default for now
	try:
		party = int(party)
	except:
		maxCongress = json.load(open("static/config.json","r"))["maxCongress"]
		output = bottle.template("views/partiesGlance", maxCongress=maxCongress)
		return output

	if congStart==-1:
		congStart = int(json.load(open("static/config.json","r"))["maxCongress"])
	else:
		try:
			congStart = int(congStart)
		except:
			congStart = 0

	if party not in xrange(0, 50001):
		party = 200
	partyData = model.partyData.getPartyName(party)
	if "fullName" in partyData:
		partyNameFull = partyData["fullName"]
	else:
		partyNameFull = ""
	
	output = bottle.template("views/parties", party=party, partyNameFull=partyNameFull, congStart=congStart)
	return output

def parties(party=200):
    # Just default for now
    try:
        party = int(party)
    except:
        if party=="all":
{'fraction_non_alphanumeric': 0.13732167510354348, 'fraction_numerical': 0.005614358030372756, 'mean_word_length': 3.3938536190861304, 'pattern_counts': {'":': 7, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3323231', 'n_tokens_mistral': 3483, 'n_tokens_neox': 3283, 'n_words': 830}