PushingScores/contextualise.py
2020-01-16 22:14:01 +00:00

407 lines
14 KiB
Python

# encoding=utf8
import sys
import pypandoc
import PyPDF2
from PyPDF2 import PdfFileMerger, PdfFileReader
from weasyprint import HTML, CSS
from weasyprint.fonts import FontConfiguration
from flask import send_file, Flask, Response, url_for, render_template, Markup, jsonify, redirect, request, flash, session, make_response
from config import Config
import json
import os
import datetime as dt
from datetime import datetime
from pprint import pprint
import re
from PIL import Image, ImageDraw, ImageFont
import numpy as np
from itertools import zip_longest
import collections
import random
import string
app = Flask(__name__, static_url_path='', static_folder="static", template_folder="templates")
app.jinja_env.add_extension('jinja2.ext.loopcontrols')
app.config.from_object(Config)
######################################################################################
# SETTING THE VARIABLES
######################################################################################
# setting variables for holding paths, folder names and the one file for description
path = "/static/files/"
jsonfiles = [] #json files
fullpathjsonfiles = [] #fullpath for some situations
listingfiles= [] #fullpaths
listingdirectories = [] #paths
thefile = None #selected file for description
positioninarray = 8 #counter
listofdicts=[] #to be able to import and use json content
datafromjson = []
max_wordpath_items = 500 # limit the nr. of items, as to prevent possible glitches with bots
pathofwords = []
pathofnumbers = []
#VARS FOR THE SESSIONS
# We don't want to store the secret key in git, but also don't really care what it is
# so generate it and store it to a file that's not in git:
current_dir = os.path.dirname(os.path.realpath(__file__))
secret_key_file = os.path.join(current_dir, 'secret.key')
if os.path.exists(secret_key_file):
with open(secret_key_file, 'r') as fp:
secret_key = fp.read()
else:
secret_key = ''.join(random.choice(string.ascii_lowercase) for i in range(100))
with open(secret_key_file, 'w') as fp:
fp.write(secret_key)
app.secret_key = secret_key
#app.config['SESSION_TYPE'] = 'filesystem' # works only for flask-session (we use native flask cookie-sessions)
def clearSession():
# Flask sessions are serialised into a cookie, so we cannot use the deque here
session['wordpath'] = []
session['clicktime'] = []
session['id'] = []
session['veryfirstnow'] = datetime.now().isoformat()
def setupSession():
# session should be configured from within request context
# so this function should be called on each request
if 'veryfirstnow' not in session:
clearSession()
# preparing the index.json file for the navbar
index_dict = {}
######################################################################################
#SOME JSON AND WALK OS REALTED THINGIES
######################################################################################
#reading wordlist.json
with open('wordlist.json', 'r', encoding='utf8') as f:
wordlist_dict = json.load(f)
#listing the json paths simultaneously generating a new index.json for the navbar
for path, subdirs, files in os.walk('./static/files/'):
for name in files:
if name.endswith(".json"):
fullpath = os.path.join(path, name)
jsonfiles.append(fullpath[8:])
fullpathjsonfiles.append(fullpath)
with open (fullpath) as f:
temp_dict = json.load(f)
index_dict[temp_dict["id"]] = temp_dict["title"]
######################################################################################
#NOW THE REAL DEAL
######################################################################################
@app.route("/")
def home():
setupSession()
return render_template('home.html', wordlist_dict=wordlist_dict)
def functionsession():
return(session)
# THIS IS NOT WORKING YET DUNNO WHY
@app.context_processor
def context_processor():
functionsession = session['wordpath']
return dict(functionsession=functionsession)
@app.route('/about/')
def about():
setupSession()
return render_template('about.html')
@app.route('/clear')
def clear():
# return to a refer if its set, default to root
return_url = request.environ.get("HTTP_REFERER", '/')
clearSession()
return redirect(return_url)
@app.route('/description')
def description():
setupSession()
idno=request.args.get('id')
jsonfilefordescription = "files/"+idno+"/"+idno+".json"
with open("static/"+jsonfilefordescription, 'r') as f:
data_dict = json.load(f)
datafromjson = data_dict["files"]
#open json file, list filepaths in array and loop with thefile
textfile=""
textfiles=[]
namefile=[]
with open("static/"+jsonfilefordescription, 'r') as f:
data_dict = json.load(f)
datafromjson = data_dict["files"]
itemid = data_dict["id"]
# a glitch of Flask sessions: if you do session['wordpath'].append() it creates an empty list
# hence we get it, append it, and set it.
# since Flask's session variables are json serialised (to be stored in a cookie), they do not
# support collections.deque, therefore we create that on each request to limit the items
ids = collections.deque(session['id'], maxlen=max_wordpath_items)
ids.append(itemid)
session["id"] = list(ids) # ... and therefore, we have to convert it back
for file in datafromjson:
if file.lower().endswith(('.html')):
namefile.append(file)
with open("static/"+file,"r", encoding='utf-8') as f:
textfile = f.read()
textfile = Markup(textfile)
textfiles.append(textfile)
return render_template('description.html', datafromjson=datafromjson, itemid=itemid, textfiles=textfiles, idno=idno, index_dict=index_dict, namefile=namefile)
@app.route('/diverge', methods=['GET'])
def diverge():
setupSession()
searchterm=request.args.get('search')
now = datetime.now() #description time
# a glitch of Flask sessions: if you do session['wordpath'].append() it creates an empty list
# hence we get it, append it, and set it.
wp = collections.deque(session['wordpath'], maxlen=max_wordpath_items)
wp.append(searchterm)
session['wordpath'] = list(wp)
clicktime = collections.deque(session['clicktime'], maxlen=max_wordpath_items)
clicktime.append(now.isoformat()) # make sure we have a determined format to stringify
session['clicktime'] = list(clicktime)
return render_template('diverge.html', wordlist_dict=wordlist_dict, searchterm=searchterm, index_dict=index_dict)
######################################################################################
#THE SCORE STUFF
######################################################################################
### Add : if score is empty then add some sentence like "your score is empty"
### to be printed to the text document
@app.route("/get-file")
def get_file():
setupSession()
fullscore = None
wordpath = session["wordpath"]
idlist = session["id"]
timelist = session["clicktime"]
veryfirstnow = session['veryfirstnow']
clickongetfiletime = datetime.now()
tadam = None
initialtime = None
# # USER IP ADDRESS OBTENTION
if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
userip = request.environ['REMOTE_ADDR']
else:
userip = request.environ['HTTP_X_FORWARDED_FOR'] # if behind a proxy
# Proxy might add multiple ips, take only one:
if ',' in userip:
userip = userip.split(',')[0]
# # CALCULATION OF INITIAL TIME BEFORE FIRST CLICK
if len(timelist) and not (timelist[0] is None):
thetime = timelist[0]
thetime = str(thetime)
print(thetime)
thetime = dt.datetime.strptime(thetime, "%Y-%m-%dT%H:%M:%S.%f")
firsttime = dt.datetime.strptime(veryfirstnow, "%Y-%m-%dT%H:%M:%S.%f")
initialtime = thetime - firsttime
initialtime = initialtime.total_seconds()
initialtime = int(initialtime)
initialtime = "."*initialtime
print(initialtime)
# #CALCULATE FILE NUMBER
dirListing = os.listdir("scores/")
scorenumber = len(dirListing)
# CONVERSION OF TIME INTO FORMATS THAT CAN BE USED FOR CALCULATIONS
timelistforoperations = []
for t in timelist :
t = str(t)
yo = dt.datetime.strptime(t, "%Y-%m-%dT%H:%M:%S.%f")
timelistforoperations.append(yo)
prev = None
wholestringy = None
# print("veryfirstnow : "+str(veryfirstnow)+"\n")
print(wordpath)
print(timelistforoperations)
print(idlist)
# WEAVING DELAYS AND WORDS TOGETHER AS A HUGE STRING OF CHARACTERS
for (word, time) in zip(wordpath,timelistforoperations):
upperword = word.upper()
#get previous time for substraction
if not (prev is None):
difftime = time - prev
difftime = difftime.total_seconds()
difftime = int(difftime)
# print(difftime)
else:
yo = str(veryfirstnow)
yoyo = dt.datetime.strptime(yo, '%Y-%m-%dT%H:%M:%S.%f')
difftime = time - yoyo
difftime = difftime.total_seconds()
difftime = int(difftime)
test = difftime
prev = time
diffpattern = test * '.'
stringy = diffpattern + upperword
if not (wholestringy is None):
wholestringy = wholestringy+stringy
fullscore = wholestringy
else:
wholestringy = upperword
fullscore = wholestringy
if not (fullscore is None):
# outside of the loop calculate seconds from "clickongetfiletime" minus the last "time" from the loop
lastdifftime = clickongetfiletime - prev
lastdifftime = lastdifftime.total_seconds()
lastdifftime = int(lastdifftime)
lastdifftime = lastdifftime * '.'
#the 60 seconds thing
# print(lastdifftime+"\n")
fullscore = initialtime+fullscore+lastdifftime
# Defining splitting point
n = 60
# Using list comprehension
out = [(fullscore[i:i+n]) for i in range(0, len(fullscore), n)]
#joining the strings with linebreaks
# tadam = '\n'.join(out) +"\n\n\n\nScore number : "+str(scorenumber)+ "\nGenerated at : "+str(clickongetfiletime)+"\nBy author : "+ userip
tadam = '\n'.join(out)
# have a message in file if no nav has been recorded so it's less dull than error page
if tadam is None:
tadam = "This score is Null"
uniquename = str(clickongetfiletime)
# with open('scores/'+uniquename+'.txt', 'a+') as f:
# f.write(tadam)
# print(tadam)
###### SCORE FIST PAGE
globalname = "Pushing scores"
print(tadam)
scorefirstpage = '''<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="static/css/stylepandoc.css">
</head>
<body>
<style>
body{background-color:magenta;}
</style>
<div id="coverpage">
<div class="infos scorenumber">SCORE #'''+str(scorenumber)+'''</div>
<div class="infos author">By '''+userip+'''</div>
<!--<div class="infos globalname">Part of the Pushing Scores series</div>-->
<div class="infos publisher">Part of the <i>Pushing Scores</i> series<br>
Published and distributed by <img src="static/logo/logo.png"></div>
<div class="infos time">On '''+str(clickongetfiletime)+'''</div>
</div>
</body>
</html>
'''
scorecontentpage = '''<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="static/css/stylepandoc.css">
</head>
<body>
<div id="scorecontentpage">
{}
</div>
</body>
</html>
'''.format(tadam)
############# GENERATE SCORE PDF
pathnamefilepdf = "scores/"+uniquename+"test.pdf"
font_config = FontConfiguration()
HTML(string=scorecontentpage, base_url='./').write_pdf(pathnamefilepdf, stylesheets=[CSS('static/css/stylepandoc.css', font_config=font_config)], font_config=font_config)
############# GENERATE FIRST PAGE PDF
pathnamefilecoverpdf = "scores/"+uniquename+"testcover.pdf"
font_config = FontConfiguration()
HTML(string=scorefirstpage, base_url='./').write_pdf(pathnamefilecoverpdf, stylesheets=[CSS('static/css/stylepandoc.css', font_config=font_config)], font_config=font_config)
############# ASSEMBLE PDFS
merger = PdfFileMerger()
file1 = open(pathnamefilecoverpdf,"rb")
file2 = open(pathnamefilepdf,"rb")
pdf1 = PyPDF2.PdfFileReader(file1)
pdf2 = PyPDF2.PdfFileReader(file2)
pdf1_pages = pdf1.getNumPages()
pdf2_pages = pdf2.getNumPages()
outputfile = open("scores/"+uniquename+".pdf", "wb")
writer = PyPDF2.PdfFileWriter()
for i in range(pdf1_pages):
writer.addPage(pdf1.getPage(i))
for j in range(pdf2_pages):
writer.addPage(pdf2.getPage(j))
writer.write(outputfile)
file1.close()
file2.close()
outputfile.close()
clearSession()
os.remove(pathnamefilecoverpdf)
os.remove(pathnamefilepdf)
print("files removed")
try:
return send_file("scores/"+uniquename+".pdf", attachment_filename="olala.pdf")
except Exception as e:
return str(e)
######################################################################################
#INDEX PAGE
######################################################################################
@app.route("/index")
def index():
return render_template('theindex.html', wordlist_dict=wordlist_dict, index_dict=index_dict)
if __name__ == '__main__':
app.run(debug=True)