initial commit - old code
BIN
EncodeSans.ttf
Normal file
BIN
__pycache__/stockTicker.cpython-37.pyc
Normal file
BIN
csv/.DS_Store
vendored
Normal file
BIN
csv/._.DS_Store
Normal file
BIN
csv/._tickers.csv
Normal file
|
3
csv/tickers.csv
Normal 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
|
|
BIN
logos/._AAPL.png
Normal file
BIN
logos/._ADSK.png
Normal file
BIN
logos/._AMZN.png
Normal file
BIN
logos/._BABA.png
Normal file
BIN
logos/._BIDU.png
Normal file
BIN
logos/._COST.png
Normal file
BIN
logos/._DIS.png
Normal file
BIN
logos/._DNKN.png
Normal file
BIN
logos/._FB.png
Normal file
BIN
logos/._FDX.png
Normal file
BIN
logos/._GILD.png
Normal file
BIN
logos/._GOOG.png
Normal file
BIN
logos/._HOG.png
Normal file
BIN
logos/._HPQ.png
Normal file
BIN
logos/._INTC.png
Normal file
BIN
logos/._JPM.png
Normal file
BIN
logos/._KO.png
Normal file
BIN
logos/._LULU.png
Normal file
BIN
logos/._LUV.png
Normal file
BIN
logos/._MMM.png
Normal file
BIN
logos/._MSFT.png
Normal file
BIN
logos/._NFLX.png
Normal file
BIN
logos/._NKE.png
Normal file
BIN
logos/._PYPL.png
Normal file
BIN
logos/._RCL.png
Normal file
BIN
logos/._ROKU.png
Normal file
BIN
logos/._SBUX.png
Normal file
BIN
logos/._TSLA.png
Normal file
BIN
logos/._TWTR.png
Normal file
BIN
logos/._TXN.png
Normal file
BIN
logos/._W.png
Normal file
BIN
logos/._WM.png
Normal file
BIN
logos/._WMT.png
Normal file
BIN
logos/._blank.png
Normal file
BIN
logos/._default.png
Normal file
BIN
logos/._down.png
Normal file
BIN
logos/._up.png
Normal file
BIN
logos/AAPL.png
Normal file
After Width: | Height: | Size: 861 B |
BIN
logos/ADSK.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
logos/AMZN.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
logos/BABA.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
logos/BIDU.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
logos/COST.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
logos/DIS.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
logos/DNKN.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
logos/FB.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
logos/FDX.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
logos/GILD.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
logos/GOOG.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
logos/HOG.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
logos/HPQ.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
logos/INTC.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
logos/JPM.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
logos/KO.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
logos/LULU.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
logos/LUV.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
logos/MMM.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
logos/MSFT.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
logos/NFLX.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
logos/NKE.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
logos/PYPL.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
logos/RCL.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
logos/ROKU.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
logos/SBUX.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
logos/TSLA.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
logos/TWTR.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
logos/TXN.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
logos/W.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
logos/WM.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
logos/WMT.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
logos/blank.png
Normal file
After Width: | Height: | Size: 281 B |
BIN
logos/default.png
Normal file
After Width: | Height: | Size: 118 B |
BIN
logos/down.png
Normal file
After Width: | Height: | Size: 246 B |
BIN
logos/up.png
Normal file
After Width: | Height: | Size: 242 B |
148
server.py
Normal 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
11
static/style.css
Normal 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
@ -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
BIN
templates/._index.html
Normal file
66
templates/index.html
Normal 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>
|