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
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View 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
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
Executable
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

+148
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
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
body {
background: black;
color: white;
@font-face {
font-family: Encode;
src: EncodeSans.ttf;
}
font-family: Encode;
}
+238
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
View File
Binary file not shown.
Binary file not shown.
+66
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>