fintic-tracker/server.py
2021-09-19 19:19:09 +01:00

552 lines
16 KiB
Python

# 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 StockTicker
from werkzeug.utils import secure_filename
import os
import datetime
import threading
import csv
import pexpect
import time
import json
from multiprocessing import Process
from subprocess import Popen, PIPE
import numpy as np
#stock_ticker = StockTicker()
print('API CALLER NOT STARTED')
#api_caller = pexpect.spawn("sudo -E python3 api_caller.py")
command = 300
tickerList = 0
DelayTime = 20
LastCommand = ''
speedTime = 25
LOGO_FOLDER = 'logos/'
CSV_FOLDER = 'csv/new/'
ALLOWED_EXTENSIONS = {'csv', 'png'}
ticker = pexpect.spawn("sudo -E taskset -c 3 python3 stockTicker.py")
ticker.sendline('A') # run by default
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)
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def index():
global command
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
logos_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos')
LogoList = os.listdir(logos_path)
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():
command = request.form['text']
LastCommand = 'Change runtime'
return index()
@app.route("/Delay", methods=['POST'])
def Delay():
global DelayTime
DelayTime = request.form['text']
global LastCommand
LastCommand = 'Change Delay'
return index()
@app.route("/Speed", methods=['POST'])
def Speed():
global speed
speed = request.form['text']
ticker.sendline(speed)
f = open('csv/settings.csv', 'r')
CSV = csv.reader(f)
next(CSV)
for line in CSV:
_, brightness = line
f.close()
f = open('csv/settings.csv', 'w+')
f.write('speed,brightness\n')
f.write(str(speed) + ',' + brightness)
f.close()
global LastCommand
LastCommand = 'Change Speed'
return index()
@app.route("/Brightness", methods=['POST'])
def Brightness():
global brightness
brightness = int(request.form['text'])-1
ticker.sendline(str(brightness))
f = open('csv/settings.csv', 'r')
CSV = csv.reader(f)
next(CSV)
for line in CSV:
speed, _ = line
f.close()
f = open('csv/settings.csv', 'w+')
f.write('speed,brightness\n')
f.write(str(speed) + ',' + str(brightness))
f.close()
global LastCommand
LastCommand = 'Change Brightness'
return index()
@app.route("/DisplayText", methods=['POST'])
def DisplayText():
text = request.form['text']
f = open('csv/scroll_text.csv', 'w+')
f.write(text)
f.close()
ticker.sendline('K')
ticker.sendline('T')
return index()
@app.route("/SetNews", methods=['POST'])
def SetNews():
text = request.form['text']
#args = ['q', 'sources', 'category', 'country']
args = ['q', 'category', 'country']
arg_dict = {}
lst = text.split(',')
try:
for i, arg in enumerate(args):
if len(lst[i])>0:
arg_dict[arg] = lst[i]
json.dump( arg_dict, open( "csv/news_settings.json", 'w+' ))
except Exception as e:
#reset settings
f = open( "csv/news_settings.json", 'w+' )
f.close()
api_caller.sendline('R')
return index()
@app.route("/SetWeather", methods=['POST'])
def SetWeather():
text = request.form['text']
#args = ['q', 'sources', 'category', 'country']
f = open( "csv/weather_location.txt", 'w+' )
f.write(text)
f.close()
api_caller.sendline('R')
return index()
@app.route("/DisplayGIF", methods=['POST'])
def DisplayGIF():
if request.method == 'POST':
if 'file' not in request.files:
print('No file attached in request')
return hello()
fle = request.files['file']
if fle.filename == '':
print('No file selected')
return hello()
if fle:
filename = 'user_gif.gif'
fle.save(os.path.join(os.path.dirname(os.path.abspath(__file__)),os.path.join('display_images', filename)))
global LastCommand
LastCommand = 'Add a new logo file'
ticker.sendline('K')
ticker.sendline('G')
return hello()
return index()
@app.route("/DisplayImage", methods=['POST'])
def DisplayImage():
if request.method == 'POST':
if 'file' not in request.files:
print('No file attached in request')
return hello()
fle = request.files['file']
if fle.filename == '':
print('No file selected')
return hello()
if fle:
filename = 'user_image.ppm'
fle.save(os.path.join(os.path.dirname(os.path.abspath(__file__)),os.path.join('display_images', filename)))
global LastCommand
LastCommand = 'Add a new logo file'
ticker.sendline('K')
ticker.sendline('I')
return hello()
return index()
@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()
fle = request.files['file']
if fle.filename == '':
print('No file selected')
return hello()
if fle and allowed_file(fle.filename):
filename = secure_filename(fle.filename)
fle.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 index()
@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()
fle = request.files['file']
if fle.filename == '':
print('No file selected')
return hello()
if fle and allowed_file(fle.filename):
filename = secure_filename(fle.filename)
fle.save(os.path.join(LOGO_FOLDER, filename))
global LastCommand
LastCommand = 'Add a new logo file'
return hello()
return index()
professional = False
@app.route("/start", methods = ['PUT', 'POST'])
def start():
print(professional)
data = str(request.data)
all_settings = ['Stocks', 'Crypto', 'Forex', 'Current Weather', 'Daily Forecast', 'News', 'Sports (Upcoming Games)', 'Sports (Past Games)',
'Sports (Live Games)', 'Sports (Team Stats)', 'Custom Images', 'Custom GIFs', 'Custom Messages']
if professional:
all_settings = ['Stocks', 'Crypto', 'Forex', 'Current Weather', 'News']
positions = []
display_settings = []
for setting in all_settings:
pos = data.find(setting)
if pos != -1:
if professional:
setting += ' Prof'
display_settings.append(setting)
positions.append(pos)
# sort settings by display
inds = np.argsort(positions)
display_settings = np.array(display_settings)[inds]
with open('csv/display_settings.json', 'w+') as f:
json.dump(list(display_settings), f)
ticker.sendline('K')
ticker.sendline('A')
return index()
@app.route("/display_format", methods = ['PUT', 'POST', 'GET'])
def display_format():
global professional
data = str(request.data)
if "Standard" in data:
professional = False
elif "Professional" in data:
professional = True
print(professional)
return index()
@app.route("/feature_settings", methods = ['PUT', 'POST', 'GET'])
def feature_settings():
data = str(request.data.decode('utf-8'))
input_settings = json.loads(data)
print(input_settings)
feature = input_settings['feature']
if feature in ['Stocks', 'Crypto', 'Forex']:
save_trade_settings(input_settings)
elif feature in ['Current Weather', 'Daily Forecast']:
save_weather_settings(input_settings)
elif feature == 'News':
save_news_settings(input_settings)
elif 'Sports' in feature:
save_sports_settings(input_settings)
elif feature in ['Custom GIFs', 'Custom Images']:
save_image_settings(input_settings)
return index()
def combine_dict(current_settings, input_symbols, current_key):
# removes keys not in input from current_settings[current_key] and adds keys not in current from input
current_symbols = list(current_settings[current_key].keys())
# add any stock that arent current in the settings
for IS in input_symbols:
if IS not in current_symbols:
current_settings[current_key][IS] = -1
# remove stocks not in settings
for CS in current_symbols:
if CS not in input_symbols:
del current_settings[current_key][CS]
return current_settings
def save_trade_settings(input_settings):
filename = input_settings['feature'].lower() + '_settings.json'
current_settings = json.load(open('csv/' + filename, 'r'))
current_settings['speed'] = input_settings['speed'].lower()
current_settings['animation'] = input_settings['animation'].lower()
current_settings['percent'] = input_settings['percent']
current_settings['point'] = input_settings['point']
current_settings['no_logos'] = input_settings['no_logos']
current_settings['chart'] = input_settings['chart']
current_settings['title'] = input_settings['title']
current_settings = combine_dict(current_settings, input_settings['symbols'], 'symbols')
json.dump(current_settings, open('csv/' + filename, 'w+'))
def save_weather_settings(input_settings):
filename = 'current_weather.json' if input_settings['feature'] == 'Current Weather' else 'daily_weather.json'
current_settings = json.load(open('csv/' + filename, 'r'))
current_settings['speed'] = input_settings['speed'].lower()
current_settings['animation'] = input_settings['animation'].lower()
current_settings['temp'] = input_settings['temp'].lower()
current_settings['wind_speed'] = input_settings['wind_speed'].lower()
current_settings['colour'] = input_settings['colour'].lower()
current_settings['city_colour'] = input_settings['city_colour'].lower()
current_settings['title'] = input_settings['title']
if input_settings['feature'] == 'Daily Forecast':
current_settings['current_weather'] = input_settings['current_weather']
current_settings = combine_dict(current_settings, input_settings['cities'], 'cities')
json.dump(current_settings, open('csv/' + filename, 'w+'))
def save_news_settings(input_settings):
filename = 'news_settings.json'
current_settings = json.load(open('csv/' + filename, 'r'))
current_settings['speed'] = input_settings['speed'].lower()
current_settings['animation'] = input_settings['animation'].lower()
current_settings['title'] = input_settings['title']
current_settings['category'] = input_settings['category'].lower()
current_settings['country'] = input_settings['country']
current_settings = combine_dict(current_settings, input_settings['sources'], 'sources')
json.dump(current_settings, open('csv/' + filename, 'w+'))
def save_sports_settings(input_settings):
feature = input_settings['feature']
if feature == 'Sports (Upcoming Games)':
filename = 'upcoming_games.json'
elif feature == 'Sports (Past Games)':
filename = 'past_games.json'
elif feature == 'Sports (Live Games)':
filename = 'live_games.json'
elif feature == 'Sports (Team Stats)':
filename = 'team_stats.json'
current_settings = json.load(open('csv/' + filename, 'r'))
current_settings['speed'] = input_settings['speed'].lower()
current_settings['animation'] = input_settings['animation'].lower()
current_settings['title'] = input_settings['title']
current_settings = combine_dict(current_settings, input_settings['leagues'], 'leagues')
json.dump(current_settings, open('csv/' + filename, 'w+'))
# for images and GIFs
def save_image_settings(input_settings):
filename = 'image_settings.json' if input_settings['feature'] == 'Custom Images' else 'GIF_settings.json'
current_settings = input_settings
current_settings['speed'] = input_settings['speed'].lower()
current_settings['animation'] = input_settings['animation'].lower()
current_settings['title'] = input_settings['title']
del current_settings['feature']
json.dump(current_settings, open('csv/' + filename, 'w+'))
@app.route("/stop")
def stop():
print('stop')
ticker.sendline('K')
return index()
@app.route("/shutdown")
def shutdown():
os.system("sudo shutdown now")
return index()
@app.route("/matrix")
def matrix():
if "Run Stocks" in request.form:
ticker.sendline('K')
ticker.sendline('S')
elif "Run Crypto" in request.form:
ticker.sendline('K')
ticker.sendline('C')
elif "Run Forex" in request.form:
ticker.sendline('K')
ticker.sendline('F')
elif "Run News" in request.form:
ticker.sendline('K')
ticker.sendline('N')
elif "Run Weather" in request.form:
ticker.sendline('K')
ticker.sendline('W')
elif "Run Daily Weather" in request.form:
ticker.sendline('K')
ticker.sendline('D')
elif "Past NHL" in request.form:
ticker.sendline('K')
ticker.sendline('P')
elif "Future NHL" in request.form:
ticker.sendline('K')
ticker.sendline('l')
elif "Live NHL" in request.form:
ticker.sendline('K')
ticker.sendline('L')
elif "Premier league table" in request.form:
ticker.sendline('K')
ticker.sendline('t')
elif "Professional" in request.form:
ticker.sendline('K')
ticker.sendline('b')
elif "All" in request.form:
ticker.sendline('K')
ticker.sendline('A')
elif "Multiple" in request.form:
ticker.sendline('K')
ticker.sendline('+')
elif "Stop Display" in request.form:
LastCommand = 'Stop display at next checkpoint'
ticker.sendline('K')
elif "Shutdown the pi" in request.form:
try:
os.system("sudo shutdown now")
except:
print("couldn't shutdown")
return index()
if __name__ == "__main__":
app.run(host='0.0.0.0', port=1024, debug=False) # the debuggger causes flickering
#sudo ./demo -D1 final.ppm -t 50 -m 25 --led-gpio-mapping=adafruit-hat --led-rows=32 --led-cols=256 --led-slowdown-gpio=4