Merge pull request #20 from fin-tic/dev

Update 1.3.7
This commit is contained in:
Justin 2023-07-26 21:23:40 +08:00 committed by GitHub
commit 3e7575450a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 3689 additions and 189 deletions

View File

@ -1 +1 @@
{"scheduler":{"force": false}, "stocks": {"time": "14/06/2022 06:42:06", "force": false}, "crypto": {"time": "14/06/2022 06:58:18", "force": false}, "news": {"time": "14/06/2022 05:29:08", "force": false}, "weather": {"time": "14/06/2022 05:29:08", "force": false}, "forex": {"time": "14/06/2022 05:29:14", "force": false}, "sports_l": {"time": "14/06/2022 04:42:37", "force": false}, "sports_p": {"time": "14/06/2022 06:27:34", "force": false}, "sports_u": {"time": "14/06/2022 06:28:34", "force": false}, "sports_t": {"time": "14/06/2022 06:26:23", "force": false}, "commodities": {"time": "14/06/2022 06:51:07", "force": false}, "indices": {"time": "05/10/2022 04:06:10", "force": false}, "movies": {"time": "05/10/2022 02:31:40", "force": false}, "ipo": {"time": "05/10/2022 02:31:40", "force": false}, "prepost": {"time": "05/10/2022 02:31:40", "force": false}, "economic": {"time": "05/10/2022 02:31:40", "force": false}}
{"scheduler":{"force": false}, "stocks": {"time": "14/06/2022 06:42:06", "force": false}, "crypto": {"time": "14/06/2022 06:58:18", "force": false}, "news": {"time": "14/06/2022 05:29:08", "force": false}, "weather": {"time": "14/06/2022 05:29:08", "force": false}, "forex": {"time": "14/06/2022 05:29:14", "force": false}, "sports_l": {"time": "14/06/2022 04:42:37", "force": false}, "sports_p": {"time": "14/06/2022 06:27:34", "force": false}, "sports_u": {"time": "14/06/2022 06:28:34", "force": false}, "sports_t": {"time": "14/06/2022 06:26:23", "force": false}, "commodities": {"time": "14/06/2022 06:51:07", "force": false}, "indices": {"time": "05/10/2022 04:06:10", "force": false}, "movies": {"time": "05/10/2022 02:31:40", "force": false}, "ipo": {"time": "05/10/2022 02:31:40", "force": false}, "prepost": {"time": "05/10/2022 02:31:40", "force": false}, "economic": {"time": "05/10/2022 02:31:40", "force": false}, "jokes": {"time": "05/10/2022 02:31:40", "force": false}}

View File

@ -176,13 +176,16 @@ def updateStocks(api_key, logf):
data = response.json()
if len(data) > 0:
for symbol in symbols:
try:
stock_info[data[symbol]['quote']['symbol']] = {'current': data[symbol]['quote']['latestPrice'], 'change': data[symbol]['quote']['change'], 'percent_change':data[symbol]['quote']['changePercent'] * 100}
except:
pass
all_stocks_settings['symbols'] = stock_info
with open('csv/stocks_settings.json', 'w+') as f:
json.dump(all_stocks_settings, f)
elif 'query1.finance.yahoo.com/v7' in url:
url = url.replace('BRK.A', 'BRK-A').replace('BRK.B', 'BRK-B')
response = requests.get(url, headers=headers)
data = response.json()
if "'error': {'code'" in str(data):
@ -210,10 +213,12 @@ def updateStocks(api_key, logf):
# stock_info = {}
if len(data) > 0:
for symbol in symbols:
try:
for stock in data['quoteResponse']['result']:
if stock['symbol'] == symbol:
stock_info[stock['symbol']] = {'current': stock['regularMarketPrice'], 'change': stock['regularMarketChange'], 'percent_change':stock['regularMarketChangePercent']}
if stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B') == symbol:
stock_info[stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B')] = {'current': stock['regularMarketPrice'], 'change': stock['regularMarketChange'], 'percent_change':stock['regularMarketChangePercent']}
except:
pass
all_stocks_settings['symbols'] = stock_info
with open('csv/stocks_settings.json', 'w+') as f:
json.dump(all_stocks_settings, f)
@ -248,7 +253,7 @@ def updateStocksPrePost(api_key, logf):
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
prepost = requests.get(prepost_url, headers=headers).json()
prepost = requests.get(prepost_url.replace('BRK.A', 'BRK-A').replace('BRK.B', 'BRK-B'), headers=headers).json()
if "'error': {'code'" in str(prepost):
while True:
try:
@ -264,7 +269,7 @@ def updateStocksPrePost(api_key, logf):
crumb = f.read()
params = {'crumb': crumb}
prepost = session.get(prepost_url.replace('v6','v7'), headers=headers, params=params).json()
prepost = session.get(prepost_url.replace('v6','v7').replace('BRK.A', 'BRK-A').replace('BRK.B', 'BRK-B'), headers=headers, params=params).json()
if "'error': {'code'" not in str(prepost):
break
@ -277,31 +282,33 @@ def updateStocksPrePost(api_key, logf):
if len(prepost_data) > 0:
for symbol in symbols:
try:
for stock in prepost_data:
if stock['symbol'] == symbol:
stock_info[stock['symbol']] = {"time_now":time_now}
try:
stock_info[stock['symbol']]['Pre-market'] = {'preprice': '%.2f' % stock['preMarketPrice'],
stock_info[stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B')]['Pre-market'] = {'preprice': '%.2f' % stock['preMarketPrice'],
'prechange': '%.2f' % stock['preMarketChange'],
'prepercent': '%.2f' % stock['preMarketChangePercent']}
except:
try:
stock_info[stock['symbol']]['Pre-market'] = {'preprice': '%.2f' % stock['postMarketPrice'],
stock_info[stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B')]['Pre-market'] = {'preprice': '%.2f' % stock['postMarketPrice'],
'prechange': '%.2f' % 0,
'prepercent': '%.2f' % 0}
except:
stock_info[stock['symbol']]['Pre-market'] = {'preprice': '%.2f' % stock['regularMarketPrice'],
stock_info[stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B')]['Pre-market'] = {'preprice': '%.2f' % stock['regularMarketPrice'],
'prechange': '%.2f' % 0,
'prepercent': '%.2f' % 0}
try:
stock_info[stock['symbol']]['Post-market'] = {'postprice': '%.2f' % stock['postMarketPrice'],
stock_info[stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B')]['Post-market'] = {'postprice': '%.2f' % stock['postMarketPrice'],
'postchange': '%.2f' % stock['postMarketChange'],
'postpercent': '%.2f' % stock['postMarketChangePercent']}
except:
stock_info[stock['symbol']]['Post-market'] = {'postprice': '%.2f' % stock['regularMarketPrice'],
stock_info[stock['symbol'].replace('BRK-A', 'BRK.A').replace('BRK-B', 'BRK.B')]['Post-market'] = {'postprice': '%.2f' % stock['regularMarketPrice'],
'postchange': '%.2f' % 0,
'postpercent': '%.2f' % 0}
except:
pass
all_stocks_settings['symbols'] = stock_info
with open('csv/prepost_settings.json', 'w+') as f:
@ -753,7 +760,6 @@ def updateEconomic(api_key, logf):
try:
for each in data['result']:
try:
print(each['actual'], each['previous'], each['forecast'])
time = pytz.timezone('GMT').localize(datetime.strptime(each['date'], '%Y-%m-%dT%H:%M:%S.%fZ')).astimezone(timezone).strftime('%a %m/%d %H:%M%p')
if datetime.now(timezone).strftime('%a %m/%d %H:%M%p') >= time:
happened = True
@ -812,6 +818,38 @@ def updateEconomic(api_key, logf):
pass
def updateJokes(api_key, logf):
try:
with open('csv/jokes_settings.json', 'r') as f:
jokes_settings = json.load(f)
except:
jokes_settings = {"feature": "Jokes", "speed": "medium", "speed2": "medium", "animation": "up", "title": True, "safe": True, "categories": ["Any"], "blacklist": [], "amount": "5", "jokes": []}
try:
if 'Any' in jokes_settings['categories']:
categories = 'Any'
else:
categories = ','.join(jokes_settings['categories'])
blacklist = ','.join(jokes_settings['blacklist'])
amount = jokes_settings['amount']
jokes_settings['jokes'] = []
joke_url = 'https://v2.jokeapi.dev/joke/'+categories+'?amount='+amount
if blacklist != '':
joke_url = 'https://v2.jokeapi.dev/joke/'+categories+ '?blacklistFlags=' + blacklist + '&amount='+amount
if jokes_settings['safe']:
joke_url += '&safe-mode'
get_jokes = requests.get(joke_url)
all_jokes = get_jokes.json()
for each_joke in all_jokes['jokes']:
jokes_settings['jokes'].append(each_joke)
with open('csv/jokes_settings.json', 'w') as f:
json.dump(jokes_settings,f)
except:
pass
def updateNews(api_key, logf):
try:
@ -1181,6 +1219,9 @@ def updateLeagueEvents(api_key, time, logf):
ten_or_fifteen = slice(None)
events = []
if (league == 'PGA') or (league == 'LPGA') or (league == 'PGA_EU') or (league == 'LIV') or (league == 'F1') or (league == 'NASCAR'):
if time == 'past':
ten_or_fifteen = slice(2)
else:
ten_or_fifteen = slice(3)
else:
ten_or_fifteen = slice(None)
@ -1493,7 +1534,7 @@ if __name__ == '__main__':
t = time.time()
update_frequencies = {'stocks':2, 'crypto':7, 'forex':60, 'news':120, 'weather': 120, 'sports': 1440, 'commodities': 15, 'indices': 15, 'movies': 1440, 'ipo': 1440, 'prepost': 15, 'economic': 15} #minutes
update_frequencies = {'stocks':2, 'crypto':7, 'forex':60, 'news':120, 'weather': 120, 'sports': 1440, 'commodities': 15, 'indices': 15, 'movies': 1440, 'ipo': 1440, 'prepost': 15, 'economic': 15, 'jokes': 15} #minutes
NY_zone = pytz.timezone('America/New_York')
CET_zone = pytz.timezone('EST')
@ -1570,7 +1611,8 @@ if __name__ == '__main__':
"news": {"time": "06/03/2022 04:07:09", "force": True}, "weather": {"time": "06/03/2022 04:08:20", "force": True},
"forex": {"time": "06/03/2022 03:54:02", "force": True}, "sports_l": {"time": "06/03/2022 04:10:09", "force": True},
"sports_p": {"time": "06/03/2022 04:10:09", "force": True},
"sports_u": {"time": "06/03/2022 04:10:09", "force": True},"sports_t": {"time": "06/03/2022 04:10:09", "force": True}, "commodities": {"time": "06/03/2022 04:10:09", "force": True}, "indices": {"time": "06/03/2022 04:10:09", "force": True}, "movies": {"time": "06/03/2022 04:10:09", "force": True}, "ipo": {"time": "06/03/2022 04:10:09", "force": True}, "prepost": {"time": "06/03/2022 04:10:09", "force": True}, "economic": {"time": "06/03/2022 04:10:09", "force": True}}
"sports_u": {"time": "06/03/2022 04:10:09", "force": True},"sports_t": {"time": "06/03/2022 04:10:09", "force": True}, "commodities": {"time": "06/03/2022 04:10:09", "force": True}, "indices": {"time": "06/03/2022 04:10:09", "force": True}, "movies": {"time": "06/03/2022 04:10:09", "force": True}, "ipo": {"time": "06/03/2022 04:10:09", "force": True},
"prepost": {"time": "06/03/2022 04:10:09", "force": True}, "economic": {"time": "06/03/2022 04:10:09", "force": True}, "jokes": {"time": "06/03/2022 04:10:09", "force": True}}
try:
if last_updates['scheduler']['force']:
@ -1714,6 +1756,21 @@ if __name__ == '__main__':
update_processes.append(update_process)
# jokes
jokes_time = datetime.strptime(last_updates['jokes']['time'], "%d/%m/%Y %H:%M:%S")
NY_time = datetime.now(NY_zone).replace(tzinfo=None)
diff = (NY_time - jokes_time).total_seconds()/60 #minutes
if last_updates['jokes']['force'] or diff >= update_frequencies['jokes']:# or msg == 'c':
jokes_time = NY_time.strftime("%d/%m/%Y %H:%M:%S")
last_updates['jokes']['time'] = jokes_time
last_updates['jokes']['force'] = False
update_process = Process(target = updateJokes, args = (api_key,logf))
update_process.start()
update_processes.append(update_process)
# indices
indices_time = datetime.strptime(last_updates['indices']['time'], "%d/%m/%Y %H:%M:%S")

BIN
feature_titles/jokes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

2030
fonts/BonusCoffee-16.bdf Normal file

File diff suppressed because it is too large Load Diff

BIN
fonts/BonusCoffee-16.pbm Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

BIN
fonts/BonusCoffee-16.pil Normal file

Binary file not shown.

BIN
logos/emojis/category.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

BIN
logos/emojis/emoji1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
logos/emojis/emoji2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/emojis/emoji3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/emojis/emoji4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/emojis/emoji5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
logos/emojis/emoji6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
logos/emojis/emoji7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/emojis/emoji8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/emojis/flags.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

BIN
logos/indices/ES=F.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/indices/NQ=F.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/indices/RTY=F.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
logos/indices/YM=F.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

279
server.py
View File

@ -116,13 +116,36 @@ class DummyProcess():
# pass
# output = subprocess.check_output(['sudo', 'iwlist', 'wlan0', 'scan'])
# output_str = output.decode('utf-8')
# lines = output_str.split('Cell')
networks = {}
# for line in lines:
# if 'ESSID:""\n' not in line and 'Scan completed' not in line:
# ssid = line.split('ESSID:')[1].split('\n')[0]
# ssid = ssid.replace('"', '', 1)
# ssid = ssid[::-1].replace('"', '', 1)[::-1]
# if 'AES' in ssid:
# ssid = ssid.replace("AES", "CCMP")
# try:
# group_cipher = line.split('Group Cipher : ')[1].split('\n')[0]
# pair_cipher = line.split('Pairwise Ciphers (1) : ')[1].split('\n')[0]
# except:
# group_cipher = ''
# pair_cipher = ''
# # quality = line.split('Quality=')[1].split('Signal level')[0].replace(" ", "")
# networks[ssid] = {'group_cipher': group_cipher, 'pair_cipher': pair_cipher}
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def index():
global command
all_features = ['Current Weather','Daily Forecast','News', 'Sports (Upcoming Games)','Sports (Past Games)','Sports (Live Games)',
'Sports (Team Stats)','Custom Images', 'Custom GIFs', 'Custom Messages', 'Stocks', 'Crypto', 'Forex', 'Commodities', 'Indices', 'Movies',
'IPO Calendar', 'Economic Calendar']
'IPO Calendar', 'Economic Calendar', 'Jokes']
global professional
@ -212,7 +235,8 @@ def index():
'OMXS30 - Stockholm': '^OMX', 'AEX - Amsterdam': '^AEX', 'ATX - Austria': '^ATX', 'BEL 20 - Brussels': '^BFX',
'SSMI - Switzerland': '^SSMI', 'CAC 40 - France': '^FCHI', 'IBEX 35 - Spain': '^IBEX', 'FTSE 100 - UK': '^FTSE', 'Dax - Germany': '^GDAXI',
'Bovespa - Brazil': '^BVSP', 'IPC - Mexico': '^MXX', 'S&P/TSX - Canada': '^GSPTSE', 'VIX - USA': '^VIX', 'Russell 2000 - USA': '^RUT',
'Nasdaq Composite - USA': '^IXIC', 'Nasdaq 100 - USA': '^NDX', 'S&P 500 - USA': '^GSPC', 'Dow Jones - USA': '^DJI', 'U.S. Dollar (DXY) - USA': 'DX-Y.NYB'}
'Nasdaq Composite - USA': '^IXIC', 'Nasdaq 100 - USA': '^NDX', 'S&P 500 - USA': '^GSPC', 'Dow Jones - USA': '^DJI', 'U.S. Dollar (DXY) - USA': 'DX-Y.NYB',
'E-Mini Dow Jones - USA': 'YM=F', 'E-Mini S&P 500 - USA': 'ES=F', 'E-Mini Nasdaq 100 - USA': 'NQ=F', 'E-Mini Russell 2000 - USA': 'RTY=F'}
try:
f = open('csv/indices_settings.json', 'r')
indices_settings = json.load(f)
@ -334,6 +358,15 @@ def index():
except:
economic_settings = {"feature": "Economic Calendar", "speed": "medium", "speed2": "medium", "animation": "up", "importance": "Med - High", "title": True, "timezone": "US/Eastern", "countries": ["United States"], "events": []}
try:
f = open('csv/jokes_settings.json', 'r')
jokes_settings = json.load(f)
f.close()
if not jokes_settings['categories']:
jokes_settings['categories'] = ['Any']
except:
jokes_settings = {"feature": "Jokes", "speed": "medium", "speed2": "medium", "animation": "up", "title": True, "safe": True, "categories": ["Any"], "blacklist": [], "amount": "5", "jokes": []}
try:
f = open('csv/scheduler.json','r')
scheduler_settings = json.load(f)
@ -355,17 +388,14 @@ def index():
ipo_api_key = ipo_api[0]
except:
ipo_api_key = ''
try:
wifi_SSID = wifiline[5][6:].replace('"','')
except:
wifi_SSID = ''
try:
wifi_PSK = wifiline[6][5:].replace('"','')
networks_list = networks
except:
wifi_PSK = ''
networks_list = ''
templateData = {
'system_info':system_info,
@ -395,9 +425,10 @@ def index():
'movie_api_key':movie_api_key,
'ipo_api_key':ipo_api_key,
'wifi_SSID':wifi_SSID,
'wifi_PSK':wifi_PSK,
'scheduler_settings':scheduler_settings,
'economic_settings':economic_settings
'economic_settings':economic_settings,
'jokes_settings':jokes_settings,
'networks_list': networks_list
}
@ -503,11 +534,11 @@ def save_displaying(input_settings):
global professional
all_settings = ['Stocks', 'Crypto', 'Forex', 'Commodities', 'Indices', 'Current Weather', 'Daily Forecast', 'News', 'Sports (Upcoming Games)', 'Sports (Past Games)',
'Sports (Live Games)', 'Sports (Team Stats)', 'Custom Images', 'Custom GIFs', 'Custom Messages', 'Movies', 'IPO Calendar', 'Economic Calendar']
'Sports (Live Games)', 'Sports (Team Stats)', 'Custom Images', 'Custom GIFs', 'Custom Messages', 'Movies', 'IPO Calendar', 'Economic Calendar', 'Jokes']
professional = len(input_settings) == 2
if professional:
all_settings = ['Stocks', 'Crypto', 'Forex', 'Commodities', 'Indices', 'Current Weather', 'News', 'Daily Forecast', 'Sports (Upcoming Games)',
'Sports (Past Games)', 'Sports (Team Stats)', 'Sports (Live Games)', 'Custom Messages', 'Custom Images', 'Movies', 'IPO Calendar', 'Economic Calendar']
'Sports (Past Games)', 'Sports (Team Stats)', 'Sports (Live Games)', 'Custom Messages', 'Custom Images', 'Movies', 'IPO Calendar', 'Economic Calendar', 'Jokes']
positions = []
display_settings = []
@ -652,6 +683,8 @@ def save():
save_ipo_settings(input_settings)
elif feature == 'Economic Calendar':
save_economic_settings(input_settings)
elif feature == 'Jokes':
save_jokes_settings(input_settings)
elif 'Sports' in feature:
save_sports_settings(input_settings)
@ -909,9 +942,9 @@ def savePortfolioSettings():
symbol1 = settings['symbol']
days1 = settings['days']
day_start = datetime.datetime.strptime(str(days1), "%Y-%m-%d")
day_today = datetime.datetime.strptime(datetime.datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
days1 = str((day_today - day_start).days)
# day_start = datetime.datetime.strptime(str(days1), "%Y-%m-%d")
# day_today = datetime.datetime.strptime(datetime.datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
# days1 = str((day_today - day_start).days)
portfolio['symbols'][symbol1] = {'shares':shares1, 'day':days1, 'cost':cost1}
@ -945,9 +978,9 @@ def savePortfolioCryptoSettings():
symbol1 = settings['symbol']
days1 = settings['days']
day_start = datetime.datetime.strptime(str(days1), "%Y-%m-%d")
day_today = datetime.datetime.strptime(datetime.datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
days1 = str((day_today - day_start).days)
# day_start = datetime.datetime.strptime(str(days1), "%Y-%m-%d")
# day_today = datetime.datetime.strptime(datetime.datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
# days1 = str((day_today - day_start).days)
portfolio['symbols'][symbol1] = {'shares':shares1, 'day':days1, 'cost':cost1}
@ -1098,8 +1131,8 @@ def save_trade_settings(input_settings):
'OMXS30 - Stockholm': '^OMX', 'AEX - Amsterdam': '^AEX', 'ATX - Austria': '^ATX', 'BEL 20 - Brussels': '^BFX',
'SSMI - Switzerland': '^SSMI', 'CAC 40 - France': '^FCHI', 'IBEX 35 - Spain': '^IBEX', 'FTSE 100 - UK': '^FTSE', 'Dax - Germany': '^GDAXI',
'Bovespa - Brazil': '^BVSP', 'IPC - Mexico': '^MXX', 'S&P/TSX - Canada': '^GSPTSE', 'VIX - USA': '^VIX', 'Russell 2000 - USA': '^RUT',
'Nasdaq Composite - USA': '^IXIC', 'Nasdaq 100 - USA': '^NDX', 'S&P 500 - USA': '^GSPC', 'Dow Jones - USA': '^DJI', 'U.S. Dollar (DXY) - USA': 'DX-Y.NYB'
}
'Nasdaq Composite - USA': '^IXIC', 'Nasdaq 100 - USA': '^NDX', 'S&P 500 - USA': '^GSPC', 'Dow Jones - USA': '^DJI', 'U.S. Dollar (DXY) - USA': 'DX-Y.NYB',
'E-Mini Dow Jones - USA': 'YM=F', 'E-Mini S&P 500 - USA': 'ES=F', 'E-Mini Nasdaq 100 - USA': 'NQ=F', 'E-Mini Russell 2000 - USA': 'RTY=F'}
try:
filename = input_settings['feature'].lower() + '_settings.json'
@ -1326,6 +1359,44 @@ def save_economic_settings(input_settings):
f.close()
def save_jokes_settings(input_settings):
filename = 'jokes_settings.json'
try:
f = open('csv/' + filename, 'r')
current_settings = json.load(f)
f.close()
except:
current_settings = {"feature": "Jokes", "speed": "medium", "speed2": "medium", "animation": "up", "title": True, "safe": True, "categories": ["Any"], "blacklist": [], "amount": "5", "jokes": []}
current_settings['speed'] = input_settings['speed'].lower()
current_settings['speed2'] = input_settings['speed2'].lower()
current_settings['animation'] = input_settings['animation'].lower()
current_settings['title'] = input_settings['title']
current_settings['safe'] = input_settings['safe']
if not input_settings['categories']:
current_settings['categories'] = ['Any']
else:
current_settings['categories'] = input_settings['categories']
current_settings['blacklist'] = input_settings['blacklist']
current_settings['amount'] = input_settings['amount']
try:
f = open('csv/' + filename, 'w')
json.dump(current_settings, f)
f.close()
except:
with open('csv/jokes_settings.json', 'w') as f:
json.dump(current_settings, f)
f = open('csv/last_updates.json', 'r')
last_updates = json.load(f)
f.close()
last_updates['jokes']['force'] = True
f = open('csv/last_updates.json', 'w')
json.dump(last_updates, f)
f.close()
def save_sports_settings(input_settings):
feature = input_settings['feature']
@ -1514,6 +1585,176 @@ def setTop20or10():
return index()
@app.route("/deletePortfolioPositionCrypto", methods=["POST"])
def deletePortfolioPositionCrypto():
value = request.data.decode('utf-8')
value2 = json.loads(value)
try:
with open("csv/portfolio_crypto_settings.json") as f:
data = json.load(f)
except:
data = {"symbols": {}}
try:
del data["symbols"][value2]
with open('csv/portfolio_crypto_settings.json', 'w') as f:
json.dump(data, f)
except:
pass
return index()
@app.route("/deletePortfolioPosition", methods=["POST"])
def deletePortfolioPosition():
value = request.data.decode('utf-8')
value2 = json.loads(value)
try:
with open("csv/portfolio_settings.json") as f:
data = json.load(f)
except:
data = {"symbols": {}}
try:
del data["symbols"][value2]
with open('csv/portfolio_settings.json', 'w') as f:
json.dump(data, f)
except:
pass
return index()
@app.route("/fetchStockPortfolio", methods=["POST"])
def fetchStockPortfolio():
value = request.data.decode('utf-8')
value2 = json.loads(value)
try:
with open("csv/portfolio_settings.json") as f:
data = json.load(f)
except:
data = {"symbols": {}}
try:
stock_pos_info = data['symbols'][value2]
except:
stock_pos_info = {}
return (stock_pos_info)
@app.route("/fetchCryptoPortfolio", methods=["POST"])
def fetchCryptoPortfolio():
value = request.data.decode('utf-8')
value2 = json.loads(value)
try:
with open("csv/portfolio_crypto_settings.json") as f:
data = json.load(f)
except:
data = {"symbols": {}}
try:
crypto_pos_info = data['symbols'][value2]
except:
crypto_pos_info = {}
return (crypto_pos_info)
@app.route("/fetchCustomMsg", methods=["POST"])
def fetch_custom_msg():
value = request.data.decode('utf-8')
value2 = json.loads(value)
try:
with open("csv/message_settings.json") as f:
data = json.load(f)
except:
data = {"feature": "Custom Messages", "speed": "medium", "speed2": "medium", "animation": "down", "title": False, "messages": [{"name": "welcome", "text": "Welcome to Fintic!", "text_colour": "White", "size": "Large", "background_colour": "Black"}, {"name": "get_started", "text": "To get started, connect your device to the \"Fintic Hotspot\" and access \"fintic.local:1024\" on your web browser. You can connect your ticker to Wi-Fi there.", "text_colour": "White", "size": "Small", "background_colour": "Black"}]}
for i, each in enumerate(data['messages']):
if each['name'] == value2:
the_info = {'index': i, 'text': data['messages'][i]['text'], 'name': data['messages'][i]['name'], 'size':data['messages'][i]['size'], 'text_colour': data['messages'][i]['text_colour'], 'background_colour': data['messages'][i]['background_colour']}
#the_info = data['messages'][i]
break
else:
the_info = {}
return (the_info)
@app.route("/sendMsgToJSON", methods = ['PUT', 'POST'])
def sendMsgToJSON():
data= request.data.decode('utf-8')
input_settings = json.loads(data)
if input_settings['name'] != '' and input_settings['text'] != '':
try:
with open('csv/message_settings.json','r') as f:
message_settings = json.load(f)
except:
message_settings = {"feature": "Custom Messages", "speed": "medium", "speed2": "medium", "animation": "down", "title": False, "messages": [{"name": "welcome", "text": "Welcome to Fintic!", "text_colour": "White", "size": "Large", "background_colour": "Black"}, {"name": "get_started", "text": "To get started, connect your device to the \"Fintic Hotspot\" and access \"fintic.local:1024\" on your web browser. You can connect your ticker to Wi-Fi there.", "text_colour": "White", "size": "Small", "background_colour": "Black"}]}
message_settings['messages'].append(input_settings)
with open('csv/message_settings.json', 'w') as f:
json.dump(message_settings, f)
return index()
@app.route("/updateSelectedMsg", methods=["PUT", "POST"])
def updateSelectedMsg():
value = request.data.decode('utf-8')
value2 = json.loads(value)
try:
with open("csv/message_settings.json") as f:
data = json.load(f)
except:
data = {"feature": "Custom Messages", "speed": "medium", "speed2": "medium", "animation": "down", "title": False, "messages": [{"name": "welcome", "text": "Welcome to Fintic!", "text_colour": "White", "size": "Large", "background_colour": "Black"}, {"name": "get_started", "text": "To get started, connect your device to the \"Fintic Hotspot\" and access \"fintic.local:1024\" on your web browser. You can connect your ticker to Wi-Fi there.", "text_colour": "White", "size": "Small", "background_colour": "Black"}]}
try:
data['messages'][value2['index']]['name'] = value2['name']
data['messages'][value2['index']]['text'] = value2['text']
data['messages'][value2['index']]['text_colour'] = value2['text_colour']
data['messages'][value2['index']]['size'] = value2['size']
data['messages'][value2['index']]['background_colour'] = value2['background_colour']
with open('csv/message_settings.json', 'w') as f:
json.dump(data, f)
except:
pass
return index()
@app.route("/savePromptStartStop", methods=["PUT", "POST"])
def savePromptStartStop():
stop()
time.sleep(0.1)
start()
return index()
@app.route("/scanNetworks", methods=["PUT", "POST"])
def scanNetworks2():
try:
output = subprocess.check_output(['sudo', 'iwlist', 'wlan0', 'scan'])
output_str = output.decode('utf-8')
lines = output_str.split('Cell')
global networks
networks = {}
for line in lines:
if 'ESSID:""\n' not in line and 'Scan completed' not in line:
ssid = line.split('ESSID:')[1].split('\n')[0]
ssid = ssid.replace('"', '', 1)
ssid = ssid[::-1].replace('"', '', 1)[::-1]
if 'AES' in ssid:
ssid = ssid.replace("AES", "CCMP")
try:
group_cipher = line.split('Group Cipher : ')[1].split('\n')[0]
pair_cipher = line.split('Pairwise Ciphers (1) : ')[1].split('\n')[0]
except:
group_cipher = ''
pair_cipher = ''
# quality = line.split('Quality=')[1].split('Signal level')[0].replace(" ", "")
networks[ssid] = {'group_cipher': group_cipher, 'pair_cipher': pair_cipher}
except:
networks = {}
return (networks)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=1024, debug=False) # the debuggger causes flickering

View File

@ -14,14 +14,14 @@ touch crypto_settings.json last_updates.json system_info.json
touch league_tables.json
mkdir sports
touch current_weather.json stocks_settings.json daily_weather.json live_games.json live_mlb.json live_mls.json live_nba.json live_nfl.json live_nhl.json live_pl.json commodities_settings.json indices_settings.json movie_settings.json ipo_settings.json
touch display_settings.json message_settings.json upcoming_games.json forex_settings.json prepost_settings.json scheduler.json economic_settings.json
touch display_settings.json message_settings.json upcoming_games.json forex_settings.json prepost_settings.json scheduler.json economic_settings.json jokes_settings.json
touch GIF_settings.json news_settings.json image_settings.json past_games.json general_settings.json portfolio_settings.json portfolio_crypto_settings.json
filenames="crypto_settings.json last_updates.json league_tables.json current_weather.json stocks_settings.json daily_weather.json live_games.json live_mlb.json live_mls.json live_nba.json live_nfl.json live_nhl.json live_pl.json commodities_settings.json indices_settings.json movie_settings.json ipo_settings.json economic_settings.json display_settings.json message_settings.json upcoming_games.json forex_settings.json GIF_settings.json news_settings.json image_settings.json past_games.json portfolio_settings.json portfolio_crypto_settings.json prepost_settings.json scheduler.json"
filenames="crypto_settings.json last_updates.json league_tables.json current_weather.json stocks_settings.json daily_weather.json live_games.json live_mlb.json live_mls.json live_nba.json live_nfl.json live_nhl.json live_pl.json commodities_settings.json indices_settings.json movie_settings.json ipo_settings.json economic_settings.json display_settings.json message_settings.json upcoming_games.json forex_settings.json GIF_settings.json news_settings.json image_settings.json past_games.json portfolio_settings.json portfolio_crypto_settings.json prepost_settings.json scheduler.json jokes_settings.json"
echo '{"update_available": false, "first_boot": true}' >> system_info.json
echo [\"Standard\", [[\"Stocks\", \"Crypto\", \"Forex\"]]] >> display_settings.json
echo '{"scheduler":{"force": false}, "stocks": {"time": "07/03/2022 12:33:06", "force": true}, "crypto": {"time": "07/03/2022 12:28:51", "force": true}, "news": {"time": "07/03/2022 12:28:51", "force": true}, "weather": {"time": "07/03/2022 12:28:51", "force": true}, "forex": {"time": "07/03/2022 12:28:51", "force": true}, "sports_l": {"time": "07/03/2022 12:32:46", "force": true}, "sports_p": {"time": "07/03/2022 12:32:26", "force": true}, "sports_u": {"time": "07/03/2022 12:31:55", "force": true}, "sports_t": {"time": "07/03/2022 12:32:56", "force": true}, "commodities": {"time": "07/03/2022 12:32:56", "force": true}, "indices": {"time": "07/03/2022 12:32:56", "force": true}, "movies": {"time": "07/03/2022 12:32:56", "force": true}, "ipo": {"time": "05/10/2022 02:31:40", "force": false}, "prepost": {"time": "05/10/2022 02:31:40", "force": false}, "economic": {"time": "05/10/2022 02:31:40", "force": false}}' >> last_updates.json
echo '{"scheduler":{"force": false}, "stocks": {"time": "07/03/2022 12:33:06", "force": true}, "crypto": {"time": "07/03/2022 12:28:51", "force": true}, "news": {"time": "07/03/2022 12:28:51", "force": true}, "weather": {"time": "07/03/2022 12:28:51", "force": true}, "forex": {"time": "07/03/2022 12:28:51", "force": true}, "sports_l": {"time": "07/03/2022 12:32:46", "force": true}, "sports_p": {"time": "07/03/2022 12:32:26", "force": true}, "sports_u": {"time": "07/03/2022 12:31:55", "force": true}, "sports_t": {"time": "07/03/2022 12:32:56", "force": true}, "commodities": {"time": "07/03/2022 12:32:56", "force": true}, "indices": {"time": "07/03/2022 12:32:56", "force": true}, "movies": {"time": "07/03/2022 12:32:56", "force": true}, "ipo": {"time": "05/10/2022 02:31:40", "force": false}, "prepost": {"time": "05/10/2022 02:31:40", "force": false}, "economic": {"time": "05/10/2022 02:31:40", "force": false}, "jokes": {"time": "05/10/2022 02:31:40", "force": false}}' >> last_updates.json
echo '{"feature": "Stocks", "speed": "medium","speed2": "medium", "animation": "down", "percent": false, "point": true, "logos": true, "chart": false, "title": true, "symbols": {"ETH,USD": {"current": "2629.32", "24hr_change": "-27.6432", "percent_change": "-1.04"}, "BTC,USD": {"current": "38161.00", "24hr_change": "-50.8386", "percent_change": "-0.13"}, "BNB,USD": {"current": "372.57", "24hr_change": "0.4140", "percent_change": "0.11"}, "ADA,BTC": {"current": "0.0000", "24hr_change": "-0.0000", "percent_change": "-3.74"}}}' >> crypto_settings.json
@ -51,6 +51,7 @@ echo '{"feature": "IPO", "speed": "medium", "speed2": "medium", "animation": "do
echo '{"symbols": {}}' >> portfolio_settings.json
echo '{"symbols": {}}' >> portfolio_crypto_settings.json
echo '{}' >> prepost_settings.json
echo '{"feature": "Jokes", "speed": "medium", "speed2": "medium", "animation": "up", "title": true, "safe": true, "categories": ["Any"], "blacklist": [], "amount": "5", "jokes": []}' >> jokes_settings.json
echo '{"shutdown": {"hour": "00", "minute": "00", "enabled": false}, "reboot":{"hour": "00", "minute": "00", "enabled": false}, "timezone": "GMT", "brightness1":{"hour": "00", "minute": "00", "bright": "10", "enabled": false}, "brightness2":{"hour": "00", "minute": "00", "bright": "10", "enabled": false}}, "brightness3":{"hour": "00", "minute": "00", "bright": "10", "enabled": false}}, "brightness4":{"hour": "00", "minute": "00", "bright": "10", "enabled": false}}' >> scheduler.json
echo '{"feature": "Economic Calendar", "speed": "medium", "speed2": "medium", "animation": "up", "importance": "Med - High", "title": true, "timezone": "US/Eastern", "countries": ["United States"], "events": []}' >> economic_settings.json
@ -105,6 +106,8 @@ touch 'IPO Calendar.ppm'
touch 'IPO Calendar Prof.ppm'
touch 'Economic Calendar.ppm'
touch 'Economic Calendar Prof.ppm'
touch 'Jokes.ppm'
touch 'Jokes Prof.ppm'
chmod 777 *

View File

@ -49,6 +49,7 @@ var indicesFeatures = document.querySelectorAll("#indices-features li");
var moviesFeatures = document.querySelectorAll("#movies-features li");
var ipoFeatures = document.querySelectorAll("#ipo-features li");
var economicFeatures = document.querySelectorAll("#economic-list li");
var jokesFeatures = document.querySelectorAll("#jokes-list li");
var allFeaturesList = [
stocksFeatures,
@ -69,6 +70,7 @@ var allFeaturesList = [
moviesFeatures,
ipoFeatures,
economicFeatures,
jokesFeatures,
];
// features remove buttons
@ -96,6 +98,7 @@ var indicesRemoveBtn = document.getElementById("indices-remove-btn");
var moviesRemoveBtn = document.getElementById("movies-remove-btn");
var ipoRemoveBtn = document.getElementById("ipo-remove-btn");
var economicRemoveBtn = document.getElementById("economic-remove-btn");
var jokesRemoveBtn = document.getElementById("jokes-remove-btn");
var allFeaturesRemoveBtns = [
stocksRemoveBtn,
@ -116,6 +119,7 @@ var allFeaturesRemoveBtns = [
moviesRemoveBtn,
ipoRemoveBtn,
economicRemoveBtn,
jokesRemoveBtn,
];
// features increase buttons
var stocksincreaseBtn = document.getElementById("stocks-increase-btn");
@ -142,6 +146,7 @@ var indicesincreaseBtn = document.getElementById("indices-increase-btn");
var moviesincreaseBtn = document.getElementById("movies-increase-btn");
var ipoincreaseBtn = document.getElementById("ipo-increase-btn");
var economicincreaseBtn = document.getElementById("economic-increase-btn");
var jokesincreaseBtn = document.getElementById("jokes-increase-btn");
var allFeaturesIncreaseBtns = [
stocksincreaseBtn,
@ -162,6 +167,7 @@ var allFeaturesIncreaseBtns = [
moviesincreaseBtn,
ipoincreaseBtn,
economicincreaseBtn,
jokesincreaseBtn,
];
// features decrease buttons
@ -189,6 +195,7 @@ var indicesDecreaseBtn = document.getElementById("indices-decrease-btn");
var moviesDecreaseBtn = document.getElementById("movies-decrease-btn");
var ipoDecreaseBtn = document.getElementById("ipo-decrease-btn");
var economicDecreaseBtn = document.getElementById("economic-decrease-btn");
var jokesDecreaseBtn = document.getElementById("jokes-decrease-btn");
var allFeaturesDecreaseBtns = [
stocksDecreaseBtn,
@ -209,6 +216,7 @@ var allFeaturesDecreaseBtns = [
moviesDecreaseBtn,
ipoDecreaseBtn,
economicDecreaseBtn,
jokesDecreaseBtn,
];
const changeVarValue = () => {
@ -236,6 +244,7 @@ const changeVarValue = () => {
moviesFeatures = document.querySelectorAll("#movies-features li");
ipoFeatures = document.querySelectorAll("#ipo-features li");
economicFeatures = document.querySelectorAll("#economic-list li");
jokesFeatures = document.querySelectorAll("#jokes-list li");
allFeaturesList = [
stocksFeatures,
@ -256,6 +265,7 @@ const changeVarValue = () => {
moviesFeatures,
ipoFeatures,
economicFeatures,
jokesFeatures,
];
};
@ -329,6 +339,7 @@ const addEventonBtns = () => {
availableFeatures = document.querySelectorAll("#available-features li");
displayToFormat = document.querySelectorAll("#display-format li");
addEventOnList();
displaySavePrompt();
}
}
});
@ -343,6 +354,7 @@ const addEventonBtns = () => {
availableFeatures = document.querySelectorAll("#available-features li");
displayToFormat = document.querySelectorAll("#display-format li");
addEventOnList();
displaySavePrompt();
}
}
});
@ -359,6 +371,7 @@ const addEventonBtns = () => {
);
displayToFormat2 = document.querySelectorAll("#display-format-2 li");
addEventOnList();
displaySavePrompt();
}
}
});
@ -375,6 +388,7 @@ const addEventonBtns = () => {
);
displayToFormat2 = document.querySelectorAll("#display-format-2 li");
addEventOnList();
displaySavePrompt();
}
}
});
@ -439,7 +453,7 @@ const addEventOnFeaturesList = () => {
let inputMsg = document.getElementById("inputText14");
let inputColor = document.getElementById("inputScrollSpeed16");
let inputSize = document.getElementById("inputScrollSpeed17");
let inputBg = document.getElementById("inputScrollSpeed19");
let inputBg = document.getElementById("inputScrollSpeed19BG");
let displayCheck = document.getElementById("flexCheckChecked29");
if (value.messageName == availableFeature.innerText) {
@ -473,6 +487,7 @@ displayincreaseBtn.addEventListener("click", () => {
prevElement.innerText = currentText;
prevElement.setAttribute("class", "active");
displayItem.setAttribute("class", "");
displaySavePrompt();
}
}
});
@ -490,6 +505,7 @@ displayincreaseBtn2.addEventListener("click", () => {
prevElement.innerText = currentText;
prevElement.setAttribute("class", "active");
displayItem.setAttribute("class", "");
displaySavePrompt();
}
}
});
@ -507,6 +523,7 @@ displayDecreaseBtn.addEventListener("click", () => {
nextElement.innerText = currentText;
nextElement.setAttribute("class", "active");
displayItem.setAttribute("class", "");
displaySavePrompt();
break;
}
}
@ -524,6 +541,7 @@ displayDecreaseBtn2.addEventListener("click", () => {
nextElement.innerText = currentText;
nextElement.setAttribute("class", "active");
displayItem.setAttribute("class", "");
displaySavePrompt();
break;
}
}
@ -544,6 +562,7 @@ allFeaturesRemoveBtns.map((value, index) => {
method: "POST",
body: JSON.stringify(symbol),
});
displaySavePrompt2();
}
else if ((item.getAttribute("class") == "active") && (index == 1 )){
let symbol = item.innerText;
@ -554,11 +573,13 @@ allFeaturesRemoveBtns.map((value, index) => {
method: "POST",
body: JSON.stringify(symbol),
});
displaySavePrompt2();
}
else if (item.getAttribute("class") == "active") {
item.remove();
uploaded_images = [];
uploaded_GIFs = [];
displaySavePrompt2();
}
}
});
@ -577,6 +598,7 @@ allFeaturesIncreaseBtns.map((value, index) => {
prevElement.innerText = currentText;
prevElement.setAttribute("class", "active");
item.setAttribute("class", "");
displaySavePrompt2();
}
}
});
@ -596,6 +618,7 @@ allFeaturesDecreaseBtns.map((value, index) => {
nextElement.innerText = currentText;
nextElement.setAttribute("class", "active");
item.setAttribute("class", "");
displaySavePrompt2();
break;
}
}
@ -621,6 +644,7 @@ var indices = document.getElementById("indices-features");
var movies = document.getElementById("movies-features");
var ipos = document.getElementById("ipo-features");
var economics = document.getElementById("economic-list");
var jokes = document.getElementById("jokes-list");
var allFeatures = [
stocks,
@ -641,6 +665,7 @@ var allFeatures = [
movies,
ipos,
economics,
jokes,
];
// features select box
@ -651,6 +676,7 @@ var liveGamesSelect = document.getElementById("inputTransition93");
var teamStatsSelect = document.getElementById("inputTransition103");
var moviesSelect = document.getElementById("inputTransition64");
var economicSelect = document.getElementById("inputTransition2222");
var jokesSelect = document.getElementById("jokes-categories");
var allFeaturesSelectBox = [
null,
null,
@ -670,6 +696,7 @@ var allFeaturesSelectBox = [
moviesSelect,
null,
economicSelect,
jokesSelect,
];
// features select add buttons
@ -679,6 +706,7 @@ var pastGamesAddBtn = document.getElementById("inputTransitionBtn83");
var liveGamesAddBtn = document.getElementById("inputTransitionBtn93");
var teamStatsAddBtn = document.getElementById("inputTransitionBtn103");
var economicAddBtn = document.getElementById("economic-countries-btn");
var jokesAddBtn = document.getElementById("jokes-categories-btn");
var allFeaturesSelectAddBtn = [
null,
@ -699,6 +727,7 @@ var allFeaturesSelectAddBtn = [
null,
null,
economicAddBtn,
jokesAddBtn,
];
allFeaturesSelectAddBtn.map((value, index) => {
@ -709,6 +738,7 @@ allFeaturesSelectAddBtn.map((value, index) => {
allFeatures[index].appendChild(tag);
changeVarValue();
addEventOnFeaturesList();
displaySavePrompt2();
});
}
});
@ -736,6 +766,7 @@ var allFeaturesFile = [
null,
null,
null,
null,
];
// features file add button
var imagesFileAddBtn = document.getElementById("inputTextBtn11");
@ -760,6 +791,7 @@ var allFeaturesFileAddBtn = [
null,
null,
null,
null,
];
// features input text
@ -791,6 +823,7 @@ var allFeaturesText = [
null,
null,
null,
null,
];
// features text add button
@ -822,6 +855,7 @@ var allFeaturesTextAddBtn = [
null,
null,
null,
null,
];
@ -844,6 +878,7 @@ var allFeaturesLimit = [
null,
null,
null,
null,
];
@ -867,7 +902,7 @@ allFeaturesTextAddBtn.map((value, index) => {
let colorInput = document.getElementById("inputScrollSpeed16").value;
let sizeInput = document.getElementById("inputScrollSpeed17").value;
let backgroundInput =
document.getElementById("inputScrollSpeed19").value;
document.getElementById("inputScrollSpeed19BG").value;
let displayCheck =
document.getElementById("flexCheckChecked29").checked;
let messagesWrapper = document.getElementById("messages-features");
@ -910,11 +945,12 @@ allFeaturesTextAddBtn.map((value, index) => {
else{
tag.innerHTML = allFeaturesText[index].value;
tag.setAttribute("onclick", "getCustomMsg(this.innerText)");
allFeatures[index].appendChild(tag);
changeVarValue();
addEventOnFeaturesList();
displaySavePrompt2();
createLi = false;
}}
} else {
var msg = "You've reached the maximum limit of items to add for this feature";
@ -929,12 +965,19 @@ allFeaturesTextAddBtn.map((value, index) => {
var tag = document.createElement("li");
if (index == 2) {
tag.innerHTML= document.getElementById("base-select").value + ',' + document.getElementById("quote-select").value;
} else{
} else if (index == 0) {
tag.innerHTML = allFeaturesText[index].value;
tag.setAttribute("onclick", "getStockSymbol(this.innerText)");
} else if (index == 1) {
tag.innerHTML = allFeaturesText[index].value;
tag.setAttribute("onclick", "getCryptoSymbol(this.innerText)");
} else {
tag.innerHTML = allFeaturesText[index].value;
}
allFeatures[index].appendChild(tag);
changeVarValue();
addEventOnFeaturesList();
displaySavePrompt2();
createLi = false;
}
}
@ -1109,6 +1152,7 @@ function getFeatureSettings() {
"Movies",
"IPO Calendar",
"Economic Calendar",
"Jokes",
];
let pageNum = features.indexOf(feature) + 1;
let pageSelector = "Page" + pageNum.toString();
@ -1174,6 +1218,9 @@ function getFeatureSettings() {
case 18:
s = getEconomicSettings(page);
break;
case 19:
s = getJokesSettings(page);
break;
}
settings = { ...settings, ...s }; // merge both sets of settings
@ -1366,6 +1413,7 @@ function saveMovieAPIKey(){
"Movies",
"IPO Calendar",
"Economic Calendar",
"Jokes",
];
let pageNum = features.indexOf(feature) + 1;
let pageSelector = "Page" + pageNum.toString();
@ -1408,6 +1456,7 @@ function saveIpoAPIKey(){
"Movies",
"IPO Calendar",
"Economic Calendar",
"Jokes",
];
let pageNum = features.indexOf(feature) + 1;
let pageSelector = "Page" + pageNum.toString();
@ -1584,6 +1633,7 @@ allFeaturesFileAddBtn.map((value, index) => {
imagesFile.value = "";
changeVarValue();
addEventOnFeaturesList();
displaySavePrompt2();
});
}
});
@ -1600,8 +1650,8 @@ function getImageSettings(page) {
return settings;
}
// ADD MSG TO LIST AND SAVE MSG TO JSON FILE
var messages = [];
messagesTextAddBtn.addEventListener("click", () => {
let pageSelector = "Page13";
@ -1624,6 +1674,11 @@ messagesTextAddBtn.addEventListener("click", () => {
background_colour: background_colour,
};
messages.push(message);
fetch("/sendMsgToJSON", {
method: "POST",
body: JSON.stringify(message),
});
});
function getMessageSettings(page) {
@ -1677,6 +1732,33 @@ function getEconomicSettings(page) {
}
// jokes settings
function getJokesSettings(page) {
let title = page.querySelectorAll(".title-select")[0].checked;
let categories = getListItems(page.querySelectorAll(".symbol-list")[0]);
let amount = page.querySelectorAll(".jokes-amount-select")[0].value;
let safe = page.querySelectorAll(".title-select")[1].checked;
const jokesdivElement = page.querySelector('.blacklist-checkboxes');
const allcheckboxes = jokesdivElement.querySelectorAll('input');
const blacklist = [];
allcheckboxes.forEach(checkbox => {
if (checkbox.checked) {
blacklist.push(checkbox.value);
}
});
settings = {
title: title,
safe: safe,
categories: categories,
blacklist: blacklist,
amount: amount,
};
console.log(settings);
return settings;
}
// Join Network
let wifiSsidInput = document.getElementById("wifi-ssid-input");
@ -1717,6 +1799,7 @@ displayFormatBtn.addEventListener("click", () => {
topRowText.style.display = "inline";
bottomRowText.style.display = "inline";
secondRow.style.display = "flex";
displaySavePrompt();
inputScrollSpeedRow.forEach((value) => {
value.parentElement.parentElement.style.display = "flex";
});
@ -1724,6 +1807,7 @@ displayFormatBtn.addEventListener("click", () => {
topRowText.style.display = "none";
bottomRowText.style.display = "none";
secondRow.style.display = "none";
displaySavePrompt();
inputScrollSpeedRow.forEach((value) => {
value.parentElement.parentElement.style.display = "none";
});
@ -1808,7 +1892,7 @@ inputAnimationBtn.addEventListener("click", () => {
// scroll speed row two
let inputScrollSpeedRow = [];
for (let i = 1; i <= 18; i++) {
for (let i = 1; i <= 19; i++) {
inputScrollSpeedRow.push(
document.getElementById(
i === 1 ? "inputScrollSpeedRow" : `inputScrollSpeedRow${i}`
@ -2755,3 +2839,512 @@ function setTop20() {
});
}
let theIndexOfMsg = null
// get custom message values
function getCustomMsg(value) {
let messaged = value;
const the_thing = document.getElementById("inputText13");
const the_msg = document.getElementById("inputText14");
const t_color = document.getElementById("inputScrollSpeed16");
const b_color = document.getElementById("inputScrollSpeed19BG");
const t_size = document.getElementById("inputScrollSpeed17");
the_thing.value = messaged;
fetch("/fetchCustomMsg", {
method: "POST",
body: JSON.stringify(messaged),
})
.then(response => response.json())
.then(data => {
// Update the elements with the retrieved information
the_msg.value = data.text;
t_color.value = data.text_colour;
b_color.value = data.background_colour;
t_size.value = data.size;
theIndexOfMsg = data.index;
})
.catch(error => {
console.error('Error:', error);
});
}
// get custom message values
function updateSelectedMsg(){
const msg_name = document.getElementById("inputText13").value;
const msg_text = document.getElementById("inputText14").value;
if ((msg_name !== '') && (msg_text !== '')) {
const text_color = document.getElementById("inputScrollSpeed16").value;
const background_color = document.getElementById("inputScrollSpeed19BG").value;
const text_size = document.getElementById("inputScrollSpeed17").value;
document.getElementById('demo4').style.display = "none";
document.getElementById('demo5').style.display = "none";
fetch("/updateSelectedMsg", {
method: "POST",
body: JSON.stringify({'name': msg_name, 'text': msg_text, 'text_colour': text_color, 'size': text_size, 'background_colour': background_color, 'index':theIndexOfMsg}),
});
const ulElement = document.getElementById("messages-features");
const activeListItem = ulElement.querySelector("li.active");
activeListItem.innerText = msg_name;
activeListItem.classList.remove("active");
theIndexOfMsg = null;
document.getElementById('updated-message-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('updated-message-p').style.display = "none";
}, 5000);
}
else {
customMsgValidate();
}
}
// get stock portfolio values
function getStockSymbol(value) {
let stock_symbol = value;
const stock_thing = document.getElementById("inputText3");
const stock_shares = document.getElementById("inputText8");
const stock_cost = document.getElementById("inputText9");
const stock_date = document.getElementById("inputText10");
const stock_portfolio_check = document.getElementById("flexCheckChecked4");
stock_thing.value = stock_symbol;
if (stock_portfolio_check.checked) {
fetch("/fetchStockPortfolio", {
method: "POST",
body: JSON.stringify(stock_symbol),
})
.then(response => response.json())
.then(data => {
if (JSON.stringify(data) !== '{}') {
// Update the elements with the retrieved information
stock_shares.value = data.shares;
stock_cost.value = data.cost;
stock_date.value = data.day;
} else {
stock_shares.value = '';
stock_cost.value = '';
stock_date.value = '';
}
})
.catch(error => {
console.error('Error:', error);
});
}}
// get crypto portfolio values
function getCryptoSymbol(value) {
let crypto_symbol = value;
const crypto_thing = document.getElementById("inputText4");
const crypto_shares = document.getElementById("cryptoshares");
const crypto_cost = document.getElementById("cryptocost");
const crypto_date = document.getElementById("cryptodate");
const crypto_portfolio_check = document.getElementById("crypto_portfolio_checkbox");
crypto_thing.value = crypto_symbol;
if (crypto_portfolio_check.checked) {
fetch("/fetchCryptoPortfolio", {
method: "POST",
body: JSON.stringify(crypto_symbol),
})
.then(response => response.json())
.then(data => {
if (JSON.stringify(data) !== '{}') {
// Update the elements with the retrieved information
crypto_shares.value = data.shares;
crypto_cost.value = data.cost;
crypto_date.value = data.day;
} else {
crypto_shares.value = '';
crypto_cost.value = '';
crypto_date.value = '';
}
})
.catch(error => {
console.error('Error:', error);
});
}}
// remove stock portfolio position
function removeStockPorftolio() {
let remove_stock_symbol = document.getElementById('inputText3').value;
if (remove_stock_symbol !== '') {
document.getElementById('inputText9').value = '';
document.getElementById('inputText8').value = '';
document.getElementById('inputText10').value = '';
fetch("/deletePortfolioPosition", {
method: "POST",
body: JSON.stringify(remove_stock_symbol),
});
document.getElementById('stockremoved-p').innerHTML = 'Stock Position Removed!';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
else {
document.getElementById('stockremoved-p').innerHTML = 'No symbol selected.';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
}
// update stock portfolio position with new values
function updateStockPorftolio() {
let update_stock_cost = document.getElementById('inputText9').value;
let update_stock_shares = document.getElementById('inputText8').value;
let update_symbol = document.getElementById('inputText3').value;
let update_stock_days = document.getElementById('inputText10').value;
let update_stock_settings = {
shares:update_stock_shares,
cost:update_stock_cost,
symbol:update_symbol,
days:update_stock_days,
};
if ((update_symbol === '') || (update_symbol === ' ')) {
document.getElementById('stockremoved-p').innerHTML = 'No symbol selected.';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
else if ((update_stock_cost === ' ') || (update_stock_shares === ' ') || (update_stock_days === ' ')) {
document.getElementById('stockremoved-p').innerHTML = 'No spaces.';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
else if ((isNaN(update_stock_cost)) || (isNaN(update_stock_shares))) {
document.getElementById('stockremoved-p').innerHTML = 'No text characters, only numbers.';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
else if ((!update_stock_days.includes('-')) && (update_stock_days !== '')) {
document.getElementById('stockremoved-p').innerHTML = 'Incorrect date format, it should be YYYY-MM-DD';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
else if (((update_stock_shares !== '') || (update_stock_cost !== '') || (update_stock_days !== '')) && ((update_stock_shares === '') || (update_stock_cost === '') || (update_stock_days === ''))) {
document.getElementById('stockremoved-p').innerHTML = 'Some fields are empty.';
document.getElementById('removed-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-stock-p').style.display = "none";
}, 5000);
}
else {
fetch("/savePortfolioSettings", {
method: "POST",
body: JSON.stringify(update_stock_settings),
});
document.getElementById('updated-stock-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('updated-stock-p').style.display = "none";
}, 5000);
}
}
// remove crypto portfolio position
function removeCryptoPorftolio() {
let remove_crypto_symbol = document.getElementById('inputText4').value;
if (remove_crypto_symbol !== '') {
document.getElementById('cryptoshares').value = '';
document.getElementById('cryptocost').value = '';
document.getElementById('cryptodate').value = '';
fetch("/deletePortfolioPositionCrypto", {
method: "POST",
body: JSON.stringify(remove_crypto_symbol),
});
document.getElementById('cryptoremoved-p').innerHTML = 'Crypto Position Removed!';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
else {
document.getElementById('cryptoremoved-p').innerHTML = 'No symbol selected.';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
}
// update crypto portfolio position with new values
function updateCryptoPorftolio() {
let update_crypto_cost = document.getElementById('cryptocost').value;
let update_crypto_shares = document.getElementById('cryptoshares').value;
let update_crypto_symbol = document.getElementById('inputText4').value;
let update_crypto_days = document.getElementById('cryptodate').value;
let update_crypto_settings = {
shares:update_crypto_shares,
cost:update_crypto_cost,
symbol:update_crypto_symbol,
days:update_crypto_days,
};
if ((update_crypto_symbol === '') || (update_crypto_symbol === ' ')) {
document.getElementById('cryptoremoved-p').innerHTML = 'No symbol selected.';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
else if ((update_crypto_cost === ' ') || (update_crypto_shares === ' ') || (update_crypto_days === ' ')) {
document.getElementById('cryptoremoved-p').innerHTML = 'No spaces.';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
else if ((isNaN(update_crypto_cost)) || (isNaN(update_crypto_shares))) {
document.getElementById('cryptoremoved-p').innerHTML = 'No text characters, only numbers.';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
else if ((!update_crypto_days.includes('-')) && (update_crypto_days !== '')) {
document.getElementById('cryptoremoved-p').innerHTML = 'Incorrect date format, it should be YYYY-MM-DD';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
else if (((update_crypto_shares !== '') || (update_crypto_cost !== '') || (update_crypto_days !== '')) && ((update_crypto_shares === '') || (update_crypto_cost === '') || (update_crypto_days === ''))) {
document.getElementById('cryptoremoved-p').innerHTML = 'Some fields are empty.';
document.getElementById('removed-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('removed-crypto-p').style.display = "none";
}, 5000);
}
else {
fetch("/savePortfolioCryptoSettings", {
method: "POST",
body: JSON.stringify(update_crypto_settings),
});
document.getElementById('updated-crypto-p').style.display = "block";
setTimeout(function hideElement() {
document.getElementById('updated-crypto-p').style.display = "none";
}, 5000);
}
}
// SAVE FEATURES TO DISPLAY PROMPT FUNCTIONS
var savePromptTimeout;
var isSavePromptRunning = false;
function displaySavePrompt() {
// Check if the function is already running
if (isSavePromptRunning) {
return;
}
isSavePromptRunning = true;
document.getElementById('save-prompt-message').style.display = "block";
var savePrompt = document.getElementById('save-prompt-p');
// Store the original color
var originalColor = savePrompt.style.color;
// Set the new color for the transition effect
savePrompt.style.color = "yellow";
// Clear any existing timeout
clearTimeout(savePromptTimeout);
// Add a delay before reverting back to the original color
savePromptTimeout = setTimeout(function() {
savePrompt.style.color = originalColor;
isSavePromptRunning = false;
},300); // 0.3 seconds
}
function closeSavePrompt() {
document.getElementById('save-prompt-message').style.display = "none";
}
function savePrompt() {
saveSettings();
document.getElementById('save-prompt-message').style.display = "none";
setTimeout(
function() {
document.getElementById('saved-msg-feedback').style.display = "block";
fetch("/savePromptStartStop", {
method: "PUT",
});
}, 100);
setTimeout(
function() {
document.getElementById('saved-msg-feedback').style.display = "none";
}, 3000);
}
// SAVE FEATURE SETTINGS PROMPT FUNCTIONS
var savePromptTimeout2;
var isSavePromptRunning2 = false;
function displaySavePrompt2() {
// Check if the function is already running
if (isSavePromptRunning2) {
return;
}
isSavePromptRunning2 = true;
document.getElementById('save-feature-prompt-message').style.display = "block";
var savePrompt2 = document.getElementById('save-feature-prompt-p');
// Store the original color
var originalColor2 = savePrompt2.style.color;
// Set the new color for the transition effect
savePrompt2.style.color = "yellow";
// Clear any existing timeout
clearTimeout(savePromptTimeout2);
// Add a delay before reverting back to the original color
savePromptTimeout2 = setTimeout(function() {
savePrompt2.style.color = originalColor2;
isSavePromptRunning2 = false;
},300); // 0.3 seconds
}
function closeFeatureSavePrompt() {
document.getElementById('save-feature-prompt-message').style.display = "none";
}
function featureSavePrompt() {
saveSettings();
document.getElementById('save-feature-prompt-message').style.display = "none";
setTimeout(
function() {
document.getElementById('saved-feature-msg-feedback').style.display = "block";
}, 100);
setTimeout(
function() {
document.getElementById('saved-feature-msg-feedback').style.display = "none";
}, 3000);
}
const pageIDs = ['Page1', 'Page2', 'Page3', 'Page4', 'Page5', 'Page6', 'Page7', 'Page8', 'Page9', 'Page10', 'Page11', 'Page12', 'Page13',
'Page14', 'Page15', 'Page16', 'Page17', 'Page18', 'Page19'];
for (const pageID of pageIDs) {
// Select the parent div
const parentDiv = document.getElementById(pageID);
// Add event listeners to select menus
const excludedIds = ['base-select', 'quote-select', 'commodities-items', 'indices-items', 'inputTransition73',
'inputTransition83', 'inputTransition93', 'inputTransition103', 'inputTransition2222', 'jokes-categories', 'golf-ranking-number',
'inputScrollSpeed16', 'inputScrollSpeed17', 'inputScrollSpeed19BG'];
const selectMenus = parentDiv.querySelectorAll('select');
selectMenus.forEach(selectMenu => {
const id = selectMenu.id;
if (!excludedIds.includes(id)) {
selectMenu.addEventListener('change', function(event) {
displaySavePrompt2();
});
}
});
// Add event listeners to input checkboxes
const inputForms = parentDiv.querySelectorAll('input[type="checkbox"]');
inputForms.forEach(inputForm => {
inputForm.addEventListener('input', function(event) {
displaySavePrompt2();
});
});
}
// for drop down menu, change feature settings prompt text
var selectMenu = document.getElementById("drop");
var pElement = document.getElementById("save-feature-prompt-p");
var pElement2 = document.getElementById("saved-feature-msg-feedback");
// Add an event listener for the "change" event
selectMenu.addEventListener("change", function() {
document.getElementById('save-feature-prompt-message').style.display = "none";
var selectedOption = selectMenu.selectedOptions[0];
var selectedValue = selectedOption.textContent;
pElement.textContent = selectedValue + " Settings - Changes detected.";
pElement2.innerHTML = selectedValue + " Settings -" + "<br>" + " Saved!";
});
// load selected network item into ssid input
function sendNetworkToSSID(element) {
var networksList = document.getElementById('networks-list');
var lis = networksList.querySelectorAll("li");
var ssid_input = document.getElementById('wifi-ssid-input');
var value = element.innerText;
lis.forEach(function(li) {
li.classList.remove("active");
});
ssid_input.value = value;
element.classList.add("active");
}
// scan nearby networks
function scanNetworks() {
var networksListReset = document.getElementById("networks-list");
networksListReset.innerHTML = "";
var listItem2 = document.createElement("li");
listItem2.textContent = "Scanning networks...";
networksListReset.appendChild(listItem2);
fetch("/scanNetworks", {
method: "PUT",
})
.then(response => response.text())
.then(data => {
// Parse the response data as JSON
var networks = JSON.parse(data);
networksListReset.innerHTML = "";
// Iterate over the networks object and create list items
for (var ssid in networks) {
var listItem = document.createElement("li");
listItem.textContent = ssid;
listItem.onclick = function() {
sendNetworkToSSID(this);
};
networksListReset.appendChild(listItem);
}
})
.catch(error => console.log(error));
}

View File

@ -1307,3 +1307,143 @@ input[type=checkbox]:hover {
margin-bottom:2%;
}
#save-prompt-message {
width: 160px;
height: 150px;
border-radius: 20px;
background-color: rgba(5,5,5,0.5);
backdrop-filter: blur(6px);
border-color: #5D5D5D;
border-style: solid;
border-width: thin;
position: fixed;
top: 35%;
right: 20px;
transform: translateY(-50%);
z-index: 99;
}
#save-prompt-p {
margin: 35px 10px 15px 10px;
font-size: 14px;
text-align: center;
display: flex;
color: red;
justify-content: center;
align-items: center;
transition: color 0.3s;
}
#save-prompt-btn {
display: block;
margin: 0 auto;
font-size: 16px;
}
#save-prompt-close-btn {
background-color: transparent;
border: none;
color: white;
font-size: 16px;
text-decoration: underline;
position: absolute;
top: 0;
right: 15px;
}
#save-prompt-close-btn:hover {
background-color: transparent;
border: none;
color: darkgray;
text-decoration: underline;
}
#save-prompt-close-btn:active {
background-color: transparent;
border: none;
color: #4B4B4B;
text-decoration: underline;
}
#saved-msg-feedback{
color: red;
font-size: 16px;
position: fixed;
top: 35%;
right: 20px;
transform: translateY(-50%);
z-index: 99;
text-align: center;
}
#save-feature-prompt-message {
width: 160px;
height: 170px;
border-radius: 20px;
background-color: rgba(5,5,5,0.5);
backdrop-filter: blur(6px);
border-color: #5D5D5D;
border-style: solid;
border-width: thin;
position: fixed;
top: 65%;
right: 20px;
transform: translateY(-50%);
z-index: 99;
}
#save-feature-prompt-p {
margin: 35px 10px 15px 10px;
font-size: 14px;
text-align: center;
display: flex;
color: cyan;
justify-content: center;
align-items: center;
transition: color 0.3s;
}
#save-feature-prompt-btn {
display: block;
margin: 0 auto;
font-size: 16px;
}
#save-feature-prompt-close-btn {
background-color: transparent;
border: none;
color: white;
font-size: 16px;
text-decoration: underline;
position: absolute;
top: 0;
right: 15px;
}
#save-feature-prompt-close-btn:hover {
background-color: transparent;
border: none;
color: darkgray;
text-decoration: underline;
}
#save-feature-prompt-close-btn:active {
background-color: transparent;
border: none;
color: #4B4B4B;
text-decoration: underline;
}
#saved-feature-msg-feedback {
color: cyan;
font-size: 16px;
position: fixed;
top: 65%;
right: 20px;
transform: translateY(-50%);
z-index: 99;
text-align: center;
}
@media (max-width: 500px) {
.mx-auto {
flex-direction: column;
}
.mr-5 {
margin-left: 0;
margin-top: 20px;
}
}

View File

@ -5,7 +5,7 @@
# stockTicker can not be copied and/or distributed without the express
# permission of Fintic
import random
import sys, select
import os
import threading
@ -67,23 +67,23 @@ class StockTicker():
self.points = True # display crypto change in points or percent
self.functions = {'Stocks': self.getStockImage, 'Crypto': self.getCryptoImage, 'Forex': self.getForexImage,
'Daily Forecast':self.getDailyWeatherImage, 'Current Weather': self.getTodayWeatherImage,
'Daily Forecast':self.getDailyWeatherImage, 'Current Weather': self.getTodayWeatherImage, 'Jokes': self.getJokesImage,
'Sports (Team Stats)':lambda : self.getLeagueTableImage('premier_league'), 'Sports (Past Games)': lambda:self.getLeagueImage('NBA', 'past'),
'Sports (Upcoming Games)': lambda : self.getLeagueImage('NHL', 'future'), 'Sports (Live Games)': lambda: self.getLeagueImage('NBA', 'live'),
'News':self.getNewsImage, 'Custom Messages': self.getUserMessages, 'Commodities': self.getCommoditiesImage, 'Indices': self.getIndicesImage, 'Movies': self.getMoviesImage,
'Economic Calendar': self.getEconomicImage, 'IPO Calendar':self.getIpoImage, 'IPO Calendar Prof':self.getIpoProfessional, 'Economic Calendar Prof': self.getEconomicProfessional,
'Stocks Prof': self.getStockProfessional, 'Crypto Prof': self.getCryptoProfessional, 'Forex Prof': self.getForexProfessional,
'Stocks Prof': self.getStockProfessional, 'Crypto Prof': self.getCryptoProfessional, 'Forex Prof': self.getForexProfessional, 'Jokes Prof': self.getJokesProfessional,
'Current Weather Prof': self.getTodayWeatherProfessional, 'News Prof':self.getNewsProfessional, 'Commodities Prof':self.getCommoditiesProfessional, 'Indices Prof': self.getIndicesProfessional,
'Daily Forecast Prof':self.getDailyWeatherProfessional, 'Sports (Team Stats) Prof':lambda : self.getLeagueTableProfessional('NHL'), 'Sports (Upcoming Games) Prof': lambda : self.getLeagueProfessional('NHL', 'future'),
'Sports (Past Games) Prof': lambda : self.getLeagueProfessional('NBA', 'past'), 'Custom Messages Prof': self.getUserMessagesProfessional, 'Custom Images Prof': self.getUserImagesProfessional, 'Movies Prof': self.getMoviesProfessional, 'Sports (Live Games) Prof': lambda : self.getLeagueProfessional('NBA', 'live')}
self.JSONs = {'Stocks': 'csv/stocks_settings.json', 'Crypto': 'csv/crypto_settings.json', 'Forex': 'csv/forex_settings.json',
self.JSONs = {'Stocks': 'csv/stocks_settings.json', 'Crypto': 'csv/crypto_settings.json', 'Forex': 'csv/forex_settings.json', 'Jokes': 'csv/jokes_settings.json',
'Daily Forecast':'csv/daily_weather.json', 'Current Weather': 'csv/current_weather.json', 'Commodities':'csv/commodities_settings.json', 'Indices': 'csv/indices_settings.json',
'Sports (Team Stats)': 'csv/league_tables.json', 'Sports (Past Games)': 'csv/past_games.json', 'IPO Calendar': 'csv/ipo_settings.json', 'Economic Calendar': 'csv/economic_settings.json',
'Sports (Upcoming Games)': 'csv/upcoming_games.json', 'Sports (Live Games)': 'csv/live_games.json', 'Movies': 'csv/movie_settings.json',
'News':'csv/news_settings.json', 'Custom Images': 'csv/image_settings.json', 'Custom GIFs': 'csv/GIF_settings.json', 'Custom Messages': 'csv/message_settings.json',
'Stocks Prof': 'csv/stocks_settings.json', 'Crypto Prof': 'csv/crypto_settings.json', 'Forex Prof': 'csv/forex_settings.json',
'Stocks Prof': 'csv/stocks_settings.json', 'Crypto Prof': 'csv/crypto_settings.json', 'Forex Prof': 'csv/forex_settings.json', 'Jokes Prof': 'csv/jokes_settings.json',
'Current Weather Prof': 'csv/current_weather.json', 'News Prof':'csv/news_settings.json', 'Commodities Prof':'csv/commodities_settings.json', 'Indices Prof': 'csv/indices_settings.json',
'Daily Forecast Prof':'csv/daily_weather.json', 'Sports (Team Stats) Prof': 'csv/league_tables.json', 'Sports (Upcoming Games) Prof': 'csv/upcoming_games.json', 'Sports (Past Games) Prof': 'csv/past_games.json', 'Custom Messages Prof': 'csv/message_settings.json', 'Custom Images Prof': 'csv/image_settings.json', 'Movies Prof': 'csv/movie_settings.json', 'Sports (Live Games) Prof': 'csv/live_games.json', 'IPO Calendar Prof': 'csv/ipo_settings.json', 'Economic Calendar Prof': 'csv/economic_settings.json'}
@ -947,8 +947,28 @@ class StockTicker():
img = img.crop((0,0,max(w1, w2) + 20,32))
return img
def textToImageProf(self, TICKER, CURRENT, CHANGE, ARROW, font):
if 'E-MINI' in TICKER:
w1, text_height = self.get_text_dimensions(TICKER, font)
w2, text_height = self.get_text_dimensions(CURRENT, font)
text_width_current = max(w1,w2)
img = Image.new('RGB', (text_width_current +100 , 32))
d = ImageDraw.Draw(img)
d.text((4, 0), TICKER, fill=(255, 255, 255), font=font)
d.text((4, 8), CURRENT, fill=self.greenORred, font=font)
img.paste(ARROW, ((w2 + 7),10))
d.text(((w2+18), 8), CHANGE, fill=self.greenORred, font=font)
text_width_change, text_height = self.get_text_dimensions(CHANGE, font)
newWidth = max(w2 + text_width_change, text_width_current) +15
img = img.crop((0,0,newWidth,32))
else:
text_width_current, text_height = self.get_text_dimensions(CURRENT, font)
img = Image.new('RGB', (text_width_current +100 , 32))
@ -961,12 +981,12 @@ class StockTicker():
d.text(((text_width_current+18), 8), CHANGE, fill=self.greenORred, font=font)
text_width_change, text_height = self.get_text_dimensions(CHANGE, font)
newWidth = text_width_current + text_width_change +30
img = img.crop((0,0,newWidth,32))
return img
#Stitch the logo & prices picture into one image
def stitchImage(self, image_list):
widths, heights = zip(*(i.size for i in image_list))
@ -1061,6 +1081,9 @@ class StockTicker():
try:
cost = portfolio_settings[cb]['cost']
day = portfolio_settings[cb]['day']
day_start = datetime.strptime(str(day), "%Y-%m-%d")
day_today = datetime.strptime(datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
day = str((day_today - day_start).days)
shares = portfolio_settings[cb]['shares']
original_value = float(cost) * float(shares)
@ -1230,6 +1253,9 @@ class StockTicker():
try:
cost = portfolio_settings[cb]['cost']
day = portfolio_settings[cb]['day']
day_start = datetime.strptime(str(day), "%Y-%m-%d")
day_today = datetime.strptime(datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
day = str((day_today - day_start).days)
shares = portfolio_settings[cb]['shares']
original_value = float(cost) * float(shares)
@ -2020,6 +2046,9 @@ class StockTicker():
try:
cost = portfolio_settings[symbol]['cost']
day = portfolio_settings[symbol]['day']
day_start = datetime.strptime(str(day), "%Y-%m-%d")
day_today = datetime.strptime(datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
day = str((day_today - day_start).days)
shares = portfolio_settings[symbol]['shares']
original_value = float(cost) * float(shares)
@ -2286,6 +2315,9 @@ class StockTicker():
try:
cost = portfolio_settings[symbol]['cost']
day = portfolio_settings[symbol]['day']
day_start = datetime.strptime(str(day), "%Y-%m-%d")
day_today = datetime.strptime(datetime.now(pytz.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
day = str((day_today - day_start).days)
shares = portfolio_settings[symbol]['shares']
original_value = float(cost) * float(shares)
@ -5045,13 +5077,6 @@ class StockTicker():
f.close()
locations = list(daily_weathers['locations'].keys())
weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
months =['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
month = months[int(datetime.now().strftime('%m'))-1]
date = str(int(datetime.now().strftime('%d')))
weekday = weekdays[datetime.today().weekday()]
for i, location in enumerate(locations):
try:
@ -5082,6 +5107,11 @@ class StockTicker():
img.paste(location_img, (5,3))
x_offset = location_img.size[0] + 8
weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
months =['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
month = months[int(datetime.now().strftime('%m'))-1]
date = str(int(datetime.now().strftime('%d')))
weekday = weekdays[datetime.today().weekday()]
date_img = self.textImage((month + ' ' + date + ',' + weekday).upper(), font)
@ -6074,6 +6104,210 @@ class StockTicker():
return self.stitchImage(image_list)
def getJokesImage(self):
f = open('csv/jokes_settings.json', 'r')
jokes_settings = json.load(f)
f.close()
if jokes_settings['title']:
title_img = self.openImage('feature_titles/jokes.png')
image_list = [title_img]
else:
image_list = []
font = ImageFont.load("./fonts/BonusCoffee-16.pil")
small_font = ImageFont.load("./fonts/5x8.pil")
colours = { 'White':(255,255,255),
'Red':(255,0,0),
'Green':(0,255,0),
'Dark Green':(0,100,0),
'Blue':(0,0,255),
'Purple':(145,0,255),
'Pink':(255,0,255),
'Yellow':(255,255,0),
'Orange':(255,130,0),
'Gold':(255,190,0),
'Cyan':(0,255,255)}
if len(jokes_settings['jokes']) > 0:
try:
for joke in jokes_settings['jokes']:
random_color = random.choice(list(colours.keys()))
r,g,b = colours[random_color]
random_number = str(random.randint(1, 8)) + '.png'
emoji = self.openImage('logos/emojis/emoji' + random_number)
category_icon = self.openImage('logos/emojis/category.png')
category = self.textImage(joke['category'], small_font, r=255, g=255,b=255)
if joke['safe']:
safe = self.textImage('Safe', small_font, r=255, g=255, b=0)
else:
safe = self.textImage('Unsafe', small_font, r=255, g=0, b=0)
if joke['type'] == 'twopart':
decoded = joke['setup'].encode("ascii","ignore")
joke['setup'] = decoded.decode()
joke1 = self.textImage(joke['setup'].replace('\n', ' '), font, int(r),int(g),int(b))
random_color = random.choice(list(colours.keys()))
r,g,b = colours[random_color]
decoded = joke['delivery'].encode("ascii","ignore")
joke['delivery'] = decoded.decode()
joke2 = self.textImage(joke['delivery'].replace('\n', ' '), font, int(r), int(g), int(b))
else:
decoded = joke['joke'].encode("ascii","ignore")
joke['joke'] = decoded.decode()
joke1 = self.textImage(joke['joke'].replace('\n', ' '), font, int(r), int(g), int(b))
joke2 = None
try:
true_flags = [key for key, value in joke['flags'].items() if value]
flags = ", ".join(true_flags)
flags_final = self.textImage(flags, small_font, r=255, g=145, b=0)
except:
flags_final = None
pass
if flags_final != None:
flags_icon = self.openImage('logos/emojis/flags.png')
else:
flags_icon = None
x_offset = 10
if joke2 != None:
try:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5 + flags_icon.size[0] + 2 + flags_final.size[0] + 5) + joke2.size[0], 32))
except:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5) + joke2.size[0], 32))
else:
try:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5 + flags_icon.size[0] + 2 + flags_final.size[0] + 5), 32))
except:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5), 32))
img.paste(emoji, (x_offset, 3))
x_offset += emoji.size[0] + 5
x_offset2 = x_offset
img.paste(joke1, (x_offset, 1))
x_offset += joke1.size[0]
img.paste(category_icon, (x_offset2, 20))
x_offset2 += category_icon.size[0] + 2
img.paste(category, (x_offset2, 20))
x_offset2 += category.size[0] + 5
img.paste(safe, (x_offset2, 20))
x_offset2 += safe.size[0] + 5
try:
img.paste(flags_icon, (x_offset2, 20))
x_offset2 += flags_icon.size[0] + 2
img.paste(flags_final, (x_offset2, 20))
x_offset2 += flags_final.size[0] + 5
except:
pass
try:
img.paste(joke2, (max(x_offset, x_offset2), 16))
except:
pass
image_list.append(img)
except:
pass
return self.stitchImage(image_list)
def getJokesProfessional(self):
f = open('csv/jokes_settings.json', 'r')
jokes_settings = json.load(f)
f.close()
if jokes_settings['title']:
title_img = self.openImage('feature_titles/small_feature_titles/jokes.png')
image_list = [title_img]
else:
image_list = []
font = ImageFont.load("./fonts/6x10.pil")
small_font = ImageFont.load("./fonts/4x6.pil")
colours = { 'White':(255,255,255),
'Red':(255,0,0),
'Green':(0,255,0),
'Dark Green':(0,100,0),
'Blue':(0,0,255),
'Purple':(145,0,255),
'Pink':(255,0,255),
'Yellow':(255,255,0),
'Orange':(255,130,0),
'Gold':(255,190,0),
'Cyan':(0,255,255)}
if len(jokes_settings['jokes']) > 0:
try:
for joke in jokes_settings['jokes']:
random_color = random.choice(list(colours.keys()))
r,g,b = colours[random_color]
random_number = str(random.randint(1, 8)) + '.png'
emoji = self.openImage('logos/emojis/small_emojis/emoji' + random_number)
category_icon = self.openImage('logos/emojis/small_emojis/category.png')
category = self.textImage(joke['category'], small_font, r=255, g=255,b=255)
if joke['safe']:
safe = self.textImage('Safe', small_font, r=255, g=255, b=0)
else:
safe = self.textImage('Unsafe', small_font, r=255, g=0, b=0)
if joke['type'] == 'twopart':
joke1 = self.textImage(joke['setup'].replace('\n', ' '), font, int(r),int(g),int(b))
random_color = random.choice(list(colours.keys()))
r,g,b = colours[random_color]
joke2 = self.textImage(joke['delivery'].replace('\n', ' '), font, int(r), int(g), int(b))
else:
joke1 = self.textImage(joke['joke'].replace('\n', ' '), font, int(r), int(g), int(b))
joke2 = None
try:
true_flags = [key for key, value in joke['flags'].items() if value]
flags = ", ".join(true_flags)
flags_final = self.textImage(flags, small_font, r=255, g=145, b=0)
except:
flags_final = None
pass
if flags_final != None:
flags_icon = self.openImage('logos/emojis/small_emojis/flags.png')
else:
flags_icon = None
x_offset = 10
if joke2 != None:
try:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5 + flags_icon.size[0] + 2 + flags_final.size[0] + 5) + joke2.size[0], 16))
except:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5) + joke2.size[0], 16))
else:
try:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5 + flags_icon.size[0] + 2 + flags_final.size[0] + 5), 16))
except:
img = Image.new('RGB', (20 + emoji.size[0] + 5 + max(joke1.size[0], category_icon.size[0] + 2 + category.size[0] + 5 + safe.size[0] + 5), 16))
img.paste(emoji, (x_offset, 0))
x_offset += emoji.size[0] + 5
x_offset2 = x_offset
img.paste(joke1, (x_offset, 0))
x_offset += joke1.size[0]
img.paste(category_icon, (x_offset2, 10))
x_offset2 += category_icon.size[0] + 2
img.paste(category, (x_offset2, 10))
x_offset2 += category.size[0] + 5
img.paste(safe, (x_offset2, 10))
x_offset2 += safe.size[0] + 5
try:
img.paste(flags_icon, (x_offset2, 10))
x_offset2 += flags_icon.size[0] + 2
img.paste(flags_final, (x_offset2, 10))
x_offset2 += flags_final.size[0] + 5
except:
pass
try:
img.paste(joke2, (max(x_offset, x_offset2), 6))
except:
pass
image_list.append(img)
except:
pass
return self.stitchImage(image_list)
def ip_viewer(self):
font = ImageFont.load("./fonts/6x10.pil")
@ -6151,6 +6385,8 @@ class StockTicker():
x_offset += ipo.size[0]
news.paste(economic, (x_offset, 16))
x_offset += economic.size[0]
news.paste(jokes, (x_offset, 16))
x_offset += jokes.size[0]
self.double_buffer = self.matrix.CreateFrameCanvas()
while True:
kill = stock_ticker.scrollImage(news, offset_x = 128)
@ -6237,6 +6473,9 @@ class StockTicker():
elif msg == 'EC': #economic calendar
self.scrollFunctionsAnimated(['economic', 'economic'],animation = 'traditional')
elif msg == 'JO': # jokes
self.scrollFunctionsAnimated(['jokes', 'jokes'],animation = 'traditional')
elif msg == 'A': #everything
#userSettings = ['display_gif', 'text', 'display_image', 'stocks', 'crypto', 'forex', 'today_weather', 'daily_weather', 'league_table', 'league_games', 'news'] # these wil be read from csv, just for demo

View File

@ -39,7 +39,7 @@
<!-- CSS Stylesheet linking -->
<!-- <link href="{{ url_for('static', filename='style.css') }}" type="text/css" rel="stylesheet" /> ALWAYS CHANGE VERSIONING WHENEVER CHANGES ARE MADE TO AVOID BAD CACHING -->
<link rel="stylesheet" type="text/css" href="../static/style.css?ver=1.3.6"/>
<link rel="stylesheet" type="text/css" href="../static/style.css?ver=1.3.7"/>
</head>
@ -99,7 +99,7 @@
</div>
</div>
<p class="text-white" id="version-text">Version 1.3.6</p>
<p class="text-white" id="version-text">Version 1.3.7</p>
<p class="text-white" id="version-text"><a href="https://docs.google.com/document/d/1TzvukZv_0Pd3TUM6Xe2wEkymn9uIT2qXUBFnMCQwp5g/edit?usp=sharing" target="_blank" id="footerlinks">Changelog</a></p>
</nav>
@ -177,6 +177,22 @@
<div id="wifi-message" style="display:none"><p id="wifi-p">Joining Wi-Fi, please restart the ticker.</p></div>
<!-- SAVE PROMPT MESSAGE -->
<div id="save-prompt-message" style="display:none">
<button id="save-prompt-close-btn" onclick="closeSavePrompt()">Close</button>
<p id="save-prompt-p">Features to Display - Changes detected.</p>
<button class="btn set-btn" id="save-prompt-btn" onclick="savePrompt()">Save</button>
</div>
<div id="saved-msg-feedback" style="display:none">Features to Display -<br> Saved!<br>Restarting display.</div>
<!-- SAVE FEATURE SETTINGS PROMPT MESSAGE -->
<div id="save-feature-prompt-message" style="display:none">
<button id="save-feature-prompt-close-btn" onclick="closeFeatureSavePrompt()">Close</button>
<p id="save-feature-prompt-p">Stocks Settings - Changes detected.</p>
<button class="btn set-btn" id="save-feature-prompt-btn" onclick="featureSavePrompt()">Save</button>
</div>
<div id="saved-feature-msg-feedback" style="display:none">Stocks Settings -<br> Saved!</div>
<!-- Ticker Form -->
@ -1227,6 +1243,7 @@
<li>Movies</li>
<li>IPO Calendar</li>
<li>Economic Calendar</li>
<li>Jokes</li>
{%endif%}
@ -1338,6 +1355,7 @@
<option value="16">Movies</option>
<option value="17">IPO Calendar</option>
<option value="18">Economic Calendar</option>
<option value="19">Jokes</option>
</select>
</div>
@ -1710,6 +1728,9 @@
aria-describedby="TextHelpInline"
placeholder="e.g. 200" />
</div>
<div class="col-auto">
<button id="update-stock-port-btn" class="btn set-btn" onclick="updateStockPorftolio()">Update Position</button>
</div>
</div>
<div class="row g-3 align-items-center mt-3 left-div">
@ -1744,6 +1765,12 @@
aria-describedby="TextHelpInline"
placeholder="e.g. YYYY-MM-DD" />
</div>
<div class="col-auto">
<button id="remove-stock-port-btn" class="btn set-btn" onclick="removeStockPorftolio()">Remove Position</button>
</div>
<div id="updated-stock-p" style="display:none"><p id="stockupdated-p" style="color: red;">Stock Position Updated!</p></div>
<div id="removed-stock-p" style="display:none"><p id="stockremoved-p" style="color: red;">Stock Position Removed!</p></div>
</div>
</div>
@ -1759,7 +1786,7 @@
id="stocks-features"
class="display-features-list text-white symbol-list">
{% for f in stocks_settings.symbols %}
<li>{{f}}</li>
<li onclick="getStockSymbol(this.innerText)">{{f}}</li>
{% endfor%}
</ul>
@ -2216,6 +2243,9 @@
aria-describedby="TextHelpInline"
placeholder="e.g. 200" />
</div>
<div class="col-auto">
<button id="update-crypto-port-btn" class="btn set-btn" onclick="updateCryptoPorftolio()">Update Position</button>
</div>
</div>
<div class="row g-3 align-items-center mt-3 left-div">
@ -2250,6 +2280,12 @@
aria-describedby="TextHelpInline"
placeholder="e.g. YYYY-MM-DD" />
</div>
<div class="col-auto">
<button id="remove-crypto-port-btn" class="btn set-btn" onclick="removeCryptoPorftolio()">Remove Position</button>
</div>
<div id="updated-crypto-p" style="display:none"><p id="cryptoupdated-p" style="color: red;">Crypto Position Updated!</p></div>
<div id="removed-crypto-p" style="display:none"><p id="cryptoremoved-p" style="color: red;">Crypto Position Removed!</p></div>
</div>
</div>
@ -2273,7 +2309,7 @@
{% for f in crypto_settings.symbols %}
<li>{{f}}</li>
<li onclick="getCryptoSymbol(this.innerText)">{{f}}</li>
{% endfor%}
@ -2919,8 +2955,9 @@
/> -->
<select id="indices-items" class="form-select animation-select">
<option>Dow Jones - USA</option><option>S&P 500 - USA</option><option>Nasdaq 100 - USA</option>
<option>Nasdaq Composite - USA</option><option>Russell 2000 - USA</option><option>VIX - USA</option>
<option>Dow Jones - USA</option><option>E-Mini Dow Jones - USA</option><option>S&P 500 - USA</option><option>E-Mini S&P 500 - USA</option>
<option>Nasdaq 100 - USA</option><option>E-Mini Nasdaq 100 - USA</option>
<option>Nasdaq Composite - USA</option><option>Russell 2000 - USA</option><option>E-Mini Russell 2000 - USA</option><option>VIX - USA</option>
<option>U.S. Dollar (DXY) - USA</option>
<option>S&P/TSX - Canada</option><option>IPC - Mexico</option><option>Bovespa - Brazil</option>
<option>Dax - Germany</option><option>FTSE 100 - UK</option><option>IBEX 35 - Spain</option>
@ -6944,6 +6981,209 @@
</div>
<!-- Jokes -->
<div class="page" id="Page19" style="display: none">
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12">
<div class="row g-3 align-items-center mt-3">
<div class="col-auto">
<label for="inputScrollSpeedZ222" class="col-form-label">Scroll Speed:</label>
</div>
<div class="col-auto">
<select
id="inputScrollSpeed19"
class="form-select speed-select">
<option {%if jokes_settings.speed == 'medium' %} selected {% endif %}>Medium</option>
<option {%if jokes_settings.speed == 'slow' %} selected {% endif %}>Slow</option>
<option {%if jokes_settings.speed == 'fast' %} selected {% endif %}>Fast</option>
</select>
</div>
</div>
<div class="row g-3 align-items-center mt-3 left-div">
<div class="col-auto">
<label for="inputScrollSpeedRowZ222" class="col-form-label">Scroll Speed (Row 2):</label>
</div>
<div class="col-auto">
<select
id="inputScrollSpeedRow19"
class="form-select speed-select">
<option {%if jokes_settings.speed2 == 'medium' %} selected {% endif %}>Medium</option>
<option {%if jokes_settings.speed2 == 'slow' %} selected {% endif %}>Slow</option>
<option {%if jokes_settings.speed2 == 'fast' %} selected {% endif %}>Fast</option>
</select>
</div>
</div>
<div class="row g-3 align-items-center mt-3">
<div class="col-auto">
<label for="inputTransitionZ222" class="col-form-label">Intro Transition:
</label>
</div>
<div class="col-auto">
<select id="inputTransition19" class="form-select animation-select">
<option {%if jokes_settings.animation == 'down' %} selected {% endif %}>Down</option>
<option {%if jokes_settings.animation == 'up' %} selected {% endif %}>Up</option>
<option {%if jokes_settings.animation == 'continuous' %} selected {% endif %}>Continuous</option>
</select>
</div>
</div>
<div class="row g-3 align-items-center left-div" style="padding-top: 25px;">
<div class="col-auto">
<label for="inputTransitionZ222" class="col-form-label">
Display Feature Title
</label>
</div>
<div class="col-auto">
<input
class="form-check-input title-select"
type="checkbox"
value=""
id="jokes_settings_title"
{% if jokes_settings.title%}
checked
{%endif%}/>
</div>
</div>
<div class="row g-3 align-items-center mt-3">
<div class="col-auto">
<label for="jokes-categories" class="col-form-label">Categories: </label>
</div>
<div class="col-auto">
<select id="jokes-categories" class="form-select jokes-categories-select">
<option>Any</option><option>Programming</option><option>Misc</option><option>Dark</option><option>Pun</option>
<option>Spooky</option><option>Christmas</option>
</select>
</div>
<div class="col-auto">
<button id="jokes-categories-btn" class="btn set-btn">Add</button>
</div>
</div>
<div class="row g-3 align-items-center mt-3">
<div class="col-auto">
<label for="inputText" class="col-form-label">Blacklist: </label>
</div>
<div class="col-auto blacklist-checkboxes">
<input type="checkbox" id="nsfw-jokes" value="nsfw"
{% if "nsfw" in jokes_settings.blacklist %} checked {% endif %}>
<label for="nsfw-jokes">NSFW</label>
<input type="checkbox" id="religious-jokes" value="religious"
{% if "religious" in jokes_settings.blacklist %} checked {% endif %}>
<label for="religious-jokes">Religious</label>
<input type="checkbox" id="political-jokes" value="political"
{% if "political" in jokes_settings.blacklist %} checked {% endif %}>
<label for="political-jokes">Political</label><br>
<input type="checkbox" id="racist-jokes" value="racist"
{% if "racist" in jokes_settings.blacklist %} checked {% endif %}>
<label for="racist-jokes">Racist</label>
<input type="checkbox" id="sexist-jokes" value="sexist"
{% if "sexist" in jokes_settings.blacklist %} checked {% endif %}>
<label for="sexist-jokes">Sexist</label>
<input type="checkbox" id="explicit-jokes" value="explicit"
{% if "explicit" in jokes_settings.blacklist %} checked {% endif %}>
<label for="explicit-jokes">Explicit</label>
</div>
</div>
<div class="row g-3 align-items-center mt-3">
<div class="col-auto">
<label for="jokes-amount" class="col-form-label">Amount: </label>
</div>
<div class="col-auto">
<select id="jokes-amount" class="form-select jokes-amount-select">
<option {%if jokes_settings.amount == '1' %} selected {% endif %}>1</option>
<option {%if jokes_settings.amount == '2' %} selected {% endif %}>2</option>
<option {%if jokes_settings.amount == '3' %} selected {% endif %}>3</option>
<option {%if jokes_settings.amount == '4' %} selected {% endif %}>4</option>
<option {%if jokes_settings.amount == '5' %} selected {% endif %}>5</option>
<option {%if jokes_settings.amount == '6' %} selected {% endif %}>6</option>
<option {%if jokes_settings.amount == '7' %} selected {% endif %}>7</option>
<option {%if jokes_settings.amount == '8' %} selected {% endif %}>8</option>
<option {%if jokes_settings.amount == '9' %} selected {% endif %}>9</option>
<option {%if jokes_settings.amount == '10' %} selected {% endif %}>10</option>
</select>
</div>
</div>
<div class="row g-3 align-items-center left-div" style="padding-top: 25px;">
<div class="col-auto">
<label for="inputTransitionZ222" class="col-form-label">
Safe Jokes Only
</label>
</div>
<div class="col-auto">
<input
class="form-check-input title-select"
type="checkbox"
value=""
id="jokes_settings_safe"
{% if jokes_settings.safe%}
checked
{%endif%}/>
</div>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-12">
<h6 class="mt-3">List:</h6>
<div class="features-div-two">
<ul
id="jokes-list"
class="display-features-list text-white symbol-list">
{% for f in jokes_settings.categories %}
<li>{{f}}</li>
{% endfor%}
</ul>
</div>
</div>
<div class="col-lg-2 col-md-2 col-sm-12">
<div class="icons-list">
<i
id="jokes-increase-btn"
class="upbutton fa fa-chevron-up"
aria-hidden="true"
></i>
<br />
<br />
<i
id="jokes-decrease-btn"
class="downbutton fa fa-chevron-down"
aria-hidden="true"
></i>
<a style="position: relative; bottom: 30px; left: 10px">Sort Order</a>
<br />
<br />
<i
id="jokes-remove-btn"
class="fa fa-minus"
aria-hidden="true"
></i>
<span style="position: relative; bottom: 0; left: 10px">Remove</span>
</div>
</div>
</div>
<div class="save-btn-div">
<a href="#" class="btn save-btn">Save</a>
</div>
</div>
<!-- Custom Images -->
<div class="page" id="Page11" style="display: none">
@ -8118,7 +8358,7 @@
<select
id="inputScrollSpeed19"
id="inputScrollSpeed19BG"
class="form-select back-colour"
@ -8156,7 +8396,13 @@
</div>
<div class="row g-3 align-items-center mt-3" style="margin-left: 15%;">
<div class="col-auto">
<button id="updatemsgbtn" class="btn set-btn" onclick="updateSelectedMsg()">Update Msg</button>
</div>
</div>
<div id="updated-message-p" style="display:none"><p id="msgupdated-p" style="color: red;">Message Updated!</p></div>
<div class="row g-3 align-items-center mt-3">
@ -8216,7 +8462,7 @@
{%for f in message_settings.messages %}
<li>{{f.name}}</li>
<li onclick="getCustomMsg(this.innerText)">{{f.name}}</li>
{% endfor%}
@ -8308,153 +8554,104 @@
<section class="stocks-features text-white row-3">
<div
<div class="mx-auto my-5 d-flex align-items-center position-relative" style="width: fit-content; margin-left:0;">
<div class="col-auto">
<h6 class="mt-3">Networks List:</h6>
<div class="features-div-two" style="height: 280px; width: 200px;">
<ul
id="networks-list"
class="display-features-list text-white symbol-list">
{% for key,value in networks_list.items() %}
<li onclick="sendNetworkToSSID(this)">{{key}}</li>
{% endfor%}
</ul>
</div>
</div>
class="mx-auto my-5 d-flex align-items-center position-relative"
style="width: fit-content"
>
<div class="mr-5">
<div class="mr-5" style="width: 200px; margin-left: 20px; margin-bottom:20px;">
<div class="mx-auto row g-3 align-items-center mb-2">
<div class="col-auto">
<div class="col-auto" style="margin-top: 0;">
<label
for="wifi-ssid-inputZ"
class="col-form-label text-right w-115-px"
class="col-form-label text-left w-115-px"
>Wi-Fi SSID:
</label>
</div>
<div class="col-auto">
<div class="col-auto" style="margin-top: 0;">
<input
type="text"
id="wifi-ssid-input"
class="form-control"
placeholder="Wi-Fi SSID"
aria-describedby="TextHelpInline"
value="{{ wifi_SSID }}"
/>
value="{{ wifi_SSID }}"/>
</div>
</div>
<div class="mx-auto row g-3 align-items-center mt-2">
<div class="col-auto">
<div class="col-auto" style="margin-top: 0;">
<label
for="wi-fi-pass-input"
class="col-form-label text-right w-115-px"
class="col-form-label text-left w-115-px"
>Wi-Fi password:
</label>
</div>
<div class="col-auto">
<div class="col-auto" style="margin-top: 0;">
<input
type="password"
id="wifi-pass-input"
placeholder="Wi-Fi password"
class="form-control"
aria-describedby="TextHelpInline"
value="{{ wifi_PSK }}"
/>
value=""/>
</div>
</div>
</div>
<input type="checkbox" class="form-check-input pass-toggle" onclick="togglePass()"> Show Password
<label style="width:180px; margin-top:5%"><input type="checkbox" class="form-check-input pass-toggle" onclick="togglePass()">
Show Password</label>
<div class="mx-auto row g-3 align-items-center mt-2">
<div class="col-auto">
<div class="col-auto" style="margin-top: 0;">
<label
for="country-code-inputZ"
class="col-form-label text-right w-115-px"
>Two Letter Country Code:
class="col-form-label text-left w-120-px"
>2 Letter Country Code:
</label>
</div>
<div class="col-auto">
<div class="col-auto" style="margin-top: 0;">
<input
type="text"
id="country-code-input"
placeholder="2 Letter Country Code"
class="form-control"
aria-describedby="TextHelpInline"
value={{ general_settings.country_code }}
/>
</div>
</div>
<div>
</div>
</div>
<button class="btn set-btn" id="join-network-btn" onClick=showDivTwo()>
Join Network
<div class="col-auto" >
<button class="btn set-btn" id="scan-network-btn" onClick=scanNetworks() style="margin-bottom: 15%;">
Scan Networks
</button>
<div id="network-status" style="padding-left:2%;padding-right:2%"></div>
<br>
<button class="btn set-btn" id="join-network-btn" onClick=showDivTwo()>
Join Network
</button>
<div class="col-auto" style="display: flex; flex-direction: row; justify-content: center; align-items: center; padding-top: 10%;">
<div id="network-status" style="padding-left:2%;padding-right:2%"> </div>
<div class="status rounded-circle" id="circle-1" style="display:none"></div>
<div class="status rounded-circle" id="circle-2" style="display:none"></div>
<div class="status rounded-circle" id="circle-3" style="display:none"></div>
</div>
</div>
</div>
@ -8569,7 +8766,7 @@
<p>&copy; 2020-2023 Fintic Limited., All Rights Reserved. <a href="mailto:info@fintic.io" id="footerlinks">Contact Us.</a></p>
<p>Data Provided by TradingView, IEX Cloud, Open-Meteo, CoinGecko, Exchangerate-API, TheSportsDB, Google News, Yahoo Finance, ESPN, The Movie DB, Finnhub</p>
<p>Data Provided by TradingView, IEX Cloud, Open-Meteo, CoinGecko, Exchangerate-API, TheSportsDB, Google News, <br>Yahoo Finance, ESPN, The Movie DB, Finnhub, Sv443 (JokeAPI)</p>
<p>Useful resources: <a href="https://www.youtube.com/playlist?list=PLf8pW0bNjnebNZh3y0AsY18sxJj6IhAsv" id="footerlinks" target="_blank">YouTube Tutorials</a> , <a href="https://docs.google.com/spreadsheets/d/1IZkEl49j97xvG8jcEdWc5XdOLOUb_-ZLVHle2vezWCc/edit?usp=sharing" id="footerlinks" target="_blank">Formatting Guide & Info</a> , <a href="https://fintic.io" id="footerlinks" target="_blank">Official Website</a></p>
@ -8583,7 +8780,7 @@
<script src="{{ url_for('static', filename='js/jquery-2.1.1.js') }}"></script>
<!-- <script src="{{ url_for('static', filename='app.js') }}"></script>. ALWAYS CHANGE VERSIONING WHENEVER CHANGES ARE MADE TO AVOID BAD CACHING -->
<script type='text/javascript' src='../static/app.js?ver=1.3.6'></script>
<script type='text/javascript' src='../static/app.js?ver=1.3.7'></script>
<script>