ventilaar
/
twitter_zuil
Archived
1
Fork 0
This repository has been archived on 2021-06-10. You can view files and clone it, but cannot push or open issues or pull requests.
twitter_zuil/moderator_gui.py

515 lines
17 KiB
Python

from flask import Flask, request, render_template, session, redirect, url_for, flash
from TwitterAPI import TwitterAPI
from api_keys import *
import database_connector
import hashlib
import secrets
import datetime
"""
test var, het het nogmaal gesproken op False
"""
debug = False
"""
database objecten, om minder te typen
"""
conn = database_connector.conn
cur = database_connector.cur
"""
stel flask in en twitter api in
"""
app = Flask(__name__)
twitter_API = TwitterAPI(TWITTER_APIKEY, TWITTER_APISECRET, TWITTER_ACCESSTOKEN, TWITTER_ACCESSSECRET)
"""
als debug op true is een vaste secret key gebruiken, dit is zodat we niet elke keer in hoefen te loggen na een
code wijziging. Maar in productie elke start een nieuwe token genereren
"""
if debug == True:
app.secret_key = 'jdndhsyh83r90hfeqwf' # dit is om live te testen
else:
app.secret_key = secrets.token_hex(32)
"""
deze functie checkt de username en password die worden doorgegeven.
Als beide juist zijn geeft de functie True terug, anders False met een flash
"""
def func_check_login(uname, pword):
hashedpass = hashlib.sha256(pword.encode('UTF-8') + 'saltandpepper'.encode('UTF-8')).hexdigest()
cur.execute("SELECT * FROM moderators WHERE naam = (%s);", [uname])
sqlreturn = cur.fetchone()
if sqlreturn == None:
flash('Gebruiker niet gevonden')
return False
elif hashedpass != sqlreturn[2]:
flash('Uw wachtwoord is fout')
return False
elif sqlreturn[3] != True:
flash('Dit account mag niet meer inloggen')
return False
else:
return True
"""
Deze functie weergeeft alle moderator info in een geneste tuple.
Accepteert maximale aantal rijen en pagina in int
"""
def func_listmoderators(limit, page):
cur.execute('SELECT * FROM moderators LIMIT (%s) OFFSET (%s)', (limit, page))
allmoderators = cur.fetchall()
cur.execute('SELECT COUNT(*) FROM moderators')
countmoderators = cur.fetchone()
return (allmoderators, countmoderators)
"""
Deze functie voegt een moderator toe, checkt eerst of wachtwoord aan eisen voldoet en of beide wachtwoorden hetzelfde
zijn. Daarna de gebruikersnaam checken of die niet bestaat, anders geeft de functie False terug met een flash.
Als de gebruikersnaam niet bestaat hasht de functie de wachtwoord en voegt het toe in de database met als return True.
"""
def func_addmoderator(uname, pword, pword2):
username = uname.lower()
password = pword
password2 = pword2
if len(password) < 4:
flash('Wachtwoord lengte is te weinig, gebruik minimaal 4 tekens!')
return False
elif password != password2:
flash('Wachtwoorden zijn niet hetzelfde!')
return False
if len(username) > 64 or len(username) < 3:
flash('Gebruikersnaam lengte is ongeldig, gebruik minimaal 3 en maximaal 64 tekens!')
return False
elif ' ' in username:
flash('Gebruikersnaam bevat spatie, dat mag niet')
return False
cur.execute("SELECT naam FROM moderators WHERE naam = (%s);", (username,))
sqlreturn = cur.fetchone()
if sqlreturn == None:
hashedpass = hashlib.sha256(password.encode('UTF-8') + 'saltandpepper'.encode('UTF-8')).hexdigest()
cur.execute("INSERT INTO moderators(naam, hash, maylogin) VALUES (%s, %s, 'true')", (username, hashedpass))
conn.commit()
flash('Account voor ' + username + ' aangemaakt!')
return True
else:
flash('Probleem met de database, bestaat de gebruiker al?')
return False
"""
Deze functie probeert een gegeven moderator te verwijderen. Als de moderator berichten heeft gemodereert kan de account
niet verwijdert worden. Dit komt door database restricties. Daarvoor zet de functie in de regel maylogin op false.
"""
def func_removemoderator(moderatorid):
try:
cur.execute('DELETE FROM moderators WHERE moderatorid = (%s)', [moderatorid])
conn.commit()
flash('Moderator account verwijdert')
return True
except:
conn.rollback()
try:
cur.execute('UPDATE moderators SET maylogin = false WHERE moderatorid = (%s)', [moderatorid])
conn.commit()
flash('Account kan niet verwijdert worden, account nu mag niet meer inloggen')
return True
except:
conn.rollback()
flash('Probleem opgetreden bij het aanpassen van moderator account')
return False
"""
deze functie haalt net zoals bij moderators alle berichten op gesorteert op de laatste ontvangen. Overigens worden
de kolomen ook met andere tabellen gejoined voor mooiere waardes.
Deze functie returnt een tuple met op 0 geneste dicts met berichten en op 1 de totaal aantal berichten in het systeem.
"""
def func_listberichten(limit, page):
cur.execute('SELECT berichten.berichtid, berichten.bericht, berichten.datumontvangen, berichten.naamposter, '
'berichten.datumgekeurd, locaties.naam, moderators.naam, statuses.status, berichten.twitterid '
'FROM berichten '
'LEFT OUTER JOIN statuses ON berichten.statusid = statuses.statusid '
'LEFT OUTER JOIN locaties ON berichten.locatieid = locaties.locatieid '
'LEFT OUTER JOIN moderators ON berichten.moderatorid = moderators.moderatorid '
'ORDER BY datumontvangen DESC LIMIT (%s) OFFSET (%s)', (limit, page))
allberichten = cur.fetchall()
cur.execute('SELECT COUNT(*) FROM berichten')
countberichten = cur.fetchone()
return (allberichten, countberichten)
"""
Deze functie haalt netzoals listberichten zelfda waarden op. maar dan met 1 bericht, en dus accepteert berichtid
"""
def func_querybericht(berichtid):
cur.execute('SELECT berichten.berichtid, berichten.bericht, berichten.datumontvangen, berichten.naamposter, '
'berichten.datumgekeurd, locaties.naam, moderators.naam, statuses.status, berichten.twitterid '
'FROM berichten '
'LEFT OUTER JOIN statuses ON berichten.statusid = statuses.statusid '
'LEFT OUTER JOIN locaties ON berichten.locatieid = locaties.locatieid '
'LEFT OUTER JOIN moderators ON berichten.moderatorid = moderators.moderatorid '
'WHERE berichtid = (%s)', [berichtid])
return cur.fetchone()
"""
Dit is de belangerijkste functie. Hier worden berichten opgehaalt om te modereren
1. Haal 1 oudste bericht uit de database met een paar joins uit andere tabellen
2. variabele bericht None is, flash en return False
3. Accepteer moderatornaam, en haal de moderatorid uit de database
4. Update de bericht met de juiste status code en moderatorid
deze functie returnt de bericht als tuple
"""
def func_autoqueuebericht(moderatornaam):
cur.execute('SELECT berichten.berichtid, berichten.bericht, berichten.datumontvangen, berichten.naamposter, '
'locaties.naam, statuses.status '
'FROM berichten '
'LEFT OUTER JOIN statuses ON berichten.statusid = statuses.statusid '
'LEFT OUTER JOIN locaties ON berichten.locatieid = locaties.locatieid '
'LEFT OUTER JOIN moderators ON berichten.moderatorid = moderators.moderatorid '
'WHERE berichten.statusid = 1 ORDER BY datumontvangen LIMIT 1')
bericht = cur.fetchone()
if bericht == None:
flash('Er zijn geen berichten meer om te keuren, probeer het later opnieuw')
return False
cur.execute('SELECT moderatorid FROM moderators WHERE naam = (%s)', [moderatornaam])
moderatorid = cur.fetchone()[0]
cur.execute('UPDATE berichten SET statusid = 2, moderatorid = (%s) WHERE berichtid = (%s)', (moderatorid, bericht[0]))
conn.commit()
return bericht
"""
ontvangt bericht id en zet moderatorid op null en statusid op 1
"""
def func_unlockbericht(berichtid):
cur.execute("UPDATE berichten SET statusid = 1, moderatorid = NULL WHERE berichtid = (%s)", [berichtid])
conn.commit()
return True
"""
Ontvangt berichtid, genereert YY-MM-DD HH:MM:SS in utc en zet dat in de berichtid, wijzigt ook statuscode naar accepted
"""
def func_messageaccept(berichtid):
date = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
QUERY = "UPDATE berichten SET statusid = 4, datumgekeurd = (%s) WHERE berichtid = (%s)"
DATA = (date, berichtid)
cur.execute(QUERY, DATA)
conn.commit()
return True
"""
Ontvangt berichtid, genereert YY-MM-DD HH:MM:SS in utc en zet dat in de berichtid,wijzigt ook statuscode naar rejected
"""
def func_messagereject(berichtid):
date = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
QUERY = "UPDATE berichten SET statusid = 3, datumgekeurd = (%s) WHERE berichtid = (%s)"
DATA = (date, berichtid)
cur.execute(QUERY, DATA)
conn.commit()
return True
"""
ontvangt berichtid en publiceert het naar twitter blah blah verder noteren later
"""
def func_publish_twitter(berichtid):
cur.execute('SELECT berichten.berichtid, berichten.bericht, berichten.naamposter, locaties.naam '
'FROM berichten '
'LEFT OUTER JOIN locaties ON berichten.locatieid = locaties.locatieid '
'WHERE berichtid = (%s)', [berichtid])
bericht = cur.fetchone()
formatted = str(bericht[1] + ' | Door ' + bericht[2] + ' op ' + bericht[3])
response = twitter_API.request('statuses/update', {'status': formatted})
jsonresponse = response.json()
if response.status_code == 200:
QUERY = 'INSERT INTO twitterberichten(twitterid, datumpublished) VALUES (%s, %s)'
DATA = (jsonresponse['id'], jsonresponse['created_at'])
cur.execute(QUERY, DATA)
QUERY = 'UPDATE berichten SET twitterid = (%s), statusid = 5 WHERE berichtid = (%s)'
DATA = (jsonresponse['id'], berichtid)
cur.execute(QUERY, DATA)
conn.commit()
return True
else:
return False
"""
Deze functie haalt alle locaties op
"""
def func_listlocaties(limit, page):
cur.execute('SELECT * FROM locaties LIMIT (%s) OFFSET (%s)', (limit, page))
allmoderators = cur.fetchall()
cur.execute('SELECT COUNT(*) FROM locaties')
countmoderators = cur.fetchone()
return (allmoderators, countmoderators)
"""
deze functie voegt een locatie toe in de database
"""
def func_addlocatie(lid, lname):
try:
lid = int(lid)
except:
flash('Locatie ID is geen cijfer')
if lid > 8:
flash('Locatie Id is te lang, houd het korter dan 8 characters')
return False
cur.execute("SELECT locatieid FROM locaties WHERE locatieid = (%s);", [lid])
sqlreturn = cur.fetchone()
if sqlreturn == None:
cur.execute("INSERT INTO locaties(locatieid, naam) VALUES (%s, %s)", (lid, lname))
conn.commit()
flash('Locatie toegevoegd!')
return True
else:
flash('Probleem met de database, bestaat de locatie id al?')
return False
"""
en nu naar flask, dit is gewoon de root page
"""
@app.route('/')
def root():
return render_template('root.html')
"""
de login pagina, accepteert GET en POST, als het GET is met een sessie cookie, invalideert het eerst de sessie cookie
en returnt daarna de login page. als het een POST is, roept het gelijk func_check_login aan met username en wachtwoord
als het successfol is zet het een sessie cookie in. anders krijgt de gebruikers een flash
"""
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
if func_check_login(request.form['uname'], request.form['pword']):
session['username'] = request.form['uname']
return redirect(url_for('home'))
else:
return render_template('login.html')
else:
if 'username' in session:
session.pop('username', None)
flash('You logged out!')
return render_template('login.html')
@app.route('/home')
def home():
if 'username' in session:
return render_template('home.html', username=session['username'])
else:
flash('You are not logged in!')
return redirect(url_for('login'))
"""
moderator functies
"""
@app.route('/moderators')
def moderators():
if 'username' in session:
if request.args.get('maxitems'):
maxitems = int(request.args.get('maxitems'))
else:
maxitems = 10
if request.args.get('pagenum'):
pagenum = int(request.args.get('pagenum')) - 1
else:
pagenum = 0
page = maxitems * pagenum
listreturn = func_listmoderators(maxitems, page)
moderators = listreturn[0]
moderatorcount = listreturn[1][0]
return render_template('moderators.html', moderators=moderators, moderatorcount=moderatorcount)
else:
flash('You are not logged in!')
return redirect(url_for('login'))
@app.route('/moderators/addmoderator', methods=['POST'])
def addmoderator():
if 'username' in session:
if func_addmoderator(request.form['uname'], request.form['pword'], request.form['pword2']):
return redirect(url_for('moderators'))
else:
return redirect(url_for('moderators'))
else:
flash('You are not logged in!')
return redirect(url_for('login'))
@app.route('/moderators/removemoderator', methods=['POST'])
def listmoderators():
if 'username' in session:
if func_removemoderator(request.form['delete']):
return redirect(url_for('moderators'))
else:
return redirect(url_for('moderators'))
else:
flash('You are not logged in!')
return redirect(url_for('login'))
"""
bericht listing functies
"""
@app.route('/berichten')
def berichten():
if 'username' in session:
if request.args.get('maxitems'):
maxitems = int(request.args.get('maxitems'))
else:
maxitems = 10
if request.args.get('pagenum'):
pagenum = int(request.args.get('pagenum')) - 1
else:
pagenum = 0
page = maxitems * pagenum
listreturn = func_listberichten(maxitems, page)
berichten = listreturn[0]
berichtcount = listreturn[1][0]
return render_template('berichten.html', berichten=berichten, berichtcount=berichtcount)
else:
flash('You are not logged in!')
return redirect(url_for('login'))
@app.route('/bericht/<berichtid>')
def bericht(berichtid):
if 'username' in session:
bericht = func_querybericht(berichtid)
return render_template('bericht.html', bericht=bericht)
else:
flash('You are not logged in!')
return redirect(url_for('login'))
"""
autoqueue functies
"""
@app.route('/autoqueue', methods=['GET', 'POST'])
def autoqueue():
if 'username' in session:
if request.method == 'POST':
if func_unlockbericht(request.form['stop']):
return redirect(url_for('home'))
else:
flash('probleem met het unlocken van het bericht')
return redirect(url_for('home'))
else:
bericht = func_autoqueuebericht(session['username'])
if bericht == False:
return redirect(url_for('home'))
return render_template('autoqueue.html', bericht=bericht)
else:
flash('You are not logged in!')
return redirect(url_for('login'))
@app.route('/autoqueue/accept', methods=['POST'])
def autoqueue_accept():
if 'username' in session:
if func_messageaccept(request.form['good']):
if func_publish_twitter(request.form['good']):
return redirect(url_for('autoqueue'))
else:
flash('Probleem met het publiceren op twitter')
return redirect(url_for('autoqueue'))
else:
flash('Probleem met het opslaan van de moderatie')
return redirect(url_for('autoqueue'))
else:
flash('You are not logged in!')
return redirect(url_for('login'))
@app.route('/autoqueue/reject', methods=['POST'])
def autoqueue_reject():
if 'username' in session:
if func_messagereject(request.form['bad']):
return redirect(url_for('autoqueue'))
else:
flash('Probleem met het opslaan van de moderatie')
return redirect(url_for('autoqueue'))
else:
flash('You are not logged in!')
return redirect(url_for('login'))
"""
locatie functies
"""
@app.route('/locaties')
def locaties():
if 'username' in session:
if request.args.get('maxitems'):
maxitems = int(request.args.get('maxitems'))
else:
maxitems = 10
if request.args.get('pagenum'):
pagenum = int(request.args.get('pagenum')) - 1
else:
pagenum = 0
page = maxitems * pagenum
listreturn = func_listlocaties(maxitems, page)
locaties = listreturn[0]
locatiecount = listreturn[1][0]
return render_template('locaties.html', locaties=locaties, locatiecount=locatiecount)
else:
flash('You are not logged in!')
return redirect(url_for('login'))
@app.route('/locaties/addlocatie', methods=['POST'])
def addlocatie():
if 'username' in session:
if func_addlocatie(request.form['lid'], request.form['lname']):
return redirect(url_for('locaties'))
else:
return redirect(url_for('locaties'))
else:
flash('You are not logged in!')
return redirect(url_for('login'))
if __name__ == "__main__":
app.run('0.0.0.0', port=5001, debug=debug)