Skip to content

Push for Tag 0.4.0 #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Sep 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"python.pythonPath": "/bin/python3",
"workbench.colorTheme": "Atom One Dark"
"workbench.colorTheme": "One Dark Pro"
}
37 changes: 17 additions & 20 deletions lib/config/ohmyoled.conf
Original file line number Diff line number Diff line change
@@ -1,63 +1,60 @@
[basic]
testing = False
# Log Level for Python
# Critcal = 50
# Error = 40
# Warning = 30
# Info = 20
# Debug = 10
loglevel = 10
loglevel = 20
# Tokens will have to be Supported used with Approriate Modules
#### Not Supported Yet #####
# sport_token = 'SPORT_TOKEN'
# sport_token =
##############################
# Stock Token based in FINN TOKEN https://finnhub.io/docs/api/introduction
# stock_api_token = YOUR_FINN_TOKEN
#stock_api_token =

# Open Weather Token in https://openweathermap.org/
open_weather_token = 80ce462129470ef2f5d55e6f65d32eef
# open_weather_token =

[matrix]
chain_length = 1
parallel = 1
# Brightness from 0-100
brightness = 60
brightness = 20
oled_slowdown = 3

[weather]
[time]
Run=True
color = (255,255,255)

[weather]
Run=False
# Build the city as Dallas, US, For more accurate data, use zipcode
current_location=True
#city =
zipcode =
# zipcode =
# Format
# The Units, The options are standard, metric, imperial
format = imperial

[stock]
Run=False

# symbol=

# Runs Quote data for stocks
# quote=True

# Historical and days need
# historical=True
# days_ago=30
symbol=fb

##### Sports Not Supported it #####
# [sport]
# Run=False
[sport]
Run=False
# football
# baseball
# hockey
# basketball
# formula 1
# sport=baseball
sport=baseball
# For Team IDs Baseball https://dashboard.api-football.com/baseball/ids/teams
# For Team IDs Basketball https://dashboard.api-football.com/basketball/ids/teams/USA
# Only Support USA
# team_id = 6
team_id = 6
# optional Will pull all data for all unless specified

# Baseball
Expand Down
9 changes: 6 additions & 3 deletions lib/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
logger = logging.getLogger(__name__)
logger.addHandler(sh)
logger.addHandler(filehandler)
logger.setLevel(logging.DEBUG)

class RunnerABS():
"""
Expand All @@ -41,10 +40,10 @@ class Caller(object):
logger = logging.getLogger(__name__)
logger.addHandler(sh)
logger.addHandler(filehandler)
logger.setLevel(logging.DEBUG)
def __init__(self) -> None:
super().__init__()
self.caller_logger = logger
self.caller_logger.debug(f"Caller logger is set to {self.logger.getEffectiveLevel()}")

class Runner(RunnerABS):
"""
Expand All @@ -53,11 +52,15 @@ class Runner(RunnerABS):
logger = logging.getLogger(__name__)
logger.addHandler(sh)
logger.addHandler(filehandler)
logger.setLevel(logging.DEBUG)
def __init__(self, config):
super().__init__()
self.config = config
self.runner_logger = logger
if self.config['basic'].getboolean('testing'):
self.logger.setLevel(self.config['basic'].getint('loglevel'))
else:
self.logger.setLevel(10)
self.logger.debug(f"Runner logger is set to {self.logger.getEffectiveLevel()}")
def run_non_async_request(self, url):
response = requests.get(url)
return response
Expand Down
9 changes: 8 additions & 1 deletion lib/sports/sports.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import json
import sys

# TODO @thefinaljoke More abstract to use different apis
class SportApi(Runner):
def __init__(self, config):
super().__init__(config)
Expand Down Expand Up @@ -99,9 +100,15 @@ def __repr__(self):
def build_standings(self):
#counter = 0
position = []
regular_season_check = (
"MLB - Regular Season",
"NBA - Regular Season",
"NHL - Regular Season",
"NFL - Regular Season"
)
# Can Be Empty Must try and except for that
for pos in self.main_sport['standings'].get('response')[0]:
if pos.get('stage') != "MLB - Regular Season" or pos.get('stage') != "NBA - Regular Season":
if not pos.get('stage') in regular_season_check:
continue
position.append({'name': pos.get('team').get('name'),
'position': pos.get('position'),
Expand Down
1 change: 1 addition & 0 deletions lib/stock/stockquote.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ async def run(self) -> Dict:
"""
returns current stock Quotes and Price
"""
self.logger.info("Running Stock Data")
symbol = self.config.get('symbol')
api_data = await self.get_data(self.url_builder(symbol=symbol))
api_data['symbol'] = symbol
Expand Down
3 changes: 2 additions & 1 deletion lib/weather/ecIcons_utf8.csv
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ UTF8,92,92,902,Rising,Day and Night Conditions,f057,
UTF8,93,93,903,Falling,Day and Night Conditions,f088,
UTF8,94,94,904,Steady,Day and Night Conditions,f04d,
UTF8,1,5,800,Clear,Day Conditions Only,f00d,
UTF8,3,3,801,Cloudy Periods,Day Conditions Only,f013,
UTF8,3,3,801,Cloudy Periods,Day Conditions Only,f013,
UTF8,31,31,806,Mainly Clear,Night Conditions Only,f02e,
5 changes: 2 additions & 3 deletions lib/weather/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
import sys
import os
import json
from requests import Response
import geocoder
from typing import Dict, Tuple
from datetime import datetime
from enum import Enum
import csv

def get_weather_csv():
Expand Down Expand Up @@ -80,6 +77,7 @@ async def get_long_and_lat(self, location: str=None, zipcode: int=None) -> Tuple
"""
Searches for Longitude and latitude for Given City
"""
self.logger.debug("Getting Lat and Long")
try:
if location:
self.logger.debug("Getting Longitude and Latitude")
Expand All @@ -102,6 +100,7 @@ async def url_builder(self, location=None, zipcode=None, current_location=False)
"""
Builds Url to poll the Api
"""
self.logger.debug("Building url...")
if current_location:
ip_json = self.get_current_location()
lon, lat = ip_json['loc'].split(',')[1], ip_json['loc'].split(',')[0]
Expand Down
17 changes: 15 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import requests
import logging


stream_formatter = logging.Formatter(
"%(levelname)s:%(asctime)s:%(module)s:%(message)s"
)
Expand All @@ -30,12 +31,16 @@
logger = logging.getLogger(__name__)
logger.addHandler(sh)
logger.addHandler(filehandler)
logger.setLevel(logging.DEBUG)

class Main():
def __init__(self, config) -> None:
self.config = config
self.logger = logger
if self.config['basic'].getboolean('testing'):
self.logger.setLevel(self.config['basic'].getint('loglevel'))
else:
self.logger.setLevel(10)
self.logger.debug(f"Logger is set to {self.logger.getEffectiveLevel()}")
def parse_config_file(self):
module = {}
self.logger.info("Parsing config file")
Expand All @@ -50,6 +55,9 @@ def get_modules_to_run(self):
self.logger.info("Getting Modules")
for section, runtime in parsed.items():
if runtime:
if section == 'time':
self.logger.debug("Time midule selected from config")
api_modules.update({'time': " "})
if section == 'weather':
self.logger.debug("Weather Module Selected From Config")
api_modules.update({'weather': WeatherApi(self.config)})
Expand All @@ -74,8 +82,11 @@ def poll_rgbmatrix(self):
return rgboptions

async def init_matrix(self, matrix):
verified_modules = [TimeMatrix(matrix)]
verified_modules = []
modules = self.get_modules_to_run()
if 'time' in modules:
self.logger.debug("Initialized Time")
verified_modules.append(TimeMatrix(matrix, self.config['time']))
if 'weather' in modules:
self.logger.debug("Initialized Weather")
verified_modules.append(WeatherMatrix(matrix, modules['weather'], logger))
Expand Down Expand Up @@ -112,5 +123,7 @@ async def main_run(self):
loop.run_forever()
except KeyboardInterrupt:
logger.critical("Key Interrupt")
except Exception as e:
logger.critical(e)
finally:
loop.stop()
5 changes: 2 additions & 3 deletions matrix/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
logger = logging.getLogger(__name__)
logger.addHandler(sh)
logger.addHandler(filehandler)
logger.setLevel(logging.DEBUG)

logger.setLevel(logging.INFO)
class ABSMatrix():
def __init__(self) -> None:
pass
Expand All @@ -50,7 +49,7 @@ class Matrix(ABSMatrix):
def __init__(self, config) -> None:
self.config = config
self.logger = logger

self.logger.debug(f"Logger is set to {self.logger.getEffectiveLevel()}")
def get_font_graphics(self, font_file):
font = graphics.Font()
font.LoadFont(f"/etc/ohmyoled/fonts/{font_file}")
Expand Down
54 changes: 17 additions & 37 deletions matrix/sport/sportmatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,6 @@
from lib.sports.basketball.basketball import Basketball
from lib.sports.hockey.hockey import Hockey
from matrix.sport.team_mapping import BASEBALL_TEAMS, BASKETBALL_TEAMS
class BaseballMatrix(Matrix):
def __init__(self, matrix, api, logger) -> None:
self.matrix = matrix
self.api = api
self.logger = logger
def render_standings(self):
"""
Split the screen and then Roll the screen
"""
self.draw_rectangle()
def render_sport(self):
self.render_standings()
time.sleep(10)

class BasketballMatrix(Matrix):
def __init__(self, matrix, api, logger) -> None:
self.matrix = matrix
self.api = api
self.logger = logger

def render_sport(self):
return

class HockeyMatrix(Matrix):
def __init__(self, matrix, api, logger) -> None:
self.matrix = matrix
self.api = api
self.logger = logger

def render_sport(self):
return

class SportMatrix(Matrix):
def __init__(self, matrix, api, logger) -> None:
Expand All @@ -70,10 +39,12 @@ def determine_nextgame(self, nextgame_api):
status = ("FT", "ABD")
for game in nextgame_api:
if "IN" in game['status']:
self.logger.debug(f"In Game")
# During the game
return game
if game['status'] == "FT" and datetime.fromtimestamp(game['timestamp']).date() == datetime.today().date():
# Same Day will display for the rest of the day
self.logger.debug("Game is finished but still same day")
return game
if game['status'] not in status:
return game
Expand All @@ -98,16 +69,18 @@ def build_in_game_image(self, nextgame):
middle_draw = ImageDraw.Draw(middle_image)
font = ImageFont.truetype("/usr/share/fonts/fonts/04B_03B_.TTF", 8)
status = nextgame['status']
self.logger.debug(f"status: {status}")
score = (nextgame['teams']['home']['total'], nextgame['teams']['away']['total'])
middle_draw.multiline_text((10,0), f"{status}\n{score[0]}-{score[1]}", font=font)
self.logger.debug(f"Score: {score}")
middle_draw.multiline_text((12,0), f" {status}\n{score[0]}-{score[1]}", font=font)
return middle_image, (15, 0)
def build_finished_game_image(self, nextgame):
middle_image = self.make_new_image((34,16))
middle_draw = ImageDraw.Draw(middle_image)
font = ImageFont.truetype("/usr/share/fonts/fonts/04B_03B_.TTF", 8)
status = nextgame['status']
score = (nextgame['teams']['home']['total'], nextgame['teams']['away']['total'])
middle_draw.multiline_text((10,0), f"{status}\n{score[0]}-{score[1]}", font=font)
middle_draw.multiline_text((12,0), f" {status}\n{score[0]}-{score[1]}", font=font)
return middle_image, (15, 0)

def check_offseason(self, api):
Expand All @@ -122,16 +95,23 @@ def build_next_game_image(self, nextgame):
middle_draw = ImageDraw.Draw(middle_image)
font = ImageFont.truetype("/usr/share/fonts/fonts/04B_03B_.TTF", 8)
time = datetime.fromtimestamp(nextgame['timestamp']).strftime("%I:%M%p %a")
time = "\n ".join(time.split())
formatted_time = time.split()
formatted_time[0] = f" {formatted_time[0]}"
time = "\n ".join(formatted_time)
middle_draw.multiline_text((0,0), f'{time}', font=font)
return middle_image, (15, 0)

def build_home_away_image(self, nextgame):
self.logger.debug(f"Building Home away image")
home_data = self.home_team(nextgame)
self.logger.debug(f"Home Data {home_data}")
home_logo = Image.open(self.get_logo(home_data['logo'], home_data['id']))
self.logger.debug(f"Got Logo {home_logo}")
home_logo.thumbnail((16,16))
away_data = self.away_team(nextgame)
self.logger.debug(f"Away Data: {away_data}")
away_logo = Image.open(self.get_logo(away_data['logo'], away_data['id']))
self.logger.debug(f"Away Logo {away_logo}")
away_logo.thumbnail((16,16))
return (home_logo, (-2,0)), (away_logo, (50, 0))

Expand Down Expand Up @@ -190,7 +170,6 @@ def build_standings_image(self, api, xpos) -> Tuple[int, int]:
american, national = self.baseball_divisions(api.standings)
american.extend(national)
text = " ".join(american)
img_width, img_height = self.get_text_size(text)
standings_draw.text(
(-xpos, 0),
text,
Expand Down Expand Up @@ -225,7 +204,7 @@ def render(self, api):
xpos_for_top += 1
if xpos_for_top == 100:
xpos_for_top = 0
time.sleep(3) if xpos == 1 else time.sleep(.05)
time.sleep(3) if xpos == 1 else time.sleep(.03)
else:
font = ImageFont.truetype("/usr/share/fonts/fonts/04b24.otf", 14)
self.draw_multiline_text((0, 0), "Basketball\nOffseason", font=font)
Expand Down Expand Up @@ -263,7 +242,8 @@ def render(self, api):
if 'hockey' in api.sport:
self.logger.info("Found Hockey, Displaying Hockey Matrix")
if self.check_offseason(api):
sportmatrix = HockeyMatrix(self.matrix, api, self.logger)
pass
#sportmatrix = HockeyMatrix(self.matrix, api, self.logger)
else:
font = ImageFont.truetype("/usr/share/fonts/fonts/04b24.otf", 14)
self.draw_multiline_text((0, 0), "Hockey\nOffseason", font=font)
Expand Down
Loading