Head start from @dicijr

This commit is contained in:
Maximilian Giller 2019-05-18 09:28:29 +02:00
parent 2a94c1fb90
commit 00a05a1a6e
11 changed files with 167 additions and 23 deletions

View file

@ -0,0 +1,22 @@
from DataSourceInterface import DataSourceInterface
from datetime import datetime, timezone, timedelta
class CryptoInterface(DataSourceInterface):
def __init__(self):
self.crypto_prices = []
def reload(self):
if self.is_available() == False:
return
self.crypto_prices= self.__get_prices__()
self.sort_prices()
def __get_prices__(self):
raise NotImplementedError("Functions needs to be implemented")
def get_latest_prices(self):
self.crypto_prices = self.crypto_prices
return self.crypto_prices
def sort_prices(self):
self.crypto_prices =self.crypto_prices

4
Calendar/CryptoItem.py Normal file
View file

@ -0,0 +1,4 @@
class CryptoItem(object):
def __init__ (self):
self.name = None
self.value = None

View file

@ -0,0 +1,27 @@
from DesignEntity import DesignEntity
from TableDesign import TableDesign
from Assets import defaultfontsize
from CryptoPrices import CryptoPrices
from settings import coins as cryptos
class CryptoListDesign (DesignEntity):
def __init__ (self, size, coin, text_size = defaultfontsize):
super(CryptoListDesign, self).__init__(size)
self.coin = coin
self.__post_matrix__ = []
self.text_size = text_size
def __finish_image__ (self):
self.__fill_post_matrix__()
table_design = TableDesign(self.size, line_spacing=2, col_spacing=3, matrix=self.__post_matrix__, fontsize = self.text_size, mask=False, wrap=True, truncate_rows=True)
self.draw_design(table_design)
def __fill_post_matrix__ (self):
price,name=CryptoPrices.__get_prices__(self.coin)
x=0
while x < len(name):
row = name[x]+": $"+str(price[x])
self.__post_matrix__.append(row)
x= x+1
print(self.__post_matrix__)

29
Calendar/CryptoPrices.py Normal file
View file

@ -0,0 +1,29 @@
from CryptoInterface import CryptoInterface
from datetime import datetime, timedelta, date
import CryptoItem
import urllib.request
import json
import math
class CryptoPrices(CryptoInterface):
def __init__(self, coins):
self.coins = coins
super(CryptoPrices, self).__init__()
def is_available(self):
if len(self.coins) > 0 and len(self.coins) < 8:
return True
else:
return False
def __get_prices__(self):
price=[]
name=[]
for coin in self.coins:
data = urllib.request.urlopen("https://api.coingecko.com/api/v3/simple/price?ids="+coin+"&vs_currencies=USD").read()
dataJSON = json.loads(data.decode('utf-8'))
raw = dataJSON[coin]["usd"]
price.append(math.ceil(raw*100)/100)
name.append(coin)
return price,name

View file

@ -59,6 +59,9 @@ class DayHeaderDesign (DesignEntity):
def add_rssfeed (self, rss): def add_rssfeed (self, rss):
pass pass
def add_crypto (self, crypto):
pass
def __finish_image__ (self): def __finish_image__ (self):
self.__draw_number_square__() self.__draw_number_square__()
self.__draw_month__() self.__draw_month__()
@ -87,7 +90,7 @@ class DayHeaderDesign (DesignEntity):
box_height = int(numberbox_height * self.size[1]) box_height = int(numberbox_height * self.size[1])
box_pos = (box_ypos + box_height + xpadding, box_ypos + ypadding) box_pos = (box_ypos + box_height + xpadding, box_ypos + ypadding)
box_size = (int(monthbox_width * self.size[0]), box_height) box_size = (int(monthbox_width * self.size[0]), box_height)
month_name = self.date.strftime("%B") month_name = self.date.strftime("%B")
month = TextDesign(box_size, text=month_name, fontsize=font_size) month = TextDesign(box_size, text=month_name, fontsize=font_size)
month.pos = box_pos month.pos = box_pos
@ -126,7 +129,7 @@ class DayHeaderDesign (DesignEntity):
size = (box_height, weekdaybox_height * box_height) size = (box_height, weekdaybox_height * box_height)
box_ypos = numberbox_ypos * self.size[1] box_ypos = numberbox_ypos * self.size[1]
pos = (box_ypos, box_ypos) pos = (box_ypos, box_ypos)
week_day_name = self.date.strftime("%A") week_day_name = self.date.strftime("%A")
week_day = TextDesign(size, text=week_day_name, background_color=numberbox_background_color, color=numberbox_font_color, fontsize=font_size, horizontalalignment="center", verticalalignment = "center", font=weekday_font) week_day = TextDesign(size, text=week_day_name, background_color=numberbox_background_color, color=numberbox_font_color, fontsize=font_size, horizontalalignment="center", verticalalignment = "center", font=weekday_font)
week_day.pos = pos week_day.pos = pos
@ -137,4 +140,4 @@ class DayHeaderDesign (DesignEntity):
return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1])) return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1]))
def __get_day_text__ (self): def __get_day_text__ (self):
return str(self.date.day) return str(self.date.day)

View file

@ -1,13 +1,14 @@
from PanelDesign import PanelDesign from PanelDesign import PanelDesign
from Assets import colors from Assets import colors
from settings import general_settings from settings import general_settings
import calendar as callib import calendar as callib
from datetime import datetime, timedelta, date from datetime import datetime, timedelta, date
from PIL import ImageDraw from PIL import ImageDraw
from TextDesign import TextDesign from TextDesign import TextDesign
from DayHeaderDesign import DayHeaderDesign from DayHeaderDesign import DayHeaderDesign
from DayRowDesign import DayRowDesign from DayRowDesign import DayRowDesign
from RssPostListDesign import RssPostListDesign from RssPostListDesign import RssPostListDesign
from CryptoListDesign import CryptoListDesign
from settings import line_thickness from settings import line_thickness
todayheader_pos = (0,0) todayheader_pos = (0,0)
@ -20,6 +21,7 @@ dayrowsarea_height = 1 - todayheader_size[1]
dayrow_min_format = 50 / 384 dayrow_min_format = 50 / 384
dayrow_max_format = 70 / 384 dayrow_max_format = 70 / 384
rss_y_padding = 5 rss_y_padding = 5
crypto_y_padding = 5
class DayListPanel (PanelDesign): class DayListPanel (PanelDesign):
"""Overview that focuses on the current day and """Overview that focuses on the current day and
@ -48,6 +50,12 @@ class DayListPanel (PanelDesign):
if general_settings["info-area"] is "rss": if general_settings["info-area"] is "rss":
self.__draw_rss_infoarea__(rss) self.__draw_rss_infoarea__(rss)
def add_crypto (self, crypto):
for row in self.__day_rows__:
row.add_crypto(crypto)
if general_settings["info-area"] is "crypto":
self.__draw_crypto_infoarea__(crypto)
def __draw_rss_infoarea__ (self, rss): def __draw_rss_infoarea__ (self, rss):
height = infoarea_replacedrowscount * self.dayrow_size[1] * self.size[1] - rss_y_padding height = infoarea_replacedrowscount * self.dayrow_size[1] * self.size[1] - rss_y_padding
ypos = self.size[1] - height ypos = self.size[1] - height
@ -58,6 +66,16 @@ class DayListPanel (PanelDesign):
design.pos = pos design.pos = pos
self.draw_design(design) self.draw_design(design)
def __draw_crypto_infoarea__ (self, crypto):
height = infoarea_replacedrowscount * self.dayrow_size[1] * self.size[1] - crypto_y_padding
ypos = self.size[1] - height
size = (self.size[0], height)
pos = (0, ypos)
design = CryptoListDesign(size, crypto)
design.pos = pos
self.draw_design(design)
def __draw_day_rows__ (self): def __draw_day_rows__ (self):
following_days = self.__get_following_days__() following_days = self.__get_following_days__()
for i, date in enumerate(following_days): for i, date in enumerate(following_days):
@ -79,7 +97,7 @@ class DayListPanel (PanelDesign):
row_height = max_area_height / self.dayrow_count row_height = max_area_height / self.dayrow_count
self.dayrow_size = (1, row_height / self.size[1]) self.dayrow_size = (1, row_height / self.size[1])
if general_settings["info-area"] in ["rss"]: if general_settings["info-area"] in ["rss"] or ["crypto"]:
self.dayrow_count -= infoarea_replacedrowscount self.dayrow_count -= infoarea_replacedrowscount
def __get_following_days__(self): def __get_following_days__(self):
@ -108,4 +126,4 @@ class DayListPanel (PanelDesign):
self.__draw_lines__() self.__draw_lines__()
def __abs_co__(self, coordinates): def __abs_co__(self, coordinates):
return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1])) return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1]))

View file

@ -38,6 +38,9 @@ class DayRowDesign (DesignEntity):
def add_rssfeed (self, rss): def add_rssfeed (self, rss):
pass pass
def add_crypto (self, crypto):
pass
def __draw_event_list__ (self, calendar): def __draw_event_list__ (self, calendar):
number_width = daynumber_y_size[0] * self.size[1] number_width = daynumber_y_size[0] * self.size[1]
ypos = eventlist_ypos * self.size[1] ypos = eventlist_ypos * self.size[1]
@ -47,7 +50,7 @@ class DayRowDesign (DesignEntity):
pos = (number_width + eventlist_xpadding, ypos) pos = (number_width + eventlist_xpadding, ypos)
size = (self.size[0] - pos[0] - weather_width, self.size[1] - pos[1]) size = (self.size[0] - pos[0] - weather_width, self.size[1] - pos[1])
fontsize = eventlist_y_fontsize * self.size[1] fontsize = eventlist_y_fontsize * self.size[1]
events = calendar.get_day_events(self.date) events = calendar.get_day_events(self.date)
rel_dates = [self.date for _ in range(len(events))] rel_dates = [self.date for _ in range(len(events))]
event_list = SingelDayEventListDesign(size, events, fontsize, event_prefix_rel_dates = rel_dates) event_list = SingelDayEventListDesign(size, events, fontsize, event_prefix_rel_dates = rel_dates)
@ -56,7 +59,7 @@ class DayRowDesign (DesignEntity):
def __draw_forecast__ (self, weather): def __draw_forecast__ (self, weather):
forecast = weather.get_forecast_in_days(self.date.day - datetime.today().day) forecast = weather.get_forecast_in_days(self.date.day - datetime.today().day)
if forecast is None: if forecast is None:
return return
@ -80,7 +83,7 @@ class DayRowDesign (DesignEntity):
color = self.__get_day_color__() color = self.__get_day_color__()
week_day_name = self.date.strftime("%a") week_day_name = self.date.strftime("%a")
week_day = TextDesign(size, text=week_day_name, font=font, color=color, fontsize=font_size, horizontalalignment="center", verticalalignment="top") week_day = TextDesign(size, text=week_day_name, font=font, color=color, fontsize=font_size, horizontalalignment="center", verticalalignment="top")
week_day.pos = pos week_day.pos = pos
week_day.mask = False week_day.mask = False
@ -112,4 +115,4 @@ class DayRowDesign (DesignEntity):
elif week_starts_on == "Sunday" and self.date.strftime("%w") == "6": elif week_starts_on == "Sunday" and self.date.strftime("%w") == "6":
return colors["hl"] return colors["hl"]
else: else:
return colors["fg"] return colors["fg"]

View file

@ -2,18 +2,20 @@ from PanelDesign import PanelDesign
from datetime import datetime, timedelta, date from datetime import datetime, timedelta, date
from DayHeaderDesign import DayHeaderDesign from DayHeaderDesign import DayHeaderDesign
from HourListDesign import HourListDesign from HourListDesign import HourListDesign
from settings import general_settings, line_thickness from settings import general_settings
from RssPostListDesign import RssPostListDesign from RssPostListDesign import RssPostListDesign
from PIL import ImageDraw from PIL import ImageDraw
from Assets import colors from Assets import colors
from EventListDesign import EventListDesign from EventListDesign import EventListDesign
from CryptoListDesign import CryptoListDesign
header_size = (1, 0.2) header_size = (1, 0.2)
hourlist_size = (1, 1 - header_size[1]) hourlist_size = (1, 1 - header_size[1])
default_shownhours_count = 12 default_shownhours_count = 12
infoarea_replaced_hours = 4 infoarea_replaced_hours = 4
infoarea_borderline_width = line_thickness infoarea_borderline_width = 1
infoarea_padding = 5 infoarea_padding = 5
class DayViewPanel (PanelDesign): class DayViewPanel (PanelDesign):
@ -47,6 +49,11 @@ class DayViewPanel (PanelDesign):
self.__draw_rss_feed__(rss) self.__draw_rss_feed__(rss)
self.__draw_infoarea_line__() self.__draw_infoarea_line__()
def add_cryptofeed (self, crypto):
if general_settings["info-area"] == "crypto":
self.__draw_crypto_feed__(crypto)
self.__draw_infoarea_line__()
def __draw_infoarea_line__(self): def __draw_infoarea_line__(self):
height = infoarea_replaced_hours * self.__hourlist__.row_size[1] height = infoarea_replaced_hours * self.__hourlist__.row_size[1]
ypos = self.size[1] - height ypos = self.size[1] - height
@ -64,6 +71,16 @@ class DayViewPanel (PanelDesign):
rss.pos = pos rss.pos = pos
self.draw_design(rss) self.draw_design(rss)
def __draw_crypto_feed__(self, crypto):
height = infoarea_replaced_hours * self.__hourlist__.row_size[1] - infoarea_padding
size = (self.size[0], height)
pos = (0, self.size[1] - size[1])
crypto = CryptoListDesign(size, crypto)
crypto.pos = pos
self.draw_design(crypto)
def __draw_event_list__(self, calendar): def __draw_event_list__(self, calendar):
height = infoarea_replaced_hours * self.__hourlist__.row_size[1] - infoarea_padding height = infoarea_replaced_hours * self.__hourlist__.row_size[1] - infoarea_padding
size = (self.size[0], height) size = (self.size[0], height)
@ -88,14 +105,14 @@ class DayViewPanel (PanelDesign):
start, end = self.__get_current_hour_range__() start, end = self.__get_current_hour_range__()
size = self.__abs_co__(hourlist_size) size = self.__abs_co__(hourlist_size)
size = (size[0], size[1] * self.shownhours_count / default_shownhours_count) size = (size[0], size[1] * self.shownhours_count / default_shownhours_count)
self.__hourlist__ = HourListDesign(size, start, end) self.__hourlist__ = HourListDesign(size, start, end)
self.__hourlist__.pos = (0, self.__header__.size[1]) self.__hourlist__.pos = (0, self.__header__.size[1])
def __get_current_hour_range__(self): def __get_current_hour_range__(self):
start_hour = datetime.now().hour start_hour = datetime.now().hour
additional_hours = self.shownhours_count - 1 additional_hours = self.shownhours_count - 1
if start_hour + additional_hours > 23: if start_hour + additional_hours > 23:
start_hour = 23 - additional_hours start_hour = 23 - additional_hours
@ -126,4 +143,4 @@ class DayViewPanel (PanelDesign):
today = date.today() today = date.today()
return dt.day == today.day and \ return dt.day == today.day and \
dt.month == today.month and \ dt.month == today.month and \
dt.year == today.year dt.year == today.year

View file

@ -13,7 +13,7 @@ from Assets import path
from LoopTimer import LoopTimer from LoopTimer import LoopTimer
import locale import locale
from DebugConsole import DebugConsole from DebugConsole import DebugConsole
from settings import datetime_encoding, language, render_to_display, render_to_file, display_colours, location, api_key, owm_paid_subscription, choosen_design, ical_urls, highlighted_ical_urls, rss_feeds, update_interval, calibrate_hours from settings import datetime_encoding, language, render_to_display, render_to_file, display_colours, location, api_key, owm_paid_subscription, choosen_design, ical_urls, highlighted_ical_urls, rss_feeds, update_interval, calibrate_hours,coins
from MonthOvPanel import MonthOvPanel from MonthOvPanel import MonthOvPanel
from DayListPanel import DayListPanel from DayListPanel import DayListPanel
from DayViewPanel import DayViewPanel from DayViewPanel import DayViewPanel
@ -22,6 +22,7 @@ from AgendaListPanel import AgendaListPanel
import OwmForecasts import OwmForecasts
import IcalEvents import IcalEvents
import RssParserPosts import RssParserPosts
import CryptoPrices
all_locales = locale.locale_alias all_locales = locale.locale_alias
if language.lower() not in all_locales.keys(): if language.lower() not in all_locales.keys():
@ -61,6 +62,7 @@ def main():
owm = OwmForecasts.OwmForecasts(location, api_key, paid_api=owm_paid_subscription) owm = OwmForecasts.OwmForecasts(location, api_key, paid_api=owm_paid_subscription)
events_cal = IcalEvents.IcalEvents(ical_urls, highlighted_ical_urls) events_cal = IcalEvents.IcalEvents(ical_urls, highlighted_ical_urls)
rss = RssParserPosts.RssParserPosts(rss_feeds) rss = RssParserPosts.RssParserPosts(rss_feeds)
coin = CryptoPrices.CryptoPrices(coins)
while True: while True:
loop_timer.begin_loop() loop_timer.begin_loop()
@ -71,11 +73,15 @@ def main():
for output in output_adapters: for output in output_adapters:
output.calibrate() output.calibrate()
if choosen_design in available_panels.keys(): if choosen_design in available_panels.keys():
design = available_panels[choosen_design]((epd.width, epd.height)) design = available_panels[choosen_design]((epd.width, epd.height))
else: else:
raise ImportError("choosen_design must be valid (" + choosen_design + ")") raise ImportError("choosen_design must be valid (" + choosen_design + ")")
debug.print_line('Getting crypto prices')
coin.reload()
design.add_crypto(coin)
debug.print_line("Fetching weather information from open weather map") debug.print_line("Fetching weather information from open weather map")
owm.reload() owm.reload()
design.add_weather(owm) design.add_weather(owm)

View file

@ -11,7 +11,9 @@ from EllipseDesign import EllipseDesign
from MonthBlockDesign import MonthBlockDesign, daynumberboxsize from MonthBlockDesign import MonthBlockDesign, daynumberboxsize
from EventListDesign import EventListDesign from EventListDesign import EventListDesign
from RssPostListDesign import RssPostListDesign from RssPostListDesign import RssPostListDesign
from settings import general_settings, line_thickness from settings import general_settings
from CryptoListDesign import CryptoListDesign
weatherheadersize = (1,0.113) weatherheadersize = (1,0.113)
monthboxsize = (1, 0.085) monthboxsize = (1, 0.085)
@ -65,6 +67,10 @@ class MonthOvPanel (PanelDesign):
if general_settings["info-area"] is "rss": if general_settings["info-area"] is "rss":
self.__draw_rss_post_list_to_bottom__(rss) self.__draw_rss_post_list_to_bottom__(rss)
def add_crypto (self, crypto):
if general_settings["info-area"] is "crypto":
self.__draw_crypto_post_list_to_bottom__(crypto)
def add_calendar (self, calendar): def add_calendar (self, calendar):
if general_settings["highlight-event-days"]: if general_settings["highlight-event-days"]:
month_events = list(set([ (event.begin_datetime.day, event.begin_datetime.month, event.begin_datetime.year) for event in calendar.get_month_events()])) month_events = list(set([ (event.begin_datetime.day, event.begin_datetime.month, event.begin_datetime.year) for event in calendar.get_month_events()]))
@ -82,6 +88,14 @@ class MonthOvPanel (PanelDesign):
info_list.pos = (int(month_pos[0]), month_pos[1] + month_height + self.weather_header_height) info_list.pos = (int(month_pos[0]), month_pos[1] + month_height + self.weather_header_height)
self.draw_design(info_list) self.draw_design(info_list)
def __draw_crypto_post_list_to_bottom__ (self, crypto):
month_pos = self.__abs_pos__(monthovposition)
month_height = self.month_block.get_real_height()
size = (self.size[0], self.size[1] - (month_pos[1] + month_height + self.weather_header_height))
info_list = CryptoListDesign(size, crypto)
info_list.pos = (int(month_pos[0]), month_pos[1] + month_height + self.weather_header_height)
self.draw_design(info_list)
def __draw_event_list_to_bottom__ (self, calendar): def __draw_event_list_to_bottom__ (self, calendar):
month_pos = self.__abs_pos__(monthovposition) month_pos = self.__abs_pos__(monthovposition)
month_height = self.month_block.get_real_height() month_height = self.month_block.get_real_height()
@ -110,7 +124,7 @@ class MonthOvPanel (PanelDesign):
def __draw_seperator__ (self): def __draw_seperator__ (self):
"""Draw a line seperating the weather and Calendar section""" """Draw a line seperating the weather and Calendar section"""
ImageDraw.Draw(self.__image__).line([ self.__abs_pos__(seperatorplace), self.__abs_pos__((1, seperatorplace[1])) ], fill='red', width=line_thickness) ImageDraw.Draw(self.__image__).line([ self.__abs_pos__(seperatorplace), self.__abs_pos__((1, seperatorplace[1])) ], fill='red', width=5)
def __draw_month_name__ (self): def __draw_month_name__ (self):
"""Draw the icon with the current month's name""" """Draw the icon with the current month's name"""
@ -126,7 +140,7 @@ class MonthOvPanel (PanelDesign):
pos = self.__get_week_day_pos__(day_of_week) pos = self.__get_week_day_pos__(day_of_week)
txt.pos = (pos[0], pos[1] + weekdaytextpadding * self.size[1]) txt.pos = (pos[0], pos[1] + weekdaytextpadding * self.size[1])
self.draw_design(txt) self.draw_design(txt)
self.__draw_highlight_box__(self.__abs_pos__(weekrownameboxsize), self.__get_week_day_pos__(self.__get_day_of_week__(datetime.now())), width=1) self.__draw_highlight_box__(self.__abs_pos__(weekrownameboxsize), self.__get_week_day_pos__(self.__get_day_of_week__(datetime.now())), width=1)
def __get_week_day_pos__ (self, day_of_week): def __get_week_day_pos__ (self, day_of_week):
@ -158,4 +172,4 @@ class MonthOvPanel (PanelDesign):
return weekdays return weekdays
def __get_day_of_week__ (self, date): def __get_day_of_week__ (self, date):
return self.__week_days__.index(date.strftime("%a")) return self.__week_days__.index(date.strftime("%a"))

View file

@ -21,13 +21,14 @@ datetime_encoding = "UTF-8" # UTF-8
units = "metric" #aviation (celcius,degrees/knots), metric (celcius,kmh), imperial(f,mph) units = "metric" #aviation (celcius,degrees/knots), metric (celcius,kmh), imperial(f,mph)
hours = "24" hours = "24"
update_interval = 60 update_interval = 60
coins=["bitcoin","litecoin","ethereum","binancecoin"] #Max might be 7 once fixed.
"""DESIGN""" """DESIGN"""
font_size = 14 # does not affect every text font_size = 14 # does not affect every text
font_boldness = "semibold" # extralight, light, regular, semibold, bold, extrabold font_boldness = "semibold" # extralight, light, regular, semibold, bold, extrabold
choosen_design = "month-overview" # month-overview, day-list, day-view, agenda-list, month-view line_thickness = 1 #1-3 Thickness advised // Default = 1 // day-list view only!
line_thickness = 1 # 1-3 Thickness advised choosen_design = "day-list" # month-overview, day-list, day-view, agenda-list, month-view
general_settings = { # General settings that designs may use general_settings = { # General settings that designs may use
"info-area" : "rss", # empty, events, rss "info-area" : "rss", # empty, events, rss
"highlight-event-days" : True, "highlight-event-days" : True,