<commit_before>#TODO: Add error catching
from flask import Flask, request, redirect, url_for, render_template, session
from flask.ext.sqlalchemy import SQLAlchemy
from subprocess import Popen, PIPE
import re, requests, os, subprocess, signal

global userToken, CLIENTID, CLIENTSECRET, botProcess
CLIENTID = os.environ["CLIENTID"]
CLIENTSECRET = os.environ["CLIENTSECRET"]
SECRET_KEY = os.environ["SECRET_KEY"]

userToken = None
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ["DATABASE_URL"]#'postgresql://localhost/test.db'
db = SQLAlchemy(app)
botProcess = None
redirect_uri = 'http://zojibot.herokuapp.com/login'


class User(db.Model):
    id = db.Column(db.Integer, unique = True)
    username = db.Column(db.String(80), primary_key = True)
    #commandSet = db.Column(db.String(5000), unique = False)
    commandSet = db.relationship('Command', backref='commands')


    def __init__(self, username):
        self.username = username
        #self.commandSet = 'None'

    def __repr__(self):
        return '<User %r>' % self.username

class Command(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(80), db.ForeignKey('user.username'))
    comm = db.Column(db.String(1000), unique=False)
    response = db.Column(db.String(1000), unique=False)

    def editCommand(newResponse):
        self.response = newResponse

    def __init__(self, username, comm, response):
        self.username = username
        self.comm = comm
        self.response = response

    def __repr__(self):
        return 'Username: %s Command: %s Response: %s Command ID: %s' % (self.username, self.comm, self.response, self.id)

def parseCurlForUsername(f):#strip the username out of the json response
    match = re.search("\"user_name\":\s*\"(\w+)\"", f)
    if match != None:
        return str(match.group(1))
    else:
        print 'Returning username as None'
        return None

def parseCurlForAuthToken(f):#get client token from json response
    print 'Searching through: ' + f
    match = re.search("\"access_token\":\s*\"(.*?)\",", f) #might have to change to specificify alphanumeric
    if match != None:
        return str(match.group(1))
    else:
        print 'Returning auth token as None'
        return None

#HomePage
@app.route('/')
def index():
    if 'username' in session:
        return redirect('/dashboard/')
    #return 'Index page<br><a href="/login">Login here</a>'
    return render_template('index.html')

#ErrorPage
@app.route('/error/')
def error():
    return 'Got an error'

#LoginPage
@app.route('/login/') #use redirect() to redirect user TODO: might want to move the userCode part to a /callback/ page
def login():#TODO: add some try/catches around file stuff and curl stuff
    global userToken, CLIENTID, CLIENTSECRET
    userCode = request.args.get('code')
    print 'userCode: '+str(userCode)
    if userCode != None: #got redirect from twitch
        print 'In /login with userCode'
        urlParams = {'client_id':CLIENTID, 'client_secret':CLIENTSECRET, 'grant_type':'authorization_code', 'redirect_uri':redirect_uri, 'code':str(userCode)}
        r = requests.post('https://api.twitch.tv/kraken/oauth2/token', params = urlParams)
        print 'Parsing response: '+r.text
        userToken = parseCurlForAuthToken(r.text)
        if userToken != None:
            print 'Got user token back it\'s '+userToken
            headers = {'Accept':'application/vnd.twitchtv.v2+json', 'Authorization': 'OAuth '+userToken}
            rq = requests.get('https://api.twitch.tv/kraken', headers = headers)
            print 'Getting username from ' + rq.text
            username = parseCurlForUsername(rq.text)
            print 'Got username back, it\'s '+username
            if username != None:
                try:
                    name = User.query.get(username)
                    print 'Found name ' + str(name)+ ' in database'
                    if name == None:
                        print 'Name was none'
                        print 'Adding new user ' + username + ' to database'
                        newUser = User(username)
                        db.session.add(newUser)
                        db.session.commit()
                except Exception as e:
                    print 'Exception: '+str(e)
                    print 'Adding new user ' + username + ' to database'
                    newUser = User(username)
                    db.session.add(newUser)
                    db.session.commit()
                print 'Sessioning username: '+username

                try:
                    session['username'] = username
                except Exception as e:
                    print 'Error: '+str(e)
                    return redirect('/error/')
                print 'Redirecting to profile'
                return redirect('/dashboard/')
            else:#error
                print 'Error: username not parsed'
        else:#error getting token
            print 'Error: Token not received'
    else: #need to inform&redirect user to twitch or check for cookie&send to user
        #redirect
        redirectURL = r'https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id='+CLIENTID+r'&redirect_uri='+redirect_uri#&scope=[space separated list of scopes]
        print "Printing for posterity:\nClientid: "+CLIENTID+"\nURL: "+redirectURL
        return redirect(redirectURL)

#StartBotPage
@app.route('/start/')
def startbot():
    global botProcess

    if 'username' in session:
        username = session['username']
        if botProcess == None:
            print 'STARTING BOT'
            botProcess = subprocess.Popen('python bot.py '+username, shell=True, preexec_fn=os.setsid).pid
    return redirect('/dashboard/')

#StopBotPage
@app.route('/stop/')
def stopbot():
    global botProcess

    if 'username' in session:
        if botProcess != None:
            try:
                print 'STOPPING BOT'
                #botProcess.kill()
                os.killpg(botProcess, signal.SIGTERM)
                botProcess = None
            except Exception as e:
                return 'Error: '+str(e)
    return redirect('/dashboard/')

#DashboardPage
@app.route('/dashboard/')#TODO: add command editing and saving, then restart bot; Also need to put user check for people already logged in when database resets;
def profile():
    global botProcess

        #TODO: Add in database stuff
    if 'username' in session:
        username = session['username']
        #check request to start bot
        #result = 'Hello, ' + username + '<br> <a href="/edit/">Edit</a><br> Add new command: <br><form action="/add/"> Command: <input type="text" name="command"><br>Response:<input type="text" name="response"><br><input type="submit" value="Submit"></form>'
        action = ''
        value = ''
        text = ''
        status = ''
        if botProcess == None: #TODO: Do a checkup on bot status (maybe later w/ javascript?)
            #button = 'Bot status: Stopped<br><form action="/start/"> <button type="submit" name="bot" value="start">Start bot</button></form>'
            status = 'Stopped'
            action = r'"/start/"'
            value = "start"
            text = "Start bot"
        else:
            #button = 'Bot status: Started<br><form action="/stop/"> <button type="submit" name="bot" value="stop">Stop bot</button></form>'
            status = 'Running'
            action = r'"/stop/"'
            value = "stop"
            text = "Stop bot"
        #return result+'<br><a href="/logout/">Logout</a>'
        return render_template('dashboard.html', username=username, action=action, value=value, text=text, status=status)

    else: #no username in session
        return render_template('login_redirect.html')


#AddCommandPage
@app.route('/add/') #TODO: Add in duplicate check
def addCommand():

    if 'username' in session:
        username = session['username']
        command = request.args.get('command')
        response = request.args.get('response')
        print 'Adding command: '+command
        try:
            if command != '!edit':
                duplicate = Command.query.filter_by(username=username, comm=command).first()<commit_msg>Again<commit_after>#TODO: Add error catching
from flask import Flask, request, redirect, url_for, render_template, session
from flask.ext.sqlalchemy import SQLAlchemy
from subprocess import Popen, PIPE
import re, requests, os, subprocess, signal

global userToken, CLIENTID, CLIENTSECRET, botProcess
CLIENTID = os.environ["CLIENTID"]
CLIENTSECRET = os.environ["CLIENTSECRET"]
SECRET_KEY = os.environ["SECRET_KEY"]

userToken = None
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ["DATABASE_URL"]#'postgresql://localhost/test.db'
db = SQLAlchemy(app)
botProcess = None
redirect_uri = 'http://zojibot.herokuapp.com/login'


class User(db.Model):
    id = db.Column(db.Integer, unique = True)
    username = db.Column(db.String(80), primary_key = True)
    #commandSet = db.Column(db.String(5000), unique = False)
    commandSet = db.relationship('Command', backref='commands')


    def __init__(self, username):
        self.username = username
        #self.commandSet = 'None'

    def __repr__(self):
        return '<User %r>' % self.username

class Command(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(80), db.ForeignKey('user.username'))
    comm = db.Column(db.String(1000), unique=False)
    response = db.Column(db.String(1000), unique=False)

    def editCommand(newResponse):
        self.response = newResponse

    def __init__(self, username, comm, response):
        self.username = username
        self.comm = comm
        self.response = response

    def __repr__(self):
        return 'Username: %s Command: %s Response: %s Command ID: %s' % (self.username, self.comm, self.response, self.id)

def parseCurlForUsername(f):#strip the username out of the json response
    match = re.search("\"user_name\":\s*\"(\w+)\"", f)
    if match != None:
        return str(match.group(1))
    else:
        print 'Returning username as None'
        return None

def parseCurlForAuthToken(f):#get client token from json response
    print 'Searching through: ' + f
    match = re.search("\"access_token\":\s*\"(.*?)\",", f) #might have to change to specificify alphanumeric
    if match != None:
        return str(match.group(1))
    else:
        print 'Returning auth token as None'
        return None

#HomePage
@app.route('/')
def index():
    if 'username' in session:
        return redirect('/dashboard/')
    #return 'Index page<br><a href="/login">Login here</a>'
    return render_template('index.html')

#ErrorPage
@app.route('/error/')
def error():
    return 'Got an error'

#LoginPage
@app.route('/login/') #use redirect() to redirect user TODO: might want to move the userCode part to a /callback/ page
def login():#TODO: add some try/catches around file stuff and curl stuff
    global userToken, CLIENTID, CLIENTSECRET
    userCode = request.args.get('code')
    print 'userCode: '+str(userCode)
    if userCode != None: #got redirect from twitch
        print 'In /login with userCode'
        urlParams = {'client_id':CLIENTID, 'client_secret':CLIENTSECRET, 'grant_type':'authorization_code', 'redirect_uri':redirect_uri, 'code':str(userCode)}
        r = requests.post('https://api.twitch.tv/kraken/oauth2/token', params = urlParams)
        print 'Parsing response: '+r.text
        userToken = parseCurlForAuthToken(r.text)
        if userToken != None:
            print 'Got user token back it\'s '+userToken
            headers = {'Accept':'application/vnd.twitchtv.v2+json', 'Authorization': 'OAuth '+userToken}
            rq = requests.get('https://api.twitch.tv/kraken', headers = headers)
            print 'Getting username from ' + rq.text
            username = parseCurlForUsername(rq.text)
            print 'Got username back, it\'s '+username
            if username != None:
                try:
                    name = User.query.get(username)
                    print 'Found name ' + str(name)+ ' in database'
                    if name == None:
                        print 'Name was none'
                        print 'Adding new user ' + username + ' to database'
                        newUser = User(username)
                        db.session.add(newUser)
                        db.session.commit()
                except Exception as e:
                    print 'Exception: '+str(e)
                    print 'Adding new user ' + username + ' to database'
                    newUser = User(username)
                    db.session.add(newUser)
                    db.session.commit()
                print 'Sessioning username: '+username

                try:
                    session['username'] = username
                except Exception as e:
                    print 'Error: '+str(e)
                    return redirect('/error/')
                print 'Redirecting to profile'
                return redirect('/dashboard/')
            else:#error
                print 'Error: username not parsed'
        else:#error getting token
            print 'Error: Token not received'
    else: #need to inform&redirect user to twitch or check for cookie&send to user
        #redirect
        redirectURL = r'https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id='+CLIENTID+r'&redirect_uri='+redirect_uri#&scope=[space separated list of scopes]
        print "Printing for posterity:\nClientid: "+CLIENTID+"\nURL: "+redirectURL
        return redirect(redirectURL)

#StartBotPage
@app.route('/start/')
def startbot():
    global botProcess

    if 'username' in session:
        username = session['username']
        if botProcess == None:
            print 'STARTING BOT'
            botProcess = subprocess.Popen('python bot.py '+username, shell=True, preexec_fn=os.setsid).pid
    return redirect('/dashboard/')

#StopBotPage
@app.route('/stop/')
def stopbot():
    global botProcess

    if 'username' in session:
        if botProcess != None:
            try:
                print 'STOPPING BOT'
                #botProcess.kill()
                os.killpg(botProcess, signal.SIGTERM)
                botProcess = None
            except Exception as e:
                return 'Error: '+str(e)
    return redirect('/dashboard/')

#DashboardPage
@app.route('/dashboard/')#TODO: add command editing and saving, then restart bot; Also need to put user check for people already logged in when database resets;
def profile():
    global botProcess

        #TODO: Add in database stuff
    if 'username' in session:
        username = session['username']
        #check request to start bot
        #result = 'Hello, ' + username + '<br> <a href="/edit/">Edit</a><br> Add new command: <br><form action="/add/"> Command: <input type="text" name="command"><br>Response:<input type="text" name="response"><br><input type="submit" value="Submit"></form>'
        action = ''
        value = ''
        text = ''
        status = ''
        if botProcess == None: #TODO: Do a checkup on bot status (maybe later w/ javascript?)
            #button = 'Bot status: Stopped<br><form action="/start/"> <button type="submit" name="bot" value="start">Start bot</button></form>'
            status = 'Stopped'
            action = '/start/'
            value = "start"
            text = "Start bot"
        else:
            #button = 'Bot status: Started<br><form action="/stop/"> <button type="submit" name="bot" value="stop">Stop bot</button></form>'
            status = 'Running'
            action = '/stop/'
            value = "stop"
            text = "Stop bot"
        #return result+'<br><a href="/logout/">Logout</a>'
        return render_template('dashboard.html', username=username, action=action, value=value, text=text, status=status)

    else: #no username in session
        return render_template('login_redirect.html')


#AddCommandPage
@app.route('/add/') #TODO: Add in duplicate check
def addCommand():

    if 'username' in session:
        username = session['username']
        command = request.args.get('command')
        response = request.args.get('response')
        print 'Adding command: '+command
        try:
            if command != '!edit':
                duplicate = Command.query.filter_by(username=username, comm=command).first()
{'fraction_non_alphanumeric': 0.12662219526986052, 'fraction_numerical': 0.0025469981807155853, 'mean_word_length': 2.525978191148172, 'pattern_counts': {'":': 4, '<': 61, '<?xml version=': 0, '>': 61, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1134468', 'n_tokens_mistral': 4786, 'n_tokens_neox': 4630, 'n_words': 1293}