initial commit - old code

This commit is contained in:
Neythen 2021-04-26 19:51:21 +01:00
commit 086b22e776
90 changed files with 466 additions and 0 deletions

BIN
EncodeSans.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
csv/.DS_Store vendored Normal file

Binary file not shown.

BIN
csv/._.DS_Store Normal file

Binary file not shown.

BIN
csv/._new Normal file

Binary file not shown.

BIN
csv/._tickers.csv Normal file

Binary file not shown.
1 ����Mac OS X ���� ���2��°�����â������������������������������������ATTR šÉÿ��â���˜���9������������������˜���9��com.apple.quarantine�0083 60819962 Safari 8436C4B7-83A8-48AB-8121-A0495E899FD4��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This resource fork intentionally left blank �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÿÿ

3
csv/tickers.csv Normal file
View File

@ -0,0 +1,3 @@
MSFT,NFLX,GOOG,TSLA,AAPL,INTC,TXN,HPQ,HOG,LUV,WMT
MSFT,NFLX,GOOG,TSLA,AAPL,INTC,TXN,HPQ,HOG,LUV,WMT
MSFT,NFLX,GOOG,TSLA,AAPL,INTC,TXN,HPQ,HOG,LUV,WMT
1 MSFT NFLX GOOG TSLA AAPL INTC TXN HPQ HOG LUV WMT
2 MSFT NFLX GOOG TSLA AAPL INTC TXN HPQ HOG LUV WMT
3 MSFT NFLX GOOG TSLA AAPL INTC TXN HPQ HOG LUV WMT

BIN
demo Executable file

Binary file not shown.

BIN
final.ppm Normal file

Binary file not shown.

BIN
logos/._AAPL.png Normal file

Binary file not shown.

BIN
logos/._ADSK.png Normal file

Binary file not shown.

BIN
logos/._AMZN.png Normal file

Binary file not shown.

BIN
logos/._BABA.png Normal file

Binary file not shown.

BIN
logos/._BIDU.png Normal file

Binary file not shown.

BIN
logos/._COST.png Normal file

Binary file not shown.

BIN
logos/._DIS.png Normal file

Binary file not shown.

BIN
logos/._DNKN.png Normal file

Binary file not shown.

BIN
logos/._FB.png Normal file

Binary file not shown.

BIN
logos/._FDX.png Normal file

Binary file not shown.

BIN
logos/._GILD.png Normal file

Binary file not shown.

BIN
logos/._GOOG.png Normal file

Binary file not shown.

BIN
logos/._HOG.png Normal file

Binary file not shown.

BIN
logos/._HPQ.png Normal file

Binary file not shown.

BIN
logos/._INTC.png Normal file

Binary file not shown.

BIN
logos/._JPM.png Normal file

Binary file not shown.

BIN
logos/._KO.png Normal file

Binary file not shown.

BIN
logos/._LULU.png Normal file

Binary file not shown.

BIN
logos/._LUV.png Normal file

Binary file not shown.

BIN
logos/._MMM.png Normal file

Binary file not shown.

BIN
logos/._MSFT.png Normal file

Binary file not shown.

BIN
logos/._NFLX.png Normal file

Binary file not shown.

BIN
logos/._NKE.png Normal file

Binary file not shown.

BIN
logos/._PYPL.png Normal file

Binary file not shown.

BIN
logos/._RCL.png Normal file

Binary file not shown.

BIN
logos/._ROKU.png Normal file

Binary file not shown.

BIN
logos/._SBUX.png Normal file

Binary file not shown.

BIN
logos/._TSLA.png Normal file

Binary file not shown.

BIN
logos/._TWTR.png Normal file

Binary file not shown.

BIN
logos/._TXN.png Normal file

Binary file not shown.

BIN
logos/._W.png Normal file

Binary file not shown.

BIN
logos/._WM.png Normal file

Binary file not shown.

BIN
logos/._WMT.png Normal file

Binary file not shown.

BIN
logos/._blank.png Normal file

Binary file not shown.

BIN
logos/._default.png Normal file

Binary file not shown.

BIN
logos/._down.png Normal file

Binary file not shown.

BIN
logos/._up.png Normal file

Binary file not shown.

BIN
logos/AAPL.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

BIN
logos/ADSK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
logos/AMZN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
logos/BABA.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
logos/BIDU.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
logos/COST.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
logos/DIS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
logos/DNKN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
logos/FB.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
logos/FDX.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
logos/GILD.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
logos/GOOG.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
logos/HOG.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
logos/HPQ.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
logos/INTC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
logos/JPM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
logos/KO.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
logos/LULU.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/LUV.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
logos/MMM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
logos/MSFT.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
logos/NFLX.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
logos/NKE.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
logos/PYPL.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
logos/RCL.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
logos/ROKU.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
logos/SBUX.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
logos/TSLA.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
logos/TWTR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
logos/TXN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
logos/W.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
logos/WM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
logos/WMT.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
logos/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

BIN
logos/default.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

BIN
logos/down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

BIN
logos/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

148
server.py Normal file
View File

@ -0,0 +1,148 @@
# Copyright (C) 2020 Daniel Richardson richardson.daniel@hotmail.co.uk
#
# This file is part of stockTicker project for justinodunn.
#
# stockTicker can not be copied and/or distributed without the express
# permission of Daniel Richardson
from flask import Flask, render_template, request
from stockTicker import runStockTicker, stopStockTicker
from werkzeug.utils import secure_filename
import os
import datetime
import threading
import csv
command = 300
tickerList = 0
DelayTime = 20
LastCommand = ''
speedTime = 25
LOGO_FOLDER = 'logos/'
CSV_FOLDER = 'csv/new/'
ALLOWED_EXTENSIONS = {'csv', 'png'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def process_file(path, filename):
default_csv = csv.writer(open('csv/tickers.csv', 'w'))
new_csv = csv.reader(open((path), 'r'))
for row in new_csv:
default_csv.writerow(row)
def ShutdownPI():
print('SHUTTING DOWN')
os.system("sudo shutdown --poweroff")
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def hello():
global command
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
LogoList = os.listdir('logos')
templateData = {
'title' : 'Stock Ticker Control Panel',
'time': timeString,
'runtime': command,
'tickers': tickerList,
'logofiles':LogoList,
'lastcommand':LastCommand,
'delay':DelayTime,
'speedtime':speedTime
}
return render_template('index.html', **templateData)
@app.route("/Runtime", methods=['POST'])
def Runtime():
global command
command = request.form['text']
print(command)
global LastCommand
LastCommand = 'Change runtime'
return hello()
@app.route("/Delay", methods=['POST'])
def Delay():
global DelayTime
DelayTime = request.form['text']
print(DelayTime)
global LastCommand
LastCommand = 'Change Delay'
return hello()
@app.route("/Speed", methods=['POST'])
def Speed():
global speedTime
speedTime = request.form['text']
print(speedTime)
global LastCommand
LastCommand = 'Change Speed'
return hello()
@app.route("/Ticker", methods=['POST'])
def Ticker():
if request.method == 'POST':
if 'file' not in request.files:
print('No file attached in request')
return hello()
file = request.files['file']
if file.filename == '':
print('No file selected')
return hello()
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(CSV_FOLDER, filename))
process_file(os.path.join(CSV_FOLDER, filename), filename)
global LastCommand
LastCommand = 'Change CSV file'
return hello()
return hello()
@app.route("/AddLogo", methods=['POST'])
def AddLogo():
if request.method == 'POST':
if 'file' not in request.files:
print('No file attached in request')
return hello()
file = request.files['file']
if file.filename == '':
print('No file selected')
return hello()
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(LOGO_FOLDER, filename))
global LastCommand
LastCommand = 'Add a new logo file'
return hello()
return hello()
@app.route("/matrix", methods=['POST'])
def matrix():
global LastCommand
if "Run Display" in request.form:
pass
runStockTicker(command, DelayTime, speedTime)
LastCommand = 'Run display'
elif "Stop Display (at next refresh)" in request.form:
pass
try:
stopStockTicker()
LastCommand = 'Stop display at next checkpoint'
except:
print("none running")
elif "Shutdown the pi" in request.form:
pass
try:
LastCommand = 'shutdown'
ShutdownPI()
except:
print("couldn't shutdown")
return hello()
if __name__ == "__main__":
app.run(host='0.0.0.0', port=1024, debug=True)
#sudo ./demo -D1 final.ppm -t 50 -m 25 --led-gpio-mapping=adafruit-hat --led-rows=32 --led-cols=256

BIN
static/._style.css Normal file

Binary file not shown.

11
static/style.css Normal file
View File

@ -0,0 +1,11 @@
body {
background: black;
color: white;
@font-face {
font-family: Encode;
src: EncodeSans.ttf;
}
font-family: Encode;
}

238
stockTicker.py Normal file
View File

@ -0,0 +1,238 @@
# Copyright (C) 2020 Daniel Richardson richardson.daniel@hotmail.co.uk
#
# This file is part of stockTicker project for justinodunn.
#
# stockTicker can not be copied and/or distributed without the express
# permission of Daniel Richardson
from twelvedata import TDClient
import sys
import os
import threading
from PIL import Image, ImageDraw, ImageFont
import time
import csv
#Define global resources
symbols = []
ApiKeys = [["b1be6696d54342bdb5c8f59a052854fd","237d183faf984e7eba708a647c55153a","3012b3cb19784ed4be2b02e9907e53cb"],["f835e85df2a74df1904fe6dc53bcc17a","41ec268496744c34a96e3c408081300b","2d566fc71ade46d688713b13730c5219"]]
#ApiKeys = [["6172b84d1f464ad88b95ed52e4391bce","979f9b8c9ee748fbbb57cb490ccaaf42","593fa818a44144699b75433aafd92d15"]
retrievedList = []
greenORred = (255, 255, 255)
ListStocks = []
blank = Image.open('logos/blank.png')
ApiCalledError = False
keySwapper = 0
displayTime = 60
speedDisplay = 25
running = True
Delay = 20
parseCSV = 0
symbolLength = 0
#Get the logo from file that is the same as ticker name
def getLogo(Ticker):
try:
Logo = Image.open('logos/' + Ticker + '.png')
except:
print('Could not find logo for: ' + Ticker + ' using default')
Logo = Image.open('logos/default.png')
return Logo
#Using change between min and day price give appropriate arrow
#and set the overall change colour
def getArrow(CHANGE):
global greenORred
if(CHANGE>0):
Arrow = Image.open('logos/up.png')
greenORred = (0, 255, 0)
return Arrow, CHANGE
Arrow = Image.open('logos/down.png')
greenORred = (255, 0, 0)
CHANGE = (CHANGE * -1)
return Arrow, CHANGE
def get_text_dimensions(text_string, font):
canvas = Image.new('RGB', (100,100))
draw = ImageDraw.Draw(canvas)
monospace = font
text = text_string
white = (255,255,255)
draw.text((10, 10), text, font=monospace, fill=white)
bbox = canvas.getbbox()
width = bbox[2]-bbox[0]
height = bbox[3]-bbox[1]
return width,height
#Draw Ticker, current and change onto one image
def textToImage(TICKER, CURRENT, CHANGE, ARROW):
font = ImageFont.truetype("EncodeSans.ttf", 18)
img = Image.new('RGB', (150, 32))
d = ImageDraw.Draw(img)
d.text((4, -4), TICKER, fill=(255, 255, 255), font=font)
d.text((4, 13), CURRENT, fill=greenORred, font=font)
text_width_current, text_height = get_text_dimensions(CURRENT, font)
img.paste(ARROW, ((text_width_current + 9),18))
d.text(((text_width_current+29), 13), CHANGE, fill=greenORred, font=font)
text_width_change, text_height = get_text_dimensions(CHANGE, font)
newWidth = (text_width_current+29) + (text_width_change)
img.crop((0,0,newWidth,32))
return img
#Stitch the logo & prices picture into one image
def stitchImage(IMAGES):
widths, heights = zip(*(i.size for i in IMAGES))
total_width = sum(widths)
max_height = max(heights)
new_im = Image.new('RGB', (total_width, max_height))
x_offset = 0
for im in IMAGES[0:2]:
new_im.paste(im, (x_offset,0))
x_offset += im.size[0]
return new_im
#Display the image onto the matrix
def displayImage(IMAGE):
print('k')
return 0
#Get current prices and day prices for the ticker then format the response into an array
def getStockPrices(APIKEY, SYMBOLS):
global ApiCalledError
try:
symbols_list = SYMBOLS.split(",")
td = TDClient(apikey=APIKEY)
tmin = td.time_series(symbol=SYMBOLS, interval="1min", outputsize='1').as_json()
tday = td.time_series(symbol=SYMBOLS, interval="1day", outputsize='2').as_json()
for i in range(len(symbols_list)):
currentMinPriceList = tmin[symbols_list[i]]
currentDayPriceList = list(tday[symbols_list[i]])
del currentDayPriceList[0]
currentMinPriceClose = tmin[symbols_list[i]][0]['close']
currentDayPriceClose = currentDayPriceList[0]['close']
retrievedList.append([])
retrievedList[i].append(symbols_list[i])
retrievedList[i].append(currentMinPriceClose)
retrievedList[i].append(currentDayPriceClose)
except:
ApiCalledError = True
print("Could not fetch data - API CALLS REACHED? - Will display old image")
#Connect all the pieces togeather creating 1 long final stock image
def GetfullStockImage():
global ListStocks
global retrievedList
global ApiCalledError
ApiCalledError = False
ListStocks = []
retrievedList = []
start = time.time()
print('elapsed time: ' + str((time.time()-start)))
j=0
while (j<3):
print('API KEY: ' + str(ApiKeys[keySwapper][j]))
getStockPrices(ApiKeys[keySwapper][j], symbols[(j+parseCSV)][0])
if (ApiCalledError == False):
j+=1
print('elapsed time after api call: ' + str((time.time()-start)))
for i in range(len(retrievedList)):
print('elapsed timethrough loop: ' + str((time.time()-start)))
Change = float(retrievedList[i][1])-float(retrievedList[i][2]) #TEXT
Ticker = retrievedList[i][0] #TEXT
Current = '%.2f' % float(retrievedList[i][1]) #TEXT
Logo = getLogo(retrievedList[i][0])
Arrow, Change = getArrow(Change)
Change = '%.2f' % Change
MidFrame = textToImage(Ticker, Current, Change, Arrow) #IMAGE THE TEXT
StitchedStock = stitchImage([Logo,MidFrame])
ListStocks.append(blank)
ListStocks.append(StitchedStock)
retrievedList = []
else:
break
print('elapsed time loop ended: ' + str((time.time()-start)))
if (ApiCalledError == False):
FinalDisplayImage = stitchImage(ListStocks)
FinalDisplayImage.save('final.ppm')
print(retrievedList)
#Send the final stitched image to the display for set amount of time
def displayMatrix():
#os.system("sudo ./demo -D1 final.ppm -t " + str(displayTime) +" -m "+ str(speedDisplay) +" --led-gpio-mapping=adafruit-hat --led-rows=32 --led-cols=256")
os.system("sudo ./demo -D1 final.ppm -t " + str(displayTime) +" -m "+ str(speedDisplay) +" --led-gpio-mapping=adafruit-hat --led-rows=64 --led-cols=64")
#Retrieve symbols from the CSV file
def GetSymbols():
global symbols
symbols = []
CSV = csv.reader(open('csv/tickers.csv', 'r'))
z = 0
for row in CSV:
symbols.append([])
endLine = str(row[0]+','+row[1]+','+row[2]+','+row[3]+','+row[4]+','+row[5]+','+row[6]+','+row[7]+','+row[8]+','+row[9]+','+row[10])
symbols[z].append(endLine)
z+=1
print(symbols)
#Main run definition called by server
def runStockTicker(RUNTIME, DELAY, SPEEDTIME):
global keySwapper
global running
global displayTime
global symbolLength
global parseCSV
global Delay
global speedDisplay
parseCSV = 0
Delay = DELAY
displayTime = RUNTIME
speedDisplay = SPEEDTIME
GetSymbols()
symbolLength = (len(symbols) - 3)
GetfullStockImage()
keySwapper += 1
running = True
parseCSV += 3
while (True):
if (running == True):
if (keySwapper<=1):
if(parseCSV <= symbolLength):
th = threading.Thread(target=displayMatrix)
th.start()
#displayMatrix()
time.sleep((int(displayTime) - int(Delay)))
GetfullStockImage()
keySwapper += 1
th.join()
parseCSV += 3
else:
parseCSV = 0
else:
keySwapper = 0
else:
break;
#Change running to false stopping refresh at next checkpoint
def stopStockTicker():
global running
global keySwapper
keySwapper = 0
running = False
print('MATRIX DISPLAY STOP CALLED')

BIN
stockTicker.pyc Normal file

Binary file not shown.

BIN
templates/._index.html Normal file

Binary file not shown.

66
templates/index.html Normal file
View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<head>
<link rel="stylesheet" href='/static/style.css' />
<title>{{ title }}</title>
<style>p {color:gray}</style>
</head>
<body>
<center>
<h2>Stock Ticker Control Panel</h2>
<h3>Time of last page reload <br> {{ time }}</h3>
<hr width=70% size=3 noshade>
<p>Last command sent: {{ lastcommand }}</p>
<br>
<h3>Runtime: {{ runtime }}s & API call: {{ delay }}s before refresh <br> displayed at a speed of {{ speedtime }}m/s</h3>
<p>Set the amount of time each image is displayed before a refresh in seconds</p>
<form action="/Runtime" method="POST">
<input name="text" placeholder="300"style="height:24px">
<input type="submit" value="Runtime"style="height:30px">
</form>
<p>Set the amount of time before next image refresh that the stocks are updated</p>
<form action="/Delay" method="POST">
<input name="text" placeholder="20"style="height:24px">
<input type="submit" value="Delay"style="height:30px">
</form>
<p>Set the speed the image scrolls across the screen (m/s, lower is faster)</p>
<form action="/Speed" method="POST">
<input name="text" placeholder="25"style="height:24px">
<input type="submit" value="Speed"style="height:30px">
</form>
<br><br>
<h3>Tickers to display</h3>
<p>To change the tickers displayed please upload a CSV (comma separated value) file with 11 tickers on each row e.g</p>
<p>MSFT,NFLX,GOOG,TSLA,AAPL,INTC,TXN,HPQ,HOG,LUV,WMT</p>
<p>WMT,LUV,HOG,HPQ,TXN,INTC,AAPL,TSLA,GOOG,NFLX,MSFT</p>
<form action="/Ticker" method="POST" enctype=multipart/form-data>
<p><input type=file name=file style="height:30px">
<input type=submit value=Upload style="height:30px">
</form>
<br><br>
<h3>Logos</h3>
<p>Upload logo images (e.g "TICKER.png") or change the default images here</p>
<p>1) logos must be 32px in height and can be any width</p>
<p>2) "blank.png" is the space between stocks, default of 10x32px</p>
<p>3) "default.png" is the default logo to be used if no logo can be found</p>
<p>4) arrows (up/down.png) must be 16x14px</p>
<form action="/AddLogo" method="POST" enctype=multipart/form-data>
<p><input type=file name=file style="height:30px">
<input type=submit value=Upload style="height:30px">
</form>
<p>Logos currently in file:</p>
<p>{{ logofiles }}</p>
<br><br>
<form action="/matrix" method="POST">
<input type="submit" name="Run Display" value="Run Display" style="height:50px" >
<input type="submit" name="Stop Display (at next refresh)" value="Stop Display (at next refresh)"style="height:50px">
<input type="submit" name="Shutdown the pi" value="Shutdown the pi"style="height:50px">
</form>
<br><br>
<br><br>
</center>
</body>
</html>