# Copyright (C) 2020 Fintic, finticofficial@gmail.com # # This file is part of Fintic project, developed by Neythen Treloar and Justin Dunn # # stockTicker can not be copied and/or distributed without the express # permission of Fintic import sys, select import os import threading from PIL import Image, ImageDraw, ImageFont, ImageSequence Image.init() import pytz import time import csv import requests import pexpect from rgbmatrix import RGBMatrix, RGBMatrixOptions from rgbmatrix.graphics import * from multiprocessing import Process import traceback import json from datetime import datetime import matplotlib.colors as mcolors def getInput(Block=False): if Block or select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []): msg = sys.stdin.read(1) #sys.stdin.flush() else: msg = '' return msg class StockTicker(): def __init__(self): #Define global resources self.symbols = [] self.delay = 0.02 self.greenORred = (255, 255, 255) #self.blank = Image.open('logos/blank.png') self.blank = Image.new('RGB', (10, 32)) self.running = True settings = json.load(open('csv/general_settings.json', 'r')) self.brightness = settings['brightness']*10 # Configuration for the matrix options = RGBMatrixOptions() options.rows = 32 options.cols = 64 options.chain_length = 2 options.parallel = 1 options.hardware_mapping = 'adafruit-hat' # If you have an Adafruit HAT: 'adafruit-hat' options.gpio_slowdown = 2 options.brightness = self.brightness self.matrix = RGBMatrix(options = options) #sys.exit() 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, '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, 'IPO Calendar':self.getIpoImage, 'IPO Calendar Prof':self.getIpoProfessional, 'Stocks Prof': self.getStockProfessional, 'Crypto Prof': self.getCryptoProfessional, 'Forex Prof': self.getForexProfessional, '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', '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', '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', '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'} def openImage(self, image_file): image = Image.open(image_file) image = image.convert('RGB') # Make image fit our screen. #image.thumbnail((self.matrix.width, self.matrix.height), Image.ANTIALIAS) #image = image.convert('RGB') return image def degreesToCompass(self, deg): dirs = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'] return dirs[int((deg+22.5)//45)%8] def setImage(self, image, offset_x = 0, offset_y = 0, unsafe=True, min_x = 0, max_x = 128, min_y = 0, max_y = 32): if (image.mode != "RGB"): image = image.convert('RGB') if unsafe: #In unsafe mode we directly acceshow to send commands to running python processs the underlying PIL image array #in cython, which is considered unsafe pointer accecss, #however it's super fast and seems to work fine #https://groups.google.com/forum/#!topic/cython-users/Dc1ft5W6KM4 img_width, img_height = image.size self.matrix.SetPixelsPillow(offset_x, offset_y, img_width, img_height, image) else: # First implementation of a SetImage(). OPTIMIZE_ME: A more native # implementation that directly reads the buffer and calls the underlying # C functions can certainly be faster. img_width, img_height = image.size pixels = image.load() for y in range(max(0, -offset_y), min(img_height, self.matrix.height - offset_y)): for x in range(max(0, -offset_x), min(img_width, self.matrix.width - offset_x)): if min_x <= x + offset_x <= max_x and min_y <= y + offset_y <= max_y: (r, g, b) = pixels[x, y] self.matrix.SetPixel(x + offset_x, y + offset_y, r*self.brightness, g*self.brightness, b*self.brightness) def scrollImage(self, image, offset_x = 0, offset_y = 0, frame_skip = 10, gif = False, pause_frames = 0): img_width, img_height = image.size kill = False while offset_x > -(img_width+1): if offset_x == 0: while pause_frames > 0: if pause_frames%frame_skip == 0: self.incrementGIF(image) pause_frames -=1 if gif: self.double_buffer.SetImage(image.convert('RGB'), offset_x, offset_y) else: self.double_buffer.SetImage(image, offset_x, offset_y) for y in range(self.matrix.height): self.matrix.SetPixel(offset_x + img_width +1 , y , 0,0,0) self.matrix.SetPixel(offset_x + img_width , y , 0,0,0) self.double_buffer = self.matrix.SwapOnVSync(self.double_buffer) time.sleep(self.delay) kill = self.checkKilled() if kill: break if kill: break # for animation in gifs if offset_x%frame_skip == 0: self.incrementGIF(image) #image = image.convert('RGB') offset_x -= 1 #self.setImage(image.convert('RGB'), offset_x = offset_x, offset_y = offset_y) if gif: self.double_buffer.SetImage(image.convert('RGB'), offset_x, offset_y) else: self.double_buffer.SetImage(image, offset_x, offset_y) buff = 0 # remove the ppixels behind the image, to stop trailing self.double_buffer = self.matrix.SwapOnVSync(self.double_buffer) for y in range(self.matrix.height): self.matrix.SetPixel(offset_x + img_width +1 , y , 0,0,0) self.matrix.SetPixel(offset_x + img_width , y , 0,0,0) time.sleep(self.delay) kill = self.checkKilled() if kill: break return kill def scrollImageY(self, image, direction = 1, offset_x = 0, offset_y = 0, frame_skip = 10, gif = False): kill = False while offset_y != 0: # for animation in gifs if offset_y%frame_skip == 0: self.incrementGIF(image) offset_y += direction if gif: self.double_buffer.SetImage(image.convert('RGB'), offset_x, offset_y) else: self.double_buffer.SetImage(image, offset_x, offset_y) self.double_buffer = self.matrix.SwapOnVSync(self.double_buffer) time.sleep(self.delay) kill = self.checkKilled() if kill: break return kill def scrollImageTransition(self, image_files, offset_x = 0, offset_y = 0, stocks = True): # use two image files and switch between them with a seemless transition current_img = 1 image1 = self.openImage(image_files[0]).convert('RGB') image2 = self.openImage(image_files[1]).convert('RGB') double_buffer = self.matrix.CreateFrameCanvas() kill = False while True: if current_img == 1: if stocks: update_process = Process(target = self.getFullStockImage, args = (1,)) update_process.start() image1 = self.openImage(image_files[0]).convert('RGB') image2 = self.openImage(image_files[1]).convert('RGB') elif current_img == 2: if stocks: update_process = Process(target = self.getFullStockImage, args = (2,)) update_process.start() image1 = self.openImage(image_files[1]).convert('RGB') image2 = self.openImage(image_files[0]).convert('RGB') img_width, img_height = image1.size while offset_x > -img_width: offset_x -= 1 double_buffer.SetImage(image1, offset_x, offset_y) if offset_x + img_width < self.matrix.width: # if the image is ending double_buffer.SetImage(image2, offset_x, offset_y) double_buffer = self.matrix.SwapOnVSync(double_buffer) time.sleep(self.delay) kill = self.checkKilled() if kill: break if stocks: image1.close() image2.close() if kill: break if stocks: update_process.join() update_process.terminate() if current_img == 1: current_img = 2 elif current_img == 2: current_img = 1 offset_x = 0 update_process.join() update_process.terminate() def scrollImageStacked(self, image, offset_x = 0, offset_y = 0): img_width, img_height = image.size while offset_x > -img_width - 128: offset_x -= 1 self.setImage(image, offset_x = offset_x+128, offset_y = offset_y) self.setImage(image, offset_x = offset_x, offset_y = offset_y+20) kill = self.checkKilled() time.sleep(self.delay) return kill def updateMultiple(self, options): for option in options: if option not in ['Custom GIFs', 'Custom Images', 'Custom Messages']: # these images are already saved in user uploads, dodnt need to update them img = self.functions[option]() img.save('./display_images/'+ option+ '.ppm') def incrementGIF(self, image): try: image.seek(self.frame) except EOFError: self.frame = 0 image.seek(self.frame) self.frame +=1 def checkKilled(self): kill = False try: msg = getInput() if msg == 'K': self.resetMatrix() kill = True self.process_msg(msg) except KeyboardInterrupt: sys.stdout.flush() pass return kill def set_delay(self,speed): if speed.lower() == 'slow': self.delay = 0.03 elif speed.lower() == 'medium': self.delay = 0.02 elif speed.lower() == 'fast': self.delay = 0.01 return self.delay def scrollFunctionsAnimated(self, options, animation = 'down', repeat = True): # scrolls trhough all functions with animation. Updates functions and remakes images when each function not being dispplayed self.updateMultiple([options[0]]) kill = False i = 0 # keep track of which image we are displaying self.double_buffer = self.matrix.CreateFrameCanvas() while True: update_process = Process(target = self.updateMultiple, args = ([options[(i+1) % len(options)]],)) update_process.start() f = open(self.JSONs[options[(i) % len(options)]]) settings = json.load(f) f.close() self.set_delay(settings['speed']) animation = settings['animation'].lower() if options[i % len(options)] == 'Custom Images': images = self.getUserImages() elif options[i % len(options)] == 'Custom GIFs': images = self.getUserGIFs() elif options[i % len(options)] == 'Custom Messages': images = self.getUserMessages() else: #these options just have a single ppm image image = self.openImage('./display_images/' + options[i % len(options)] +'.ppm') images = [image] for image in images: img_width, img_height = image.size offset_x = 0 if animation == 'continuous': offset_x = 128 elif animation in ['up', 'down']: offset_x = max(0, 128-img_width) offset_y = 0 #first scroll image in from bottom frame_skip = int((1/15)/self.delay) #controls how fast gifs run self.frame = 0 pause_frames = int(0.5/self.delay) if animation == 'up': offset_y = 33 direction = -1 kill = self.scrollImageY(image, direction = direction, offset_x = offset_x, offset_y = offset_y, frame_skip = frame_skip, gif = options[i % len(options)] == 'Custom GIFs') elif animation == 'down': direction = 1 offset_y = -33 kill = self.scrollImageY(image, direction = direction, offset_x = offset_x, offset_y = offset_y, frame_skip = frame_skip, gif = options[i % len(options)] == 'Custom GIFs') if kill: break offset_y = 0 if animation in ['up', 'down']: while pause_frames > 0: if pause_frames%frame_skip == 0: self.incrementGIF(image) pause_frames -=1 if options[i % len(options)] != 'Custom GIFs': self.double_buffer.SetImage(image, offset_x, offset_y) else: self.double_buffer.SetImage(image.convert('RGB'), offset_x, offset_y) self.double_buffer = self.matrix.SwapOnVSync(self.double_buffer) time.sleep(self.delay) kill = self.checkKilled() if kill: break if kill: break if kill: break try: pause = float(settings['pause']) except: pause = 0 pause_frames = int(float(pause)/self.delay) kill = self.scrollImage(image, offset_x = offset_x, offset_y = offset_y, frame_skip = frame_skip, gif = options[i % len(options)] == 'Custom GIFs', pause_frames = pause_frames) if kill: break if kill:break if not repeat: break update_process.join() update_process.terminate() i+=1 def scrollProfessionalAnimated(self, options, animation = 'on'): # scrolls trhough all functions with animation. Updates functions and remakes images when each function not being dispplayed top = options[0] bottom = options[1] self.updateMultiple([top[0], bottom[0]]) kill = False i1 = 0 # keep track of which image we are displaying i2 = 0 # keep track of which image we are displaying self.double_buffer = self.matrix.CreateFrameCanvas() update_process = Process(target = self.updateMultiple, args = ([top[(i1+1) % len(top)]+ ' Prof', bottom[(i2+1) % len(bottom)]+ ' Prof' ],)) update_process.start() self.updateMultiple([top[i1 % len(top)]+ ' Prof', bottom[i2 % len(bottom)]+ ' Prof' ]) image1 = self.openImage('./display_images/' + top[i1 % len(top)] +' Prof.ppm') image1 = image1.convert('RGB') image2 = self.openImage('./display_images/' + bottom[i2 % len(bottom)] +' Prof.ppm') image2 = image2.convert('RGB') settings1 = json.load(open(self.JSONs[top[i1 % len(top)]])) delay_t1 = self.set_delay(settings1['speed']) animation1 = settings1['animation'].lower() settings2 = json.load(open(self.JSONs[bottom[i2 % len(bottom)] ])) try: delay_t2 = self.set_delay(settings2['speed2']) except: delay_t2 = self.set_delay(settings2['speed']) animation2 = settings2['animation'].lower() if animation1 == 'continuous': offset_y1 = 0 offset_x1 = 128 else: offset_y1 = -16 offset_x1 = 0 if animation2 == 'continuous': offset_y2 = 16 offset_x2 = 128 else: offset_y2 = 32 offset_x2 = 0 frame_skip = int((1/15)/self.delay) #controls how fast gifs run self.frame = 0 img_width1, img_height1 = image1.size img_width2, img_height2 = image2.size kill = False update_t1 = time.time() update_t2 = time.time() while True: if offset_x1 < -(img_width1+1): i1 += 1 settings1 = json.load(open(self.JSONs[top[i1 % len(top)]])) delay_t1 = self.set_delay(settings1['speed']) animation1 = settings1['animation'].lower() if animation1 == 'continuous': offset_y1 = 0 offset_x1 = 128 else: offset_y1 = -16 offset_x1 = 0 update_process.join() update_process.terminate() update_process = Process(target = self.updateMultiple, args = ([top[(i1+1) % len(top)]+ ' Prof'],)) update_process.start() image1 = self.openImage('./display_images/' + top[i1 % len(top)] +' Prof.ppm') image1 = image1.convert('RGB') img_width1, img_height1 = image1.size if offset_x2 < -(img_width2+1): i2 += 1 settings2 = json.load(open(self.JSONs[bottom[(i2) % len(bottom)]])) try: delay_t2 = self.set_delay(settings2['speed2']) except: delay_t2 = self.set_delay(settings2['speed']) animation2 = settings2['animation'].lower() if animation2 == 'continuous': offset_y2 = 16 offset_x2 = 128 else: offset_y2 = 32 offset_x2 = 0 update_process.join() update_process.terminate() update_process = Process(target = self.updateMultiple, args = ([bottom[i2 % len(bottom)]+ ' Prof'],)) update_process.start() image2 = self.openImage('./display_images/' + bottom[i2 % len(bottom)] +' Prof.ppm') image2 = image2.convert('RGB') img_width2, img_height2 = image2.size if time.time() - update_t1 > delay_t1: update_t1 = time.time() if offset_y1 < 0: offset_y1+=1 else: offset_x1 -= 1 if time.time() - update_t2 > delay_t2: update_t2 = time.time() if offset_y2 > 16: offset_y2-=1 else: offset_x2 -= 1 if kill: break #image = image.convert('RGB') self.double_buffer.SetImage(image1, offset_x1, offset_y1) self.double_buffer.SetImage(image2, offset_x2, offset_y2) buff = 0 # remove the ppixels behind the image, to stop trailing self.double_buffer = self.matrix.SwapOnVSync(self.double_buffer) for y in range(16): self.matrix.SetPixel(offset_x1 + img_width1 +1 , y , 0,0,0) self.matrix.SetPixel(offset_x1 + img_width1 , y , 0,0,0) for y in range(16,32): self.matrix.SetPixel(offset_x2 + img_width2 +1 , y , 0,0,0) self.matrix.SetPixel(offset_x2 + img_width2 , y , 0,0,0) kill = self.checkKilled() if kill: break if kill: break def scrollMultiple(self, animation = 'down'): # scrolls trhough all functions with animation. Updates functions and remakes images when each function not being dispplayed # read lines from csv images = [] delays = [] kinds = [] f = open('csv/multiple.csv', 'r') CSV = csv.reader(f) next(CSV) font = ImageFont.load("./fonts/texgyre-27.pil") for row in CSV: kind, content, delay = row delays.append(delay) kinds.append(kind) if kind == 'text': images.append(self.textImage(content, font, 255, 255, 0, True, w_buff = 50)) elif kind == 'image': images.append(self.openImage(content).convert('RGB')) elif kind == 'gif': images.append(self.openImage(content)) f.close() kill = False i = 0 # keep track of which image we are displaying self.double_buffer = self.matrix.CreateFrameCanvas() while True: image = images[i%len(images)] delay = delays[i%len(images)] kind = kinds[i%len(images)] img_width, img_height = image.size offset_x = 0 if animation == 'traditional': offset_x = 128 elif animation == 'continuous': offset_x = 0 elif animation in ['up', 'down']: offset_x = max(0, 128-img_width) offset_y = 0 #first scroll image in from bottom frame_skip = int((1/15)/self.delay) #controls how fast gifs run self.frame = 0 pause_frames = int(float(delay)/self.delay) if animation == 'up': offset_y = 33 direction = -1 kill = self.scrollImageY(image, direction = direction, offset_x = offset_x, offset_y = offset_y, frame_skip = frame_skip, gif = kind=='gif') elif animation == 'down': direction = 1 offset_y = -33 kill = self.scrollImageY(image, direction = direction, offset_x = offset_x, offset_y = offset_y, frame_skip = frame_skip, gif = kind=='gif') offset_y = 0 if kill: break kill = self.scrollImage(image, offset_x = offset_x, offset_y = offset_y, frame_skip = frame_skip, gif = kind=='gif', pause_frames = pause_frames) if kill: break i+=1 def textImage(self, text, font, r = 255, g = 255, b = 255, matrix_height = False, w_buff = 3, h_buff = 3, background = False, location = False): #creates and returns a ppm image containing the text in the supplied font and colour width, height = self.get_text_dimensions(text, font) if matrix_height: height = 32 img = Image.new('RGB', (width + w_buff, height + h_buff)) d = ImageDraw.Draw(img) if background: br, bg, bb = background d.rectangle(xy = (0, 0, width + w_buff, height + h_buff), fill = (br, bg, bb)) #outline = (255, 255, 255), #width = 0) #use outline and width to add a border if location: d.text(location, text, fill=(r, g, b), font=font) else: d.text((0, 0), text, fill=(r, g, b), font=font) return img def getUserMessages(self): #displays the text entered in the webpage by the user. f = open('csv/message_settings.json', 'r') all_settings = json.load(f) f.close() colours = {'Black':(0,0,0), '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), 'Gray':(100,100,100), 'Cyan':(0,255,255)} imgs = [] for ind, message in enumerate(all_settings['messages']): font = ImageFont.load("./fonts/10x20.pil") location = (0, 4) if message["size"] == 'Large': font = ImageFont.load("./fonts/texgyre-27.pil") location = (0, -2) elif message["size"] == 'Small': font = ImageFont.load("./fonts/6x13.pil") location = (0, 7) r,g,b = colours[message['text_colour']] background = colours[message['background_colour']] img = self.textImage(message['text'], font, int(r), int(g), int(b), True, w_buff = 5, background = background, location = location) if all_settings['title'] and ind == 0: title_img = self.openImage('feature_titles/message.png') imgs.append(self.stitchImage([title_img, img])) else: imgs.append(img) return imgs def getUserMessagesProfessional(self): f = open('csv/message_settings.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/message.png') image_list = [title_img] else: image_list = [] colours = {'Black':(0,0,0), '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), 'Gray':(100,100,100), 'Cyan':(0,255,255)} blank = Image.new('RGB', (0, 16)) for i, message in enumerate(all_settings['messages']): if (i == len(all_settings['messages'])-1): font = ImageFont.load("./fonts/6x13.pil") location = (5, 2) r,g,b = colours[message['text_colour']] background = colours[message['background_colour']] msg_img = self.textImage(message['text'], font, int(r), int(g), int(b), True, w_buff = 11, background = background, location = location) img = Image.new('RGB', (msg_img.size[0] + 5, 32)) img.paste(msg_img, (0,0)) image_list.append(img) image_list.append(blank) else: font = ImageFont.load("./fonts/6x13.pil") location = (5, 2) r,g,b = colours[message['text_colour']] background = colours[message['background_colour']] msg_img = self.textImage(message['text'], font, int(r), int(g), int(b), True, w_buff = 11, background = background, location = location) img = Image.new('RGB', (msg_img.size[0] + 130, 32)) img.paste(msg_img, (0,0)) image_list.append(img) image_list.append(blank) return self.stitchImage(image_list) def displayGIF(self, gif, delay = 0.5, repeat = True): # To iterate through the entire gif i = 0 while True: try: gif.seek(i) except EOFError: if not repeat: break i = 0 gif.seek(i) # do something to im self.setImage(gif.convert('RGB')) time.sleep(delay) i += 1 try: msg = getInput() if msg == 'K': gif.close() self.resetMatrix() break self.process_msg(msg) except KeyboardInterrupt: sys.stdout.flush() pass def scrollGIF(self, gif, offset_x = 0, offset_y = 0): # To iterate through the entire gif i = 0 img_width, img_height = gif.size while offset_x > -img_width: offset_x -= 1 try: gif.seek(i) except EOFError: i = 0 gif.seek(i) # do something to im self.setImage(gif.convert('RGB'), offset_x = offset_x) time.sleep(self.delay) if offset_x % 20 == 0: i += 1 for x in range(offset_x + img_width, 128): for y in range(self.matrix.height): self.matrix.SetPixel(x , y , 0,0,0) kill = self.checkKilled() if kill: break return kill #Using change between min and day price give appropriate arrow #and set the overall change colour def getArrow(self, CHANGE, professional = False): self.greenORred logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'stocks') if(CHANGE>0): Arrow = Image.open(os.path.join(logos_path, 'up-1.png')) self.greenORred = (0, 255, 0) else: Arrow = Image.open(os.path.join(logos_path, 'down-1.png')) self.greenORred = (255, 0, 0) CHANGE = (CHANGE * -1) if professional: w, h = Arrow.size Arrow = Arrow.resize((int(w/2), int(h/2))) return Arrow, CHANGE def get_text_dimensions(self, text_string, font): canvas = Image.new('RGB', (10000,100)) draw = ImageDraw.Draw(canvas) monospace = font text = text_string white = (255,255,255) draw.text((0, 0), text, font=monospace, fill=white) bbox = canvas.getbbox() width = bbox[2]-bbox[0] height = bbox[3]-bbox[1] return width,height #Draw Ticker, current and change onto one image def textToImage(self, TICKER, CURRENT, ARROW, percent_change = False, point_change = False, font = ImageFont.load("./fonts/10x20.pil")): 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 +1000 , 32)) d = ImageDraw.Draw(img) d.text((4, 0), TICKER, fill=(255, 255, 255), font=font) d.text((4, 16), CURRENT, fill=self.greenORred, font=font) if percent_change: d.text(((w1+7), 14 - text_height), percent_change, fill=self.greenORred, font=font) w, h = self.get_text_dimensions(percent_change, font) w1 += 7 + w if point_change: img.paste(ARROW, ((w2+ 9),18)) d.text(((w2+29), 16), point_change, fill=self.greenORred, font=font) w,h = self.get_text_dimensions(point_change, font) w2 += 29 + w img = img.crop((0,0,max(w1, w2) + 20,32)) return img def textToImageProf(self, TICKER, CURRENT, CHANGE, ARROW, font): text_width_current, text_height = self.get_text_dimensions(CURRENT, font) 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, ((text_width_current + 7),10)) 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)) total_width = sum(widths) max_height = max(heights) new_im = Image.new('RGB', (total_width, max_height)) x_offset = 0 for im in image_list: new_im.paste(im, (x_offset,0)) x_offset += im.size[0] return new_im def resetMatrix(self): for x in range(self.matrix.width): for y in range(self.matrix.height): self.matrix.SetPixel(x , y , 0,0,0) def getCryptoImage(self): f = open('csv/crypto_settings.json', 'r') all_crypto_settings = json.load(f) f.close() if all_crypto_settings['title']: title_img = self.openImage('feature_titles/crypto.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] if all_crypto_settings['chart']: try: f = open('csv/portfolio_crypto_settings.json', 'r') portfolio_settings = json.load(f)['symbols'] f.close() except: pass coin_info = all_crypto_settings['symbols'] coin_bases = list(coin_info.keys()) for i, cb in enumerate(coin_bases): try: ticker, base = cb.split(',') current = float(coin_info[cb]["current"]) point_change = float(coin_info[cb]["24hr_change"]) point_change2 = abs(point_change) point_changefinal = '{0:.10f}'.format(point_change2).rstrip("0") current_final = '{0:.10f}'.format(current).rstrip("0") percent_change = float(coin_info[cb]["percent_change"]) arrow, change = self.getArrow(point_change) percent_change = '%.2f' % abs(percent_change) + '%' point_change = str(point_changefinal) current = str(current_final) if not all_crypto_settings['percent']: percent_change = False if not all_crypto_settings['point']: point_change = False midFrame = self.textToImage(ticker + '(' + base + ')', current, arrow, percent_change, point_change) #IMAGE THE TEXT if all_crypto_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'crypto') logo = self.openImage(os.path.join(logos_path, ticker + '.png')) stitchedStock = self.stitchImage([logo,midFrame]) except Exception as e: stitchedStock = midFrame else: stitchedStock = midFrame try: if all_crypto_settings['chart'] and (cb in portfolio_settings): #IF USER INPUTTED PORTFOLIO SETTINGS, DISPLAY PORTFOLIO INFO try: cost = portfolio_settings[cb]['cost'] day = portfolio_settings[cb]['day'] shares = portfolio_settings[cb]['shares'] original_value = float(cost) * float(shares) new_value = float(coin_info[cb]['current']) * float(shares) value_day_change_percent = ((float(coin_info[cb]['percent_change'])/100) * new_value) font = ImageFont.load("./fonts/5x8.pil") cost_img = self.textImage('Cost', font, r = 255, g = 255 , b = 255) cost2_img = self.textImage(cost, font, r = 0, g = 255, b = 0) shares_img = self.textImage('Shares', font, r = 255, g = 255 , b = 255) shares2_img = self.textImage(shares, font, r = 0, g = 255, b = 0) pnlchange = new_value - original_value pnlpercent = ((new_value - original_value) / original_value) * 100 pnlpercent_img = self.textImage('P/L%', font, r = 255, g = 255 , b = 255) if pnlpercent >= 0: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 0, g = 255, b = 0) else: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 255, g = 0, b = 0) daypercent_img = self.textImage('Day%', font, r = 255, g = 255 , b = 255) if float(coin_info[cb]['percent_change']) >= 0: daypercent2_img = self.textImage(str('%.2f' % abs(float(coin_info[cb]['percent_change']))) +'%', font, r = 0, g = 255, b = 0) else: daypercent2_img = self.textImage(str('%.2f' % abs(float(coin_info[cb]['percent_change'])))+'%', font, r = 255, g = 0, b = 0) days_img = self.textImage('Days', font, r = 255, g = 255 , b = 255) days2_img = self.textImage(day, font, r = 0, g = 255, b = 0) value_img = self.textImage('Value', font, r = 255, g = 255 , b = 255) value2_img = self.textImage(str('%.2f' % abs(original_value)), font, r = 0, g = 255, b = 0) pnlchange_img = self.textImage('P/L$', font, r = 255, g = 255 , b = 255) if pnlchange >= 0: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 0, g = 255, b = 0) else: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 255, g = 0, b = 0) daychange_img = self.textImage('Day$', font, r = 255, g = 255 , b = 255) if value_day_change_percent >= 0: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 0, g = 255, b = 0) else: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 255, g = 0, b = 0) x_offset = 0 img = Image.new('RGB', (max(cost_img.size[0], cost2_img.size[0], days_img.size[0], days2_img.size[0]) + 7 + max(shares_img.size[0], shares2_img.size[0], value2_img.size[0], value_img.size[0]) + 7 + max(pnlpercent_img.size[0], pnlpercent2_img.size[0], pnlchange_img.size[0], pnlchange2_img.size[0]) + 7 + max(daypercent_img.size[0], daypercent2_img.size[0], daychange_img.size[0], daychange2_img.size[0]) + 15, 32)) img.paste(cost_img, (x_offset, 0)) img.paste(cost2_img, (x_offset, 8)) img.paste(days_img, (x_offset, 16)) img.paste(days2_img, (x_offset, 24)) x_offset += max(cost_img.size[0], cost2_img.size[0], days_img.size[0], days2_img.size[0]) + 7 img.paste(shares_img, (x_offset, 0)) img.paste(shares2_img, (x_offset, 8)) img.paste(value_img, (x_offset, 16)) img.paste(value2_img, (x_offset, 24)) x_offset += max(shares_img.size[0], shares2_img.size[0], value2_img.size[0], value_img.size[0]) + 7 img.paste(pnlpercent_img, (x_offset, 0)) img.paste(pnlpercent2_img, (x_offset, 8)) img.paste(pnlchange_img, (x_offset, 16)) img.paste(pnlchange2_img, (x_offset, 24)) x_offset += max(pnlpercent_img.size[0], pnlpercent2_img.size[0], pnlchange_img.size[0], pnlchange2_img.size[0]) + 7 img.paste(daypercent_img, (x_offset, 0)) img.paste(daypercent2_img, (x_offset, 8)) img.paste(daychange_img, (x_offset,16)) img.paste(daychange2_img, (x_offset, 24)) except: pass except: pass image_list.append(stitchedStock) try: if all_crypto_settings['chart'] and (cb in portfolio_settings): try: image_list.append(img) except: pass except: pass image_list.append(self.blank) except Exception as e: pass finalDisplayImage = self.stitchImage(image_list) return finalDisplayImage def getCryptoProfessional(self): self.blank = Image.new('RGB', (0, 16)) f = open('csv/crypto_settings.json', 'r') all_crypto_settings = json.load(f) f.close() if all_crypto_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/crypto.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] if all_crypto_settings['chart']: try: f = open('csv/portfolio_crypto_settings.json', 'r') portfolio_settings = json.load(f)['symbols'] f.close() except: pass coin_info = all_crypto_settings['symbols'] coin_bases = list(coin_info.keys()) for i, cb in enumerate(coin_bases): try: ticker, base = cb.split(',') current = float(coin_info[cb]["current"]) current_final = '{0:.10f}'.format(current).rstrip("0") change = float(coin_info[cb]["24hr_change"]) change2 = abs(change) changefinal = '{0:.10f}'.format(change2).rstrip("0") arrow, change = self.getArrow(change, professional=True) if all_crypto_settings["percent"]: # convert percent to points change = '%.2f' % abs(float(coin_info[cb]['percent_change'])) + '%' else: change = str(changefinal) current = str(current_final) midFrame = self.textToImageProf(ticker + '(' + base + ')', current, change, arrow, font=ImageFont.load("./fonts/6x10.pil")) #IMAGE THE TEXT if all_crypto_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'crypto') logo = self.openImage(os.path.join(logos_path, ticker + '.png')) w,h = logo.size logo=logo.resize((int(w/2), int(h/2))) stitchedStock = self.stitchImage([logo,midFrame]) except: stitchedStock = midFrame else: stitchedStock = midFrame try: if all_crypto_settings['chart'] and (cb in portfolio_settings): #IF USER INPUTTED PORTFOLIO SETTINGS, DISPLAY PORTFOLIO INFO try: cost = portfolio_settings[cb]['cost'] day = portfolio_settings[cb]['day'] shares = portfolio_settings[cb]['shares'] original_value = float(cost) * float(shares) new_value = float(coin_info[cb]['current']) * float(shares) value_day_change_percent = ((float(coin_info[cb]['percent_change'])/100) * new_value) font = ImageFont.load("./fonts/5x8.pil") cost_img = self.textImage('Cost', font, r = 255, g = 255 , b = 255) cost2_img = self.textImage(cost, font, r = 0, g = 255, b = 0) shares_img = self.textImage('Shares', font, r = 255, g = 255 , b = 255) shares2_img = self.textImage(shares, font, r = 0, g = 255, b = 0) pnlchange = new_value - original_value pnlpercent = ((new_value - original_value) / original_value) * 100 pnlpercent_img = self.textImage('P/L%', font, r = 255, g = 255 , b = 255) if pnlpercent >= 0: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 0, g = 255, b = 0) else: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 255, g = 0, b = 0) daypercent_img = self.textImage('Day%', font, r = 255, g = 255 , b = 255) if float(coin_info[cb]['percent_change']) >= 0: daypercent2_img = self.textImage(str('%.2f' % abs(float(coin_info[cb]['percent_change']))) +'%', font, r = 0, g = 255, b = 0) else: daypercent2_img = self.textImage(str('%.2f' % abs(float(coin_info[cb]['percent_change'])))+'%', font, r = 255, g = 0, b = 0) days_img = self.textImage('Days', font, r = 255, g = 255 , b = 255) days2_img = self.textImage(day, font, r = 0, g = 255, b = 0) value_img = self.textImage('Value', font, r = 255, g = 255 , b = 255) value2_img = self.textImage(str('%.2f' % abs(original_value)), font, r = 0, g = 255, b = 0) pnlchange_img = self.textImage('P/L$', font, r = 255, g = 255 , b = 255) if pnlchange >= 0: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 0, g = 255, b = 0) else: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 255, g = 0, b = 0) daychange_img = self.textImage('Day$', font, r = 255, g = 255 , b = 255) if value_day_change_percent >= 0: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 0, g = 255, b = 0) else: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 255, g = 0, b = 0) x_offset = 0 img = Image.new('RGB', (max(cost_img.size[0], cost2_img.size[0]) + 5 + max(days_img.size[0], days2_img.size[0]) + 5 + max(shares_img.size[0], shares2_img.size[0]) + 5 + max(value2_img.size[0], value_img.size[0]) + 5 + max(pnlpercent_img.size[0], pnlpercent2_img.size[0]) + 5 + max(pnlchange_img.size[0], pnlchange2_img.size[0]) + 5 + max(daypercent_img.size[0], daypercent2_img.size[0]) + 5 + max(daychange_img.size[0], daychange2_img.size[0]) + 10,16)) img.paste(cost_img, (x_offset, 1)) img.paste(cost2_img, (x_offset, 9)) x_offset += max(cost_img.size[0], cost2_img.size[0]) + 4 img.paste(days_img, (x_offset, 1)) img.paste(days2_img, (x_offset, 9)) x_offset += max(days_img.size[0], days2_img.size[0]) + 4 img.paste(shares_img, (x_offset, 1)) img.paste(shares2_img, (x_offset, 9)) x_offset += max(shares_img.size[0], shares2_img.size[0]) + 4 img.paste(value_img, (x_offset, 1)) img.paste(value2_img, (x_offset, 9)) x_offset += max(value2_img.size[0], value_img.size[0]) + 4 img.paste(pnlpercent_img, (x_offset, 1)) img.paste(pnlpercent2_img, (x_offset, 9)) x_offset += max(pnlpercent_img.size[0], pnlpercent2_img.size[0]) + 4 img.paste(pnlchange_img, (x_offset, 1)) img.paste(pnlchange2_img, (x_offset, 9)) x_offset += max(pnlchange_img.size[0], pnlchange2_img.size[0]) + 4 img.paste(daypercent_img, (x_offset, 1)) img.paste(daypercent2_img, (x_offset, 9)) x_offset += max(daypercent_img.size[0], daypercent2_img.size[0]) + 4 img.paste(daychange_img, (x_offset,1)) img.paste(daychange2_img, (x_offset, 9)) except: pass except: pass image_list.append(stitchedStock) try: if all_crypto_settings['chart'] and (cb in portfolio_settings): try: image_list.append(img) except: pass except: pass image_list.append(self.blank) except Exception as e: pass finalDisplayImage = self.stitchImage(image_list) self.blank = Image.new('RGB', (10, 32)) return finalDisplayImage def getIndicesImage(self): f = open('csv/indices_settings.json', 'r') all_indices_settings = json.load(f) f.close() if all_indices_settings['title']: title_img = self.openImage('feature_titles/indices.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] index_info = all_indices_settings['symbols'] symbols = list(index_info.keys()) for i, symbol in enumerate(symbols): try: info = index_info[symbol] change = float(info['point_change']) #TEXT symb = symbol ticker = info['name'] #TEXT arrow, change = self.getArrow(change) point_change = '%.2f' % abs(change) percent_change = '%.2f' % abs(float(info['percent_change'])) + '%' # point_change2 = abs(change) # point_changefinal = '{0:.10f}'.format(point_change2).rstrip("0") # point_change = str(point_changefinal) current = '%.2f' % float(info['current']) # current_final = '{0:.10f}'.format(current).rstrip("0") # current = str(current_final) if not all_indices_settings['percent']: percent_change = False if not all_indices_settings['point']: point_change = False midFrame = self.textToImage(ticker, current, arrow, percent_change, point_change) #IMAGE THE TEXT if all_indices_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'indices') logo = self.openImage(os.path.join(logos_path, symb + '.png')) stitchedIndex = self.stitchImage([logo,midFrame]) except Exception as e: stitchedIndex = midFrame else: stitchedIndex = midFrame image_list.append(stitchedIndex) image_list.append(self.blank) except Exception as e: pass finalDisplayImage = self.stitchImage(image_list) return finalDisplayImage def getIndicesProfessional(self): self.blank = Image.new('RGB', (0, 16)) f = open('csv/indices_settings.json', 'r') all_indices_settings = json.load(f) f.close() if all_indices_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/indices.png') image_list = [title_img, Image.new('RGB', (5, 16))] image_list.append(self.blank) else: image_list = [] index_info = all_indices_settings['symbols'] symbols = list(index_info.keys()) for i, symbol in enumerate(symbols): try: info = index_info[symbol] change = float(info['point_change']) #TEXT symb = symbol ticker = info['name'] #TEXT arrow, change = self.getArrow(change, professional=True) if all_indices_settings["percent"]: change = '%.2f' % abs(float(info['percent_change'])) + '%' else: change = '%.2f' % abs(change) current = '%.2f' % float(info['current']) midFrame = self.textToImageProf(ticker, current, change, arrow, font=ImageFont.load("./fonts/6x10.pil")) #IMAGE THE TEXT if all_indices_settings['logos']: try: try: #load the tiny logo logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'tiny_indices') logo = Image.open(os.path.join(logos_path, ticker + '.png')) except: # load the big logo and scale it logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'indices') logo = Image.open(os.path.join(logos_path, symb + '.png')) # half the size of the logo width, height = logo.size logo = logo.resize((int(width/2), int(height/2))) stitchedIndex = self.stitchImage([logo,midFrame]) except Exception as e: stitchedIndex = midFrame else: stitchedIndex = midFrame image_list.append(stitchedIndex) image_list.append(self.blank) except Exception as e: pass finalDisplayImage = self.stitchImage(image_list) self.blank = Image.new('RGB', (10, 32)) return finalDisplayImage def getCommoditiesImage(self): f = open('csv/commodities_settings.json', 'r') all_commodities_settings = json.load(f) f.close() if all_commodities_settings['title']: title_img = self.openImage('feature_titles/commodities.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] commodity_info = all_commodities_settings['symbols'] symbols = list(commodity_info.keys()) for i, symbol in enumerate(symbols): try: info = commodity_info[symbol] change = float(info['24hr_change']) #TEXT ticker = symbol #TEXT unit = info['unit'] ticker = symbol + '(' + unit + ')' #TEXT arrow, change = self.getArrow(change) percent_change = '%.2f' % abs(float(info['percent_change'])) + '%' point_change2 = abs(change) point_changefinal = '{0:.10f}'.format(point_change2).rstrip("0") point_change = str(point_changefinal) current = float(info["current"]) current_final = '{0:.10f}'.format(current).rstrip("0") current = str(current_final) if not all_commodities_settings['percent']: percent_change = False if not all_commodities_settings['point']: point_change = False midFrame = self.textToImage(ticker, current, arrow, percent_change, point_change) #IMAGE THE TEXT if all_commodities_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'commodities') logo = self.openImage(os.path.join(logos_path, ticker + '.png')) stitchedCommodity = self.stitchImage([logo,midFrame]) except Exception as e: stitchedCommodity = midFrame else: stitchedCommodity = midFrame image_list.append(stitchedCommodity) image_list.append(self.blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() finalDisplayImage = self.stitchImage(image_list) return finalDisplayImage def getCommoditiesProfessional(self): self.blank = Image.new('RGB', (0, 16)) f = open('csv/commodities_settings.json', 'r') all_commodities_settings = json.load(f) f.close() if all_commodities_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/commodities.png') image_list = [title_img, Image.new('RGB', (5, 16))] image_list.append(self.blank) else: image_list = [] commodity_info = all_commodities_settings['symbols'] symbols = list(commodity_info.keys()) for i, symbol in enumerate(symbols): try: info = commodity_info[symbol] change = float(info['24hr_change']) #TEXT unit = info['unit'] ticker = symbol + '(' + unit + ')' #TEXT arrow, change = self.getArrow(change, professional=True) if all_commodities_settings["percent"]: change = '%.2f' % abs(float(info['percent_change'])) + '%' else: point_change2 = abs(change) point_changefinal = '{0:.10f}'.format(point_change2).rstrip("0") change = str(point_changefinal) current = float(info["current"]) current_final = '{0:.10f}'.format(current).rstrip("0") current = str(current_final) midFrame = self.textToImageProf(ticker, current, change, arrow, font=ImageFont.load("./fonts/6x10.pil")) #IMAGE THE TEXT if all_commodities_settings['logos']: try: try: #load the tiny logo logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'tiny_commodities') logo = Image.open(os.path.join(logos_path, ticker + '.png')) except: # load the big logo and scale it logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'commodities') logo = Image.open(os.path.join(logos_path, ticker + '.png')) # half the size of the logo width, height = logo.size logo = logo.resize((int(width/2), int(height/2))) stitchedCommodity = self.stitchImage([logo,midFrame]) except Exception as e: stitchedCommodity = midFrame else: stitchedCommodity = midFrame image_list.append(stitchedCommodity) image_list.append(self.blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() finalDisplayImage = self.stitchImage(image_list) self.blank = Image.new('RGB', (10, 32)) return finalDisplayImage def getForexImage(self): f = open('csv/forex_settings.json', 'r') all_forex_settings = json.load(f) f.close() if all_forex_settings['title']: title_img = self.openImage('feature_titles/forex.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] forex_settings = all_forex_settings['symbols'] symbol_bases = list(forex_settings.keys()) for i, sb in enumerate(symbol_bases): try: symbol, base = sb.split(',') current = float(forex_settings[sb]['current']) current_final = '{0:.10f}'.format(current).rstrip("0") change = float(forex_settings[sb]['24hr_change']) change2 = abs(change) changefinal = '{0:.10f}'.format(change2).rstrip("0") percent_change = '%.2f' % abs(float(forex_settings[sb]['percent_change'])) +'%' point_change = str(changefinal) if not all_forex_settings['percent']: percent_change = False if not all_forex_settings['point']: point_change = False arrow, change = self.getArrow(change) current = str(current_final) midFrame = self.textToImage(symbol+ '(' + base + ')', current, arrow, percent_change, point_change) #IMAGE THE TEXT if all_forex_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'currencies') logo = Image.open(os.path.join(logos_path, symbol.upper() + '.png')) bse = Image.open(os.path.join(logos_path, base.upper() + '.png')) new_im = Image.new('RGB', (32, 32)) new_im.paste(bse, (0,10), bse.convert('RGBA')) new_im.paste(logo, (10,0), logo.convert('RGBA')) stitchedStock = self.stitchImage([new_im, midFrame]) image_list.append(new_im) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() image_list.append(midFrame) image_list.append(self.blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() finalDisplayImage = self.stitchImage(image_list) return finalDisplayImage def getForexProfessional(self): self.blank = Image.new('RGB', (0, 16)) f = open('csv/forex_settings.json', 'r') all_forex_settings = json.load(f) f.close() if all_forex_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/forex.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] forex_settings = all_forex_settings['symbols'] symbol_bases = list(forex_settings.keys()) for i, sb in enumerate(symbol_bases): try: symbol, base = sb.split(',') current = float(forex_settings[sb]['current']) current_final = '{0:.10f}'.format(current).rstrip("0") change = float(forex_settings[sb]['24hr_change']) change2 = abs(change) changefinal = '{0:.10f}'.format(change2).rstrip("0") arrow, change = self.getArrow(change, professional = True) if all_forex_settings["percent"]: change = abs(float(forex_settings[sb]['percent_change'])) change = '%.2f' % change + '%' else: change = str(changefinal) current = str(current_final) midFrame = self.textToImageProf(symbol + '(' + base + ')', current, change, arrow, font = ImageFont.load("./fonts/6x10.pil")) #IMAGE THE TEXT if all_forex_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'currencies') logo = Image.open(os.path.join(logos_path, symbol.upper() + '.png')) bse = Image.open(os.path.join(logos_path, base.upper() + '.png')) new_im = Image.new('RGB', (32, 32)) new_im.paste(bse, (0,10), bse.convert('RGBA')) new_im.paste(logo, (10,0), logo.convert('RGBA')) width, height = new_im.size new_im = new_im.resize((int(width/2), int(height/2))) stitchedStock = self.stitchImage([new_im, midFrame]) image_list.append(new_im) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() image_list.append(midFrame) image_list.append(self.blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() finalDisplayImage = self.stitchImage(image_list) self.blank = Image.new('RGB', (10, 32)) return finalDisplayImage def getStockImage(self): f = open('csv/stocks_settings.json', 'r') all_stocks_settings = json.load(f) f.close() if all_stocks_settings['title']: title_img = self.openImage('feature_titles/stocks.png') image_list = [title_img] image_list.append(self.blank) else: image_list = [] if all_stocks_settings['chart']: try: f = open('csv/portfolio_settings.json', 'r') portfolio_settings = json.load(f)['symbols'] f.close() except: pass stock_info = all_stocks_settings['symbols'] symbols = list(stock_info.keys()) for i, symbol in enumerate(symbols): try: info = stock_info[symbol] change = float(info['change']) #TEXT ticker = symbol #TEXT arrow, change = self.getArrow(change) percent_change = '%.2f' % abs(float(info['percent_change'])) + '%' point_change = '%.2f' % abs(change) current = '%.2f' % float(info['current']) #TEXT if not all_stocks_settings['percent']: percent_change = False if not all_stocks_settings['point']: point_change = False midFrame = self.textToImage(ticker, current, arrow, percent_change, point_change) #IMAGE THE TEXT if all_stocks_settings['logos']: try: logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'stocks') logo = self.openImage(os.path.join(logos_path, ticker + '.png')) stitchedStock = self.stitchImage([logo,midFrame]) except Exception as e: stitchedStock = midFrame else: stitchedStock = midFrame try: if all_stocks_settings['chart'] and (symbol in portfolio_settings): #IF USER INPUTTED PORTFOLIO SETTINGS, DISPLAY PORTFOLIO INFO try: cost = portfolio_settings[symbol]['cost'] day = portfolio_settings[symbol]['day'] shares = portfolio_settings[symbol]['shares'] original_value = float(cost) * float(shares) new_value = float(info['current']) * float(shares) value_day_change_percent = ((float(info['percent_change'])/100) * new_value) font = ImageFont.load("./fonts/5x8.pil") cost_img = self.textImage('Cost', font, r = 255, g = 255 , b = 255) cost2_img = self.textImage(cost, font, r = 0, g = 255, b = 0) shares_img = self.textImage('Shares', font, r = 255, g = 255 , b = 255) shares2_img = self.textImage(shares, font, r = 0, g = 255, b = 0) pnlchange = new_value - original_value pnlpercent = ((new_value - original_value) / original_value) * 100 pnlpercent_img = self.textImage('P/L%', font, r = 255, g = 255 , b = 255) if pnlpercent >= 0: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 0, g = 255, b = 0) else: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 255, g = 0, b = 0) daypercent_img = self.textImage('Day%', font, r = 255, g = 255 , b = 255) if float(info['percent_change']) >= 0: daypercent2_img = self.textImage(str('%.2f' % abs(float(info['percent_change']))) +'%', font, r = 0, g = 255, b = 0) else: daypercent2_img = self.textImage(str('%.2f' % abs(float(info['percent_change'])))+'%', font, r = 255, g = 0, b = 0) days_img = self.textImage('Days', font, r = 255, g = 255 , b = 255) days2_img = self.textImage(day, font, r = 0, g = 255, b = 0) value_img = self.textImage('Value', font, r = 255, g = 255 , b = 255) value2_img = self.textImage(str('%.2f' % abs(original_value)), font, r = 0, g = 255, b = 0) pnlchange_img = self.textImage('P/L$', font, r = 255, g = 255 , b = 255) if pnlchange >= 0: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 0, g = 255, b = 0) else: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 255, g = 0, b = 0) daychange_img = self.textImage('Day$', font, r = 255, g = 255 , b = 255) if value_day_change_percent >= 0: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 0, g = 255, b = 0) else: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 255, g = 0, b = 0) x_offset = 0 img = Image.new('RGB', (max(cost_img.size[0], cost2_img.size[0], days_img.size[0], days2_img.size[0]) + 7 + max(shares_img.size[0], shares2_img.size[0], value2_img.size[0], value_img.size[0]) + 7 + max(pnlpercent_img.size[0], pnlpercent2_img.size[0], pnlchange_img.size[0], pnlchange2_img.size[0]) + 7 + max(daypercent_img.size[0], daypercent2_img.size[0], daychange_img.size[0], daychange2_img.size[0]) + 15, 32)) img.paste(cost_img, (x_offset, 0)) img.paste(cost2_img, (x_offset, 8)) img.paste(days_img, (x_offset, 16)) img.paste(days2_img, (x_offset, 24)) x_offset += max(cost_img.size[0], cost2_img.size[0], days_img.size[0], days2_img.size[0]) + 7 img.paste(shares_img, (x_offset, 0)) img.paste(shares2_img, (x_offset, 8)) img.paste(value_img, (x_offset, 16)) img.paste(value2_img, (x_offset, 24)) x_offset += max(shares_img.size[0], shares2_img.size[0], value2_img.size[0], value_img.size[0]) + 7 img.paste(pnlpercent_img, (x_offset, 0)) img.paste(pnlpercent2_img, (x_offset, 8)) img.paste(pnlchange_img, (x_offset, 16)) img.paste(pnlchange2_img, (x_offset, 24)) x_offset += max(pnlpercent_img.size[0], pnlpercent2_img.size[0], pnlchange_img.size[0], pnlchange2_img.size[0]) + 7 img.paste(daypercent_img, (x_offset, 0)) img.paste(daypercent2_img, (x_offset, 8)) img.paste(daychange_img, (x_offset,16)) img.paste(daychange2_img, (x_offset, 24)) except: pass except: pass image_list.append(stitchedStock) try: if all_stocks_settings['chart'] and (symbol in portfolio_settings): try: image_list.append(img) except: pass except: pass image_list.append(self.blank) except Exception as e: pass finalDisplayImage = self.stitchImage(image_list) return finalDisplayImage def getStockProfessional(self): self.blank = Image.new('RGB', (0, 16)) f = open('csv/stocks_settings.json', 'r') all_stocks_settings = json.load(f) f.close() if all_stocks_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/stocks.png') image_list = [title_img, Image.new('RGB', (5, 16))] image_list.append(self.blank) else: image_list = [] if all_stocks_settings['chart']: try: f = open('csv/portfolio_settings.json', 'r') portfolio_settings = json.load(f)['symbols'] f.close() except: pass stock_info = all_stocks_settings['symbols'] symbols = list(stock_info.keys()) for i, symbol in enumerate(symbols): try: info = stock_info[symbol] change = float(info['change'])#TEXT ticker = symbol #TEXT arrow, change = self.getArrow(change, professional=True) if all_stocks_settings["percent"]: change = '%.2f' % abs(float(info['percent_change'])) + '%' else: change = '%.2f' % abs(change) current = '%.2f' % float(info['current']) #TEXT midFrame = self.textToImageProf(ticker, current, change, arrow, font=ImageFont.load("./fonts/6x10.pil")) #IMAGE THE TEXT if all_stocks_settings['logos']: try: try: #load the tiny logo logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'tiny_stocks') logo = Image.open(os.path.join(logos_path, ticker + '.png')) except: # load the big logo and scale it logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'stocks') logo = Image.open(os.path.join(logos_path, ticker + '.png')) # half the size of the logo width, height = logo.size logo = logo.resize((int(width/2), int(height/2))) stitchedStock = self.stitchImage([logo,midFrame]) except Exception as e: stitchedStock = midFrame else: stitchedStock = midFrame try: if all_stocks_settings['chart'] and (symbol in portfolio_settings): #IF USER INPUTTED PORTFOLIO SETTINGS, DISPLAY PORTFOLIO INFO try: cost = portfolio_settings[symbol]['cost'] day = portfolio_settings[symbol]['day'] shares = portfolio_settings[symbol]['shares'] original_value = float(cost) * float(shares) new_value = float(info['current']) * float(shares) value_day_change_percent = ((float(info['percent_change'])/100) * new_value) font = ImageFont.load("./fonts/5x8.pil") cost_img = self.textImage('Cost', font, r = 255, g = 255 , b = 255) cost2_img = self.textImage(cost, font, r = 0, g = 255, b = 0) shares_img = self.textImage('Shares', font, r = 255, g = 255 , b = 255) shares2_img = self.textImage(shares, font, r = 0, g = 255, b = 0) pnlchange = new_value - original_value pnlpercent = ((new_value - original_value) / original_value) * 100 pnlpercent_img = self.textImage('P/L%', font, r = 255, g = 255 , b = 255) if pnlpercent >= 0: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 0, g = 255, b = 0) else: pnlpercent2_img = self.textImage(str('%.2f' % abs(pnlpercent)) + '%', font, r = 255, g = 0, b = 0) daypercent_img = self.textImage('Day%', font, r = 255, g = 255 , b = 255) if float(info['percent_change']) >= 0: daypercent2_img = self.textImage(str('%.2f' % abs(float(info['percent_change']))) +'%', font, r = 0, g = 255, b = 0) else: daypercent2_img = self.textImage(str('%.2f' % abs(float(info['percent_change'])))+'%', font, r = 255, g = 0, b = 0) days_img = self.textImage('Days', font, r = 255, g = 255 , b = 255) days2_img = self.textImage(day, font, r = 0, g = 255, b = 0) value_img = self.textImage('Value', font, r = 255, g = 255 , b = 255) value2_img = self.textImage(str('%.2f' % abs(original_value)), font, r = 0, g = 255, b = 0) pnlchange_img = self.textImage('P/L$', font, r = 255, g = 255 , b = 255) if pnlchange >= 0: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 0, g = 255, b = 0) else: pnlchange2_img = self.textImage(str('%.2f' % abs(pnlchange)), font, r = 255, g = 0, b = 0) daychange_img = self.textImage('Day$', font, r = 255, g = 255 , b = 255) if value_day_change_percent >= 0: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 0, g = 255, b = 0) else: daychange2_img = self.textImage(str('%.2f' % abs(value_day_change_percent)), font, r = 255, g = 0, b = 0) x_offset = 0 img = Image.new('RGB', (max(cost_img.size[0], cost2_img.size[0]) + 5 + max(days_img.size[0], days2_img.size[0]) + 5 + max(shares_img.size[0], shares2_img.size[0]) + 5 + max(value2_img.size[0], value_img.size[0]) + 5 + max(pnlpercent_img.size[0], pnlpercent2_img.size[0]) + 5 + max(pnlchange_img.size[0], pnlchange2_img.size[0]) + 5 + max(daypercent_img.size[0], daypercent2_img.size[0]) + 5 + max(daychange_img.size[0], daychange2_img.size[0]) + 10,16)) img.paste(cost_img, (x_offset, 1)) img.paste(cost2_img, (x_offset, 9)) x_offset += max(cost_img.size[0], cost2_img.size[0]) + 4 img.paste(days_img, (x_offset, 1)) img.paste(days2_img, (x_offset, 9)) x_offset += max(days_img.size[0], days2_img.size[0]) + 4 img.paste(shares_img, (x_offset, 1)) img.paste(shares2_img, (x_offset, 9)) x_offset += max(shares_img.size[0], shares2_img.size[0]) + 4 img.paste(value_img, (x_offset, 1)) img.paste(value2_img, (x_offset, 9)) x_offset += max(value2_img.size[0], value_img.size[0]) + 4 img.paste(pnlpercent_img, (x_offset, 1)) img.paste(pnlpercent2_img, (x_offset, 9)) x_offset += max(pnlpercent_img.size[0], pnlpercent2_img.size[0]) + 4 img.paste(pnlchange_img, (x_offset, 1)) img.paste(pnlchange2_img, (x_offset, 9)) x_offset += max(pnlchange_img.size[0], pnlchange2_img.size[0]) + 4 img.paste(daypercent_img, (x_offset, 1)) img.paste(daypercent2_img, (x_offset, 9)) x_offset += max(daypercent_img.size[0], daypercent2_img.size[0]) + 4 img.paste(daychange_img, (x_offset,1)) img.paste(daychange2_img, (x_offset, 9)) except: pass except: pass image_list.append(stitchedStock) try: if all_stocks_settings['chart'] and (symbol in portfolio_settings): try: image_list.append(img) except: pass except: pass image_list.append(self.blank) except Exception as e: pass finalDisplayImage = self.stitchImage(image_list) self.blank = Image.new('RGB', (10, 32)) return finalDisplayImage def getNewsImage(self): f = open('csv/news_settings.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/news.png') image_list = [title_img] else: image_list = [] headline_font = ImageFont.load("./fonts/6x13.pil") source_font = ImageFont.load("./fonts/6x13.pil") headline_info = all_settings['headlines'] headlines = [] source_date_times = [] source = [] for i, hi in enumerate(headline_info): try: headline, source, date_time = hi date, time = date_time.split('T') time = time[:-1] source_date_time = source + ': ' + date + ' ' + time headline = headline.replace("^", ",") headline = headline.replace("’", "'") headline = headline.replace("‘", "'") headline = headline.replace('“', '"') headline = headline.replace('”', '"') headline = headline.replace('—', '-') headline = headline.replace('–', '-') headline = ''.join([h for h in headline if ord(h) < 256]) lst = headline.rsplit('-', 1) #remove source name at end of headline headline = lst[0] headline_img = self.textImage(headline, headline_font, matrix_height = True) source_img = self.textImage(source_date_time, source_font, r=255, g=255, b=0, matrix_height = True) try: logo_name = source.lower().replace(' ', '-') logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'news_logos') logo = Image.open(os.path.join(logos_path, logo_name + '.png')) except Exception as e: logo_name = 'default' logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'news_logos') logo = Image.open(os.path.join(logos_path, logo_name + '.png')) img = Image.new('RGB', (headline_img.size[0], 32)) img.paste(headline_img, (2, 0)) img.paste(source_img, (2,16)) img= self.stitchImage([logo,img]) image_list.append(img) image_list.append(self.blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() news_image = self.stitchImage(image_list) return news_image def getNewsProfessional(self): f = open('csv/news_settings.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/news.png') image_list = [title_img] else: image_list = [] headline_font = ImageFont.load("./fonts/6x13.pil") source_font = ImageFont.load("./fonts/6x13.pil") headline_info = all_settings['headlines'] headlines = [] source_date_times = [] source = [] blank = Image.new('RGB', (0, 16)) for i, hi in enumerate(headline_info): try: headline, source, date_time = hi date, time = date_time.split('T') time = time[:-1] source_date_time = source + ': ' + date + ' ' + time headline = headline.replace("^", ",") headline = headline.replace("’", "'") headline = headline.replace("‘", "'") headline = headline.replace('“', '"') headline = headline.replace('”', '"') headline = headline.replace('—', '-') headline = headline.replace('–', '-') headline = ''.join([h for h in headline if ord(h) < 256]) lst = headline.rsplit('-', 1) #remove source name at end of headline headline = lst[0] headline_img = self.textImage(headline, headline_font, matrix_height = True) source_img = self.textImage(source_date_time+ ':', source_font, r=255, g=255, b=0, matrix_height = True) try: logo_name = source.lower().replace(' ', '-') logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'tiny_news') logo = Image.open(os.path.join(logos_path, logo_name + '.png')) except Exception as e: logo_name = 'default' logos_path = os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logos'), 'tiny_news') logo = Image.open(os.path.join(logos_path, logo_name + '.png')) width, height = logo.size #logo = logo.resize((int(width/2), int(height/2))) img = Image.new('RGB', (headline_img.size[0]+ source_img.size[0] + logo.size[0] +22, 32)) img.paste(headline_img, (source_img.size[0]+logo.size[0] + 10, 3)) img.paste(source_img, (logo.size[0]+2,3)) img.paste(logo, (0,0)) image_list.append(img) image_list.append(blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() news_image = self.stitchImage(image_list) return news_image def getLeagueImage(self, league=False, time = 'past'): if time in ['past', 'live']: filepath = 'csv/{}_games.json'.format(time) else: filepath = 'csv/upcoming_games.json' f = open(filepath, 'r') all_settings = json.load(f) f.close() title_img = self.openImage('feature_titles/sports_'+ time + '.png') if all_settings['title']: title_img = self.openImage('feature_titles/sports_{}.png'.format(time)) imgs = [title_img, self.blank] else: imgs = [] leagues_info = all_settings['leagues'] leagues = list(leagues_info.keys()) if time == 'live': for league in leagues: try: x_offset = 0 if league == 'NFL': f = open('csv/live_nfl.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['NFL'][0] elif league == 'NHL': f = open('csv/live_nhl.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['NHL'][0] elif league == 'NBA': f = open('csv/live_nba.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['NBA'][0] elif league == 'MLB': f = open('csv/live_mlb.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['MLB'][0] elif league == 'MLS': f = open('csv/live_mls.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['MLS'][0] elif league == 'PREMIERLEAGUE': f = open('csv/live_pl.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['PREMIERLEAGUE'][0] img = Image.new('RGB', (10000, 32)) try: league_logo = Image.open('logos/sports/league_logos/{}.png'.format(league)).convert('RGB') img.paste(league_logo, (x_offset,0)) x_offset += league_logo.size[0] +self.blank.size[0] except: pass slight_large_font = ImageFont.load("./fonts/9x15.pil") small_font = ImageFont.load("./fonts/5x7.pil") med_font = ImageFont.load("./fonts/7x14B.pil") large_font = ImageFont.load("./fonts/9x18B.pil") extra_small_font = ImageFont.load("./fonts/4x6.pil") try: sports_info = self.readSportsCSV(league) except: pass buff_size = 25 if all_settings['leagues'][league][2] == 'no_live' and all_settings['leagues'][league][3] == 'no_upcoming': no_match = self.textImage(('No live games').upper(), slight_large_font, r = 255, g = 255 , b = 255) img.paste(no_match, (x_offset,10)) x_offset += no_match.size[0] + buff_size elif all_settings['leagues'][league][3] != 'no_upcoming': next_match = self.textImage('Next game: ' + all_settings['leagues'][league][3], slight_large_font, r=255,g=255,b=255) img.paste(next_match, (x_offset,10)) x_offset += next_match.size[0] + buff_size else: for match in league_info: dateEvent = match['time'] date_timage = self.textImage(dateEvent, small_font, r=255, g=255, b=255) strHomeTeam = match['home_team'] strAwayTeam = match['away_team'] intHomeScore = str(match['home_score']) intAwayScore = str(match['away_score']) try: home_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strHomeTeam]['logo'])) except Exception as e: home_logo = self.textImage(strHomeTeam.replace(' ', '\n'), extra_small_font, r = 255, g = 255, b = 255) try: away_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strAwayTeam]['logo'])) except Exception as e: away_logo = self.textImage(strAwayTeam.replace(' ', '\n'), extra_small_font, r = 255, g = 255, b = 255) img.paste(away_logo, (x_offset,0)) x_offset += away_logo.size[0] + 4 score_image = self.textImage(intAwayScore + '-' + intHomeScore, large_font, h_buff = 5, r = 255, g = 255, b = 255) try: h_colour = mcolors.to_rgb(sports_info[strHomeTeam]['colour'].replace(' ', '')) except: pass try: a_colour = mcolors.to_rgb(sports_info[strAwayTeam]['colour'].replace(' ', '')) except: pass try: hc_timage = self.textImage(sports_info[strHomeTeam]['code'], small_font, r = int(h_colour[0]*255), g = int(h_colour[1]*255), b = int(h_colour[2]*255)) except Exception as e: hc_timage = self.textImage('.', extra_small_font, r = 255, g = 255, b = 255) try: ac_timage = self.textImage(sports_info[strAwayTeam]['code'], small_font, r = int(a_colour[0]*255), g = int(a_colour[1]*255), b = int(a_colour[2]*255)) except Exception as e: ac_timage = self.textImage('.', extra_small_font, r = 255, g = 255, b = 255) vs_timage = self.textImage('VS', extra_small_font, r = 255, g = 255, b = 255) vs_size = hc_timage.size[0] + ac_timage.size[0] + vs_timage.size[0] main_offset = x_offset + int(max(vs_size, date_timage.size[0], score_image.size[0])/2) img.paste(date_timage,(main_offset - int(date_timage.size[0]/2),0)) img.paste(vs_timage, (main_offset - int(vs_timage.size[0]/2),10)) img.paste(ac_timage, (main_offset - int(vs_timage.size[0]/2) - ac_timage.size[0], 9)) img.paste(score_image, (main_offset - int(score_image.size[0]/2), 15)) if match['isLive'] == 'post': if int(intHomeScore) < int(intAwayScore) or int(intHomeScore) == int(intAwayScore): ua_image = Image.new("RGB", (hc_timage.size[0] -2, 1)) ua_image1 = ImageDraw.Draw(ua_image) ua_image1.line((0,0,hc_timage.size[0]-2,0), fill="red", width = 0) img.paste(ua_image, (main_offset - int(vs_timage.size[0]/2)-ac_timage.size[0], ac_timage.size[1]+7)) img.paste(hc_timage, (main_offset + int(vs_timage.size[0]/2),9)) if match['isLive'] == 'post': if int(intHomeScore) > int(intAwayScore) or int(intHomeScore) == int(intAwayScore): u_image = Image.new("RGB", (ac_timage.size[0] -2, 1)) u_image1 = ImageDraw.Draw(u_image) u_image1.line((0,0,ac_timage.size[0]-2,0), fill="red", width = 0) img.paste(u_image, (main_offset + int(vs_timage.size[0]/2), hc_timage.size[1]+7)) x_offset = (main_offset + max(int(date_timage.size[0]/2), int(vs_timage.size[0]/2) + hc_timage.size[0], int(score_image.size[0]/2)) + 4) img.paste(home_logo, (x_offset,0)) x_offset += home_logo.size[0] + buff_size img = img.crop((0,0,x_offset,32)) imgs.append(img) except Exception as e: pass else: for league in leagues: try: x_offset = 0 if (league =='PGA') or (league == 'LPGA') or (league == 'PGA_EU') or (league == 'LIV') or (league == 'NASCAR') or (league == 'F1'): img = Image.new('RGB', (10000, 32)) else: img = Image.new('RGB', (10000, 32)) league_info = leagues_info[league] try: league_logo = Image.open('logos/sports/league_logos/{}.png'.format(league)).convert('RGB') if (league == 'PGA') or (league == 'LPGA') or (league == 'PGA_EU') or (league == 'LIV') or (league == 'NASCAR') or (league == 'F1'): x_offset += self.blank.size[0] else: img.paste(league_logo, (x_offset,0)) x_offset += league_logo.size[0] +self.blank.size[0] except: pass small_font = ImageFont.load("./fonts/5x7.pil") med_font = ImageFont.load("./fonts/7x14B.pil") large_font = ImageFont.load("./fonts/9x18B.pil") extra_small_font = ImageFont.load("./fonts/4x6.pil") try: sports_info = self.readSportsCSV(league) except: pass buff_size = 25 for match in league_info: dateEvent = match['date'].replace('-', '.') date_timage = self.textImage(dateEvent, small_font, r=255, g=255, b=255) if (league == 'PGA') or (league == 'LPGA') or (league == 'PGA_EU') or (league == 'LIV') or (league == 'NASCAR') or (league == 'F1'): event = match['event'] venue = match['venue'] city = match['city'] country = match['country'] season = match['season'] if (time != 'future') and (league != 'LIV'): golf_standings1 = match['golf_standings'][::2] golf_standings2 = match['golf_standings'][1::2] elif (time!= 'future') and (league == 'LIV'): golf_standings1 = match['golf_standings'][0][::2] golf_standings2 = match['golf_standings'][0][1::2] golf_standings1_teams = match['golf_standings'][1][::2] golf_standings2_teams = match['golf_standings'][1][1::2] img.paste(league_logo, (x_offset, 0)) x_offset += league_logo.size[0] + 2 if time == 'future': event_timage = self.textImage(event, med_font, r=255, g=255, b=0) venue_timage = self.textImage(venue, small_font, r=0, g=255, b=0) city_timage = self.textImage(city, small_font, r=255, g=255, b=255) country_timage = self.textImage(country, small_font, r=255, g=255, b=255) date1_timage = self.textImage('Date:', small_font, r=255, g=0, b=171) season1_timage = self.textImage('Season:', small_font, r=0, g=170, b=255) season_timage = self.textImage(season, small_font, r=255, g=255, b=255) #date img.paste(date1_timage, (x_offset + 2, 26)) img.paste(date_timage, (x_offset + date1_timage.size[0] + 3, 26)) #event img.paste(event_timage, (x_offset + 2, 0)) #venue img.paste(venue_timage,(x_offset + 2, 16)) #country img.paste(country_timage,(x_offset + event_timage.size[0] + 5,5)) #city img.paste(city_timage,(x_offset + 15 + venue_timage.size[0], 16)) #season img.paste(season1_timage,(x_offset + 2 + date1_timage.size[0] + date_timage.size[0] + 20,26)) img.paste(season_timage,(x_offset + 2 + date1_timage.size[0] + date_timage.size[0] + 20 + season1_timage.size[0],26)) x_offset += max(2 + event_timage.size[0] + country_timage.size[0] + 5, 2 + venue_timage.size[0] + city_timage.size[0] + 15, 2 + date1_timage.size[0] + date_timage.size[0] + 20 + season1_timage.size[0] + season_timage.size[0] + 3) x_offset += buff_size else: event_timage = self.textImage(event, med_font, r=255, g=255, b=0) venue_timage = self.textImage(venue, small_font, r=0, g=255, b=0) city_timage = self.textImage(city, small_font, r=255, g=255, b=255) country_timage = self.textImage(country, small_font, r=255, g=255, b=255) date1_timage = self.textImage('Date:', small_font, r=255, g=0, b=171) season1_timage = self.textImage('Season:', small_font, r=0, g=170, b=255) season_timage = self.textImage(season, small_font, r=255, g=255, b=255) #date img.paste(date1_timage, (x_offset + 2, 26)) img.paste(date_timage, (x_offset + date1_timage.size[0] + 3, 26)) #event img.paste(event_timage, (x_offset + 2, 0)) #venue img.paste(venue_timage,(x_offset + 2, 16)) #country img.paste(country_timage,(x_offset + event_timage.size[0] + 5,5)) #city img.paste(city_timage,(x_offset + 15 + venue_timage.size[0], 16)) #season img.paste(season1_timage,(x_offset + 2 + date1_timage.size[0] + date_timage.size[0] + 20,26)) img.paste(season_timage,(x_offset + 2 + date1_timage.size[0] + date_timage.size[0] + 20 + season1_timage.size[0],26)) x_offset += max(2 + event_timage.size[0] + country_timage.size[0] + 5, 2 + venue_timage.size[0] + city_timage.size[0] + 15, 2 + date1_timage.size[0] + date_timage.size[0] + 20 + season1_timage.size[0] + season_timage.size[0] + 3) x_offset2 = x_offset for each_player in golf_standings1: symbol1_timage = self.textImage('|', small_font, r=255, g=255, b=0) img.paste(symbol1_timage, (x_offset + 5, 7)) golf_standings1_timage = self.textImage(each_player, small_font, r=255, g=255, b=255) img.paste(golf_standings1_timage, (x_offset + symbol1_timage.size[0] + 7, 7)) x_offset += (golf_standings1_timage.size[0] + symbol1_timage.size[0] + 7) for each_player2 in golf_standings2: symbol2_timage = self.textImage('|', small_font, r=255, g=255, b=0) img.paste(symbol2_timage, (x_offset2 + 5, 20)) golf_standings2_timage = self.textImage(each_player2, small_font, r=255, g=255, b=255) img.paste(golf_standings2_timage, (x_offset2 + symbol2_timage.size[0] + 7, 20)) x_offset2 += (golf_standings2_timage.size[0] + symbol2_timage.size[0] + 7) if league == 'LIV': if x_offset >= x_offset2: x_offset += 10 x_offset2 = x_offset else: x_offset2 += 10 x_offset = x_offset2 for each_team in golf_standings1_teams: symbol1_timage = self.textImage('|', small_font, r=0, g=255, b=0) img.paste(symbol1_timage, (x_offset + 5, 7)) golf_standings1_timage = self.textImage(each_team, small_font, r=255, g=255, b=255) img.paste(golf_standings1_timage, (x_offset + symbol1_timage.size[0] + 7, 7)) x_offset += (golf_standings1_timage.size[0] + symbol1_timage.size[0] + 7) for each_team2 in golf_standings2_teams: symbol2_timage = self.textImage('|', small_font, r=0, g=255, b=0) img.paste(symbol2_timage, (x_offset2 + 5, 20)) golf_standings2_timage = self.textImage(each_team2, small_font, r=255, g=255, b=255) img.paste(golf_standings2_timage, (x_offset2 + symbol2_timage.size[0] + 7, 20)) x_offset2 += (golf_standings2_timage.size[0] + symbol2_timage.size[0] + 7) if x_offset >= x_offset2: x_offset += buff_size else: x_offset = x_offset2 x_offset += buff_size else: strHomeTeam = match['home_team'] strAwayTeam = match['away_team'] if time != 'future': intHomeScore = str(match['home_score']) intAwayScore = str(match['away_score']) try: home_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strHomeTeam]['logo'])) except Exception as e: home_logo = self.textImage(strHomeTeam.replace(' ', '\n'), extra_small_font, r = 255, g = 255, b = 255) try: away_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strAwayTeam]['logo'])) except Exception as e: away_logo = self.textImage(strAwayTeam.replace(' ', '\n'), extra_small_font, r = 255, g = 255, b = 255) img.paste(away_logo, (x_offset,0)) x_offset += away_logo.size[0] + 4 if time == 'future': #img.paste(date_timage, (x_offset+5, 0)) try: h_colour = mcolors.to_rgb(sports_info[strHomeTeam]['colour'].replace(' ', '')) except: pass try: a_colour = mcolors.to_rgb(sports_info[strAwayTeam]['colour'].replace(' ', '')) except: pass vs_timage = self.textImage('vs', med_font, r = 255, g = 255, b = 255, h_buff = 5) try: hc_timage = self.textImage(sports_info[strHomeTeam]['code'], med_font, r = int(h_colour[0]*255), g = int(h_colour[1]*255), b = int(h_colour[2]*255)) except Exception as e: hc_timage = self.textImage('.', extra_small_font, r = 255, g = 255, b = 255) try: ac_timage = self.textImage(sports_info[strAwayTeam]['code'], med_font, r = int(a_colour[0]*255), g = int(a_colour[1]*255), b = int(a_colour[2]*255)) except Exception as e: ac_timage = self.textImage('.', extra_small_font, r = 255, g = 255, b = 255) vs_size = vs_timage.size[0] + ac_timage.size[0] + hc_timage.size[0] main_offset = 5 + x_offset + int(max(vs_size, date_timage.size[0])/2) img.paste(date_timage, (main_offset - int(date_timage.size[0]/2), 0)) img.paste(vs_timage, (main_offset - int(vs_timage.size[0]/2),9)) img.paste(ac_timage, (main_offset - int(vs_timage.size[0]/2) - ac_timage.size[0], 9)) img.paste(hc_timage, (main_offset + int(vs_timage.size[0]/2),9)) x_offset = (main_offset + max(int(date_timage.size[0]/2), int(vs_timage.size[0]/2) + hc_timage.size[0]) + 6) else: score_image = self.textImage(intAwayScore + '-' + intHomeScore, large_font, h_buff = 5, r = 255, g = 255, b = 255) try: h_colour = mcolors.to_rgb(sports_info[strHomeTeam]['colour'].replace(' ', '')) except: pass try: a_colour = mcolors.to_rgb(sports_info[strAwayTeam]['colour'].replace(' ', '')) except: pass try: hc_timage = self.textImage(sports_info[strHomeTeam]['code'], small_font, r = int(h_colour[0]*255), g = int(h_colour[1]*255), b = int(h_colour[2]*255)) except Exception as e: hc_timage = self.textImage('.', extra_small_font, r = 255, g = 255, b = 255) try: ac_timage = self.textImage(sports_info[strAwayTeam]['code'], small_font, r = int(a_colour[0]*255), g = int(a_colour[1]*255), b = int(a_colour[2]*255)) except Exception as e: ac_timage = self.textImage('.', extra_small_font, r = 255, g = 255, b = 255) vs_timage = self.textImage('VS', extra_small_font, r = 255, g = 255, b = 255) vs_size = hc_timage.size[0] + ac_timage.size[0] + vs_timage.size[0] main_offset = x_offset + int(max(vs_size, date_timage.size[0], score_image.size[0])/2) img.paste(date_timage,(main_offset - int(date_timage.size[0]/2),0)) img.paste(vs_timage,(main_offset - int(vs_timage.size[0]/2),10)) img.paste(ac_timage, (main_offset - int(vs_timage.size[0]/2) - ac_timage.size[0], 9)) img.paste(score_image, (main_offset - int(score_image.size[0]/2), 15)) if int(intHomeScore) < int(intAwayScore) or int(intHomeScore) == int(intAwayScore): ua_image = Image.new("RGB", (ac_timage.size[0] -2, 1)) ua_image1 = ImageDraw.Draw(ua_image) ua_image1.line((0,0,ac_timage.size[0]-2,0), fill="red", width = 0) img.paste(ua_image, (main_offset - int(vs_timage.size[0]/2)-ac_timage.size[0], ac_timage.size[1]+7)) img.paste(hc_timage, (main_offset + int(vs_timage.size[0]/2),9)) if int(intHomeScore) > int(intAwayScore) or int(intHomeScore) == int(intAwayScore): u_image = Image.new("RGB", (hc_timage.size[0] -2, 1)) u_image1 = ImageDraw.Draw(u_image) u_image1.line((0,0,hc_timage.size[0]-2,0), fill="red", width = 0) img.paste(u_image, (main_offset + int(vs_timage.size[0]/2), hc_timage.size[1]+7)) x_offset = (main_offset + max(int(date_timage.size[0]/2), int(vs_timage.size[0]/2) + hc_timage.size[0], int(score_image.size[0]/2)) + 4) img.paste(home_logo, (x_offset,0)) x_offset += home_logo.size[0] x_offset += buff_size img = img.crop((0,0,x_offset ,32)) imgs.append(img) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() return self.stitchImage(imgs) def getLeagueTableImage(self, league = False): f = open('csv/league_tables.json', 'r') all_settings = json.load(f) f.close() leagues_info = all_settings['leagues'] leagues = list(leagues_info.keys()) if all_settings['title']: title_img = self.openImage('feature_titles/sports_team_stats.png') imgs = [title_img, self.blank] else: imgs = [] for league in leagues: try: x_offset = 0 img = Image.new('RGB', (10000, 32)) league_logo = Image.open('logos/sports/league_logos/{}.png'.format(league)).convert('RGB') img.paste(league_logo, (x_offset,0)) x_offset += league_logo.size[0] +self.blank.size[0] team_info = leagues_info[league] small_font = ImageFont.load("./fonts/5x7.pil") med_font = ImageFont.load("./fonts/8x13B.pil") large_font = ImageFont.load("./fonts/10x20.pil") #if league =='NHL': # read the NHl info from the csv, prem will need this as well sports_info = self.readSportsCSV(league) # gets colour and symbol info etc from csv buff_size = 20 for team in team_info: try: logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[team['name']]['logo'])) img.paste(logo, (x_offset, 0)) x_offset += logo.size[0] + 2 except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() name_timage = self.textImage(team['name'], med_font, r = 255, g = 255, b = 0) wins_timage = self.textImage('Wins:' + str(team['wins']), small_font, r = 0, g = 255, b = 0) loss_timage = self.textImage('Losses:' + str(team['loss']), small_font, r = 255, g = 0, b = 0) draw_timage = self.textImage('Draws:' + str(team['draw']), small_font, r = 0, g = 0, b = 255) #points_timage = self.textImage('Points:' + team['points'], small_font, r = 255, g = 255, b = 255) standing_timage = self.textImage('Standing:' + str(team['standing']), small_font, r = 255, g = 255, b = 255) img.paste(name_timage, (x_offset, -1)) img.paste(wins_timage, (x_offset, 12)) img.paste(loss_timage, (x_offset, 19)) img.paste(draw_timage, (x_offset, 26)) x_offset += max( wins_timage.size[0], loss_timage.size[0], draw_timage.size[0]) #img.paste(points_timage, (x_offset, 14)) img.paste(standing_timage, (x_offset, 22)) x_offset += standing_timage.size[0] if name_timage.size[0] > max( wins_timage.size[0], loss_timage.size[0], draw_timage.size[0]) + standing_timage.size[0]: x_offset += name_timage.size[0] - (max( wins_timage.size[0], loss_timage.size[0], draw_timage.size[0]) + standing_timage.size[0]) x_offset += buff_size img = img.crop((0,0,x_offset ,32)) imgs.append(img) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() return self.stitchImage(imgs) def getLeagueTableProfessional(self, league = False): f = open('csv/league_tables.json', 'r') all_settings = json.load(f) f.close() leagues_info = all_settings['leagues'] leagues = list(leagues_info.keys()) if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/sports_team_stats.png') imgs = [title_img, self.blank] else: imgs = [] for league in leagues: try: x_offset = 0 img = Image.new('RGB', (10000, 32)) league_logo = Image.open('logos/sports/league_logos/{}.png'.format(league)).convert('RGB') width, height = league_logo.size league_logo2 = league_logo.resize((int(width/2), int(height/2))) img.paste(league_logo2, (x_offset,0)) x_offset += (league_logo2.size[0]+5) team_info = leagues_info[league] font = ImageFont.load("./fonts/6x10.pil") sports_info = self.readSportsCSV(league) buff_size = 20 for team in team_info: name_timage = self.textImage(team['name'].upper(), font, r = 255, g = 255, b = 0) wins_timage = self.textImage('W:' + str(team['wins']), font, r = 0, g = 255, b = 0) loss_timage = self.textImage('L:' + str(team['loss']), font, r = 255, g = 0, b = 0) draw_timage = self.textImage('D:' + str(team['draw']), font, r = 0, g = 0, b = 255) standing_timage = self.textImage('#' + str(team['standing']), font, r = 255, g = 255, b = 255) img.paste(standing_timage, (x_offset, 3)) x_offset += (standing_timage.size[0]) try: logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[team['name']]['logo'])) width, height = logo.size logo2 = logo.resize((int(width/2), int(height/2))) img.paste(logo2, (x_offset, 0)) x_offset += (logo2.size[0] + 3) except Exception as e: pass img.paste(name_timage, (x_offset, 3)) x_offset += (name_timage.size[0] +2) img.paste(wins_timage, (x_offset, 3)) x_offset += (wins_timage.size[0] +2) img.paste(loss_timage, (x_offset, 3)) x_offset += (loss_timage.size[0] +2) img.paste(draw_timage, (x_offset, 3)) x_offset += (draw_timage.size[0]+10) # x_offset += max( wins_timage.size[0], loss_timage.size[0], draw_timage.size[0]) #img.paste(points_timage, (x_offset, 14)) # img.paste(standing_timage, (x_offset, 22)) # x_offset += standing_timage.size[0] # if name_timage.size[0] > max( wins_timage.size[0], loss_timage.size[0], draw_timage.size[0]) + standing_timage.size[0]: # x_offset += name_timage.size[0] - (max( wins_timage.size[0], loss_timage.size[0], draw_timage.size[0]) + standing_timage.size[0]) # x_offset += buff_size x_offset += 25 img1 = img.crop((0,0,x_offset ,16)) imgs.append(img1) except Exception as e: pass return self.stitchImage(imgs) def getLeagueProfessional(self, league=False, time = 'future'): if time in ['past', 'live']: filepath = 'csv/{}_games.json'.format(time) else: filepath = 'csv/upcoming_games.json' f = open(filepath, 'r') all_settings = json.load(f) f.close() title_img = self.openImage('feature_titles/sports_'+ time + '.png') imgs = [] if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/sports_{}.png'.format(time)) imgs = [title_img, self.blank] else: imgs = [] leagues_info = all_settings['leagues'] leagues = list(leagues_info.keys()) if time == 'live': for league in leagues: try: x_offset = 0 if league == 'NFL': f = open('csv/live_nfl.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['NFL'][0] elif league == 'NHL': f = open('csv/live_nhl.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['NHL'][0] elif league == 'NBA': f = open('csv/live_nba.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['NBA'][0] elif league == 'MLB': f = open('csv/live_mlb.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['MLB'][0] elif league == 'MLS': f = open('csv/live_mls.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['MLS'][0] elif league == 'PREMIERLEAGUE': f = open('csv/live_pl.json', 'r') all_settings = json.load(f) f.close() league_info = all_settings['leagues']['PREMIERLEAGUE'][0] img = Image.new('RGB', (10000, 32)) try: league_logo = Image.open('logos/sports/league_logos/{}.png'.format(league)).convert('RGB') width, height = league_logo.size league_logo2 = league_logo.resize((int(width/2), int(height/2))) img.paste(league_logo2, (x_offset,0)) x_offset += (league_logo2.size[0]+10) except: pass font = ImageFont.load("./fonts/6x10.pil") small_font = ImageFont.load("./fonts/4x6.pil") try: sports_info = self.readSportsCSV(league) except: pass buff_size = 20 if all_settings['leagues'][league][2] == 'no_live' and all_settings['leagues'][league][3] == 'no_upcoming': no_match = self.textImage(('No live games').upper(), font, r = 255, g = 255 , b = 255) img.paste(no_match, (x_offset,4)) x_offset += no_match.size[0] elif all_settings['leagues'][league][3] != 'no_upcoming': next_match = self.textImage('Next game: ' + all_settings['leagues'][league][3], font, r=255,g=255,b=255) img.paste(next_match, (x_offset,4)) x_offset += next_match.size[0] else: for match in league_info: dateEvent = match['time'] date_timage = self.textImage(dateEvent, small_font, r = 255, g = 255, b = 255) strHomeTeam = match['home_team'] strAwayTeam = match['away_team'] intHomeScore = str(match['home_score']) intAwayScore = str(match['away_score']) try: home_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strHomeTeam]['logo'])) width1, height1 = home_logo.size home_logo1 = home_logo.resize((int(width1/2), int(height1/2))) except Exception as e: home_logo1 = self.textImage(strHomeTeam, small_font, r = 255, g = 255, b = 255) try: away_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strAwayTeam]['logo'])) width2, height2 = away_logo.size away_logo1 = away_logo.resize((int(width2/2), int(height2/2))) except Exception as e: away_logo1 = self.textImage(strAwayTeam, small_font, r = 255, g = 255, b = 255) error = False img.paste(away_logo1, (x_offset,0)) x_offset += (away_logo1.size[0] + 2) score_image = self.textImage(intAwayScore + '-' + intHomeScore, font, h_buff = 5, r = 255, g = 255, b = 255) try: h_colour = mcolors.to_rgb(sports_info[strHomeTeam]['colour'].replace(' ', '')) except: pass try: a_colour = mcolors.to_rgb(sports_info[strAwayTeam]['colour'].replace(' ', '')) except: pass try: hc_timage = self.textImage(sports_info[strHomeTeam]['code'], font, r = int(h_colour[0]*255), g = int(h_colour[1]*255), b = int(h_colour[2]*255)) except: hc_timage = self.textImage('.', small_font, r = 255, g = 255, b = 255) error = True try: ac_timage = self.textImage(sports_info[strAwayTeam]['code'], font, r = int(a_colour[0]*255), g = int(a_colour[1]*255), b = int(a_colour[2]*255)) except: ac_timage = self.textImage('.', small_font, r = 255, g = 255, b = 255) error = True if date_timage.size[0] > (hc_timage.size[0] + 2 + score_image.size[0] + ac_timage.size[0]): x_offset10 = x_offset + int((date_timage.size[0]/2)-(score_image.size[0]/2)-ac_timage.size[0]) img.paste(date_timage,(x_offset, 0)) img.paste(score_image, (x_offset + int((date_timage.size[0]/2)-(score_image.size[0]/2)), 5)) x_offset += date_timage.size[0] img.paste(ac_timage,(x_offset10, 5)) if match['isLive'] == 'post': if int(intHomeScore) < int(intAwayScore) or int(intHomeScore) == int(intAwayScore): ua_image = Image.new("RGB", (ac_timage.size[0] -3, 1)) ua_image1 = ImageDraw.Draw(ua_image) ua_image1.line((0,0,ac_timage.size[0]-3,0), fill="red", width = 0) img.paste(ua_image, (x_offset10, ac_timage.size[1]+4)) x_offset10 += ac_timage.size[0] + score_image.size[0] img.paste(hc_timage,(x_offset10, 5)) if match['isLive'] == 'post': if int(intHomeScore) > int(intAwayScore) or int(intHomeScore) == int(intAwayScore): u_image = Image.new("RGB", (hc_timage.size[0] -3, 1)) u_image1 = ImageDraw.Draw(u_image) u_image1.line((0,0,hc_timage.size[0]-3,0), fill="red", width = 0) img.paste(u_image, (x_offset10, hc_timage.size[1]+4)) x_offset10 += hc_timage.size[0] if error: img.paste(home_logo1, (max(x_offset + date_timage.size[0], x_offset10),0)) x_offset += (home_logo1.size[0] + date_timage.size[0]) else: img.paste(home_logo1, (max(x_offset,x_offset10),0)) x_offset += home_logo1.size[0] else: x_offset_date = (x_offset + ac_timage.size[0] + int(score_image.size[0]/2) - int(date_timage.size[0]/2)) img.paste(date_timage, (x_offset_date,0)) #img.paste(date_timage, (x_offset+20+int((score_image.size[0] - date_timage.size[0])/2),0)) img.paste(ac_timage, (x_offset, 5)) if match['isLive'] == 'post': if int(intHomeScore) < int(intAwayScore) or int(intHomeScore) == int(intAwayScore): ua_image = Image.new("RGB", (ac_timage.size[0] -3, 1)) ua_image1 = ImageDraw.Draw(ua_image) ua_image1.line((0,0,ac_timage.size[0]-3,0), fill="red", width = 0) img.paste(ua_image, (x_offset, ac_timage.size[1]+4)) x_offset += ac_timage.size[0] img.paste(score_image, (x_offset, 5)) x_offset += score_image.size[0] img.paste(hc_timage, (x_offset, 5)) if match['isLive'] == 'post': if int(intHomeScore) > int(intAwayScore) or int(intHomeScore) == int(intAwayScore): u_image = Image.new("RGB", (hc_timage.size[0] -3, 1)) u_image1 = ImageDraw.Draw(u_image) u_image1.line((0,0,hc_timage.size[0]-3,0), fill="red", width = 0) img.paste(u_image, (x_offset, hc_timage.size[1]+4)) x_offset += hc_timage.size[0] x_offset_date += date_timage.size[0] if error: img.paste(home_logo1, (max(x_offset + date_timage.size[0], x_offset_date),0)) x_offset += (home_logo1.size[0] + date_timage.size[0]) else: img.paste(home_logo1, (max(x_offset,x_offset_date),0)) x_offset += home_logo1.size[0] x_offset += buff_size x_offset += 20 img = img.crop((0,0,x_offset ,16)) imgs.append(img) except: pass else: for league in leagues: try: x_offset = 0 img = Image.new('RGB', (10000, 32)) league_info = leagues_info[league] #league logo try: league_logo = Image.open('logos/sports/league_logos/{}.png'.format(league)).convert('RGB') width, height = league_logo.size league_logo2 = league_logo.resize((int(width/2), int(height/2))) if (league == 'PGA') or (league == 'LPGA') or (league == 'PGA_EU') or (league == 'LIV') or (league == 'NASCAR') or (league == 'F1'): x_offset += 10 else: img.paste(league_logo2, (x_offset,0)) x_offset += (league_logo2.size[0]+10) except: pass font = ImageFont.load("./fonts/6x10.pil") small_font = ImageFont.load("./fonts/4x6.pil") try: sports_info = self.readSportsCSV(league) except: pass buff_size = 20 for match in league_info: dateEvent = match['date'].replace('-', '.') date_timage = self.textImage(dateEvent, small_font, r = 255, g = 255, b = 255) if (league == 'PGA') or (league == 'LPGA') or (league == 'PGA_EU') or (league == 'LIV') or (league == 'NASCAR') or (league == 'F1'): event = match['event'] venue = match['venue'] city = match['city'] country = match['country'] season = match['season'] if (time != 'future') and (league != 'LIV'): golf_standings1 = match['golf_standings'][::2] golf_standings2 = match['golf_standings'][1::2] elif (time!= 'future') and (league == 'LIV'): golf_standings1 = match['golf_standings'][0][::2] golf_standings2 = match['golf_standings'][0][1::2] golf_standings1_teams = match['golf_standings'][1][::2] golf_standings2_teams = match['golf_standings'][1][1::2] img.paste(league_logo2, (x_offset, 0)) x_offset += league_logo2.size[0] + 5 if time == 'future': event_timage = self.textImage(event, small_font, r=255, g=255, b=0) venue_timage = self.textImage(venue, small_font, r=0, g=255, b=0) city_timage = self.textImage(city, small_font, r=255, g=255, b=255) country_timage = self.textImage(country, small_font, r=255, g=255, b=255) season1_timage = self.textImage('Season:', small_font, r=0, g=170, b=255) season_timage = self.textImage(season, small_font, r=255, g=255, b=255) date1_timage = self.textImage('Date:', small_font, r=255, g=0, b=171) #event img.paste(event_timage, (x_offset, 1)) #venue img.paste(venue_timage,(x_offset, 9)) x_offset += (max(event_timage.size[0], venue_timage.size[0]) + 5) #date img.paste(date1_timage, (x_offset, 1)) img.paste(date_timage, (x_offset + date1_timage.size[0] + 2, 1)) #city img.paste(city_timage,(x_offset, 9)) #country img.paste(country_timage,(x_offset + city_timage.size[0] + 7,9)) #season img.paste(season1_timage,(x_offset + date1_timage.size[0] + 2 + date_timage.size[0] + 5,1)) img.paste(season_timage,(x_offset + date1_timage.size[0] + 2 + date_timage.size[0] + season1_timage.size[0] + 5,1)) x_offset += max(date1_timage.size[0] + 2 + date_timage.size[0] + season1_timage.size[0] + 5 + season_timage.size[0], city_timage.size[0] + 7 + country_timage.size[0]) x_offset += (buff_size - 10) else: event_timage = self.textImage(event, small_font, r=255, g=255, b=0) venue_timage = self.textImage(venue, small_font, r=0, g=255, b=0) city_timage = self.textImage(city, small_font, r=255, g=255, b=255) country_timage = self.textImage(country, small_font, r=255, g=255, b=255) season1_timage = self.textImage('Season:', small_font, r=0, g=170, b=255) season_timage = self.textImage(season, small_font, r=255, g=255, b=255) date1_timage = self.textImage('Date:', small_font, r=255, g=0, b=171) #event img.paste(event_timage, (x_offset, 1)) #venue img.paste(venue_timage,(x_offset, 9)) x_offset += (max(event_timage.size[0], venue_timage.size[0]) + 5) #date img.paste(date1_timage, (x_offset, 1)) img.paste(date_timage, (x_offset + date1_timage.size[0] + 2, 1)) #city img.paste(city_timage,(x_offset, 9)) #country img.paste(country_timage,(x_offset + city_timage.size[0] + 7,9)) #season img.paste(season1_timage,(x_offset + date1_timage.size[0] + 2 + date_timage.size[0] + 5,1)) img.paste(season_timage,(x_offset + date1_timage.size[0] + 2 + date_timage.size[0] + season1_timage.size[0] + 5,1)) x_offset += max(date1_timage.size[0] + 2 + date_timage.size[0] + season1_timage.size[0] + 5 + season_timage.size[0], city_timage.size[0] + 7 + country_timage.size[0]) x_offset2 = x_offset for each_player in golf_standings1: symbol1_timage = self.textImage('|', small_font, r=255, g=255, b=0) img.paste(symbol1_timage, (x_offset + 5, 1)) golf_standings1_timage = self.textImage(each_player, small_font, r=255, g=255, b=255) img.paste(golf_standings1_timage, (x_offset + symbol1_timage.size[0] + 7, 1)) x_offset += (golf_standings1_timage.size[0] + symbol1_timage.size[0] + 7) for each_player2 in golf_standings2: symbol2_timage = self.textImage('|', small_font, r=255, g=255, b=0) img.paste(symbol2_timage, (x_offset2 + 5, 9)) golf_standings2_timage = self.textImage(each_player2, small_font, r=255, g=255, b=255) img.paste(golf_standings2_timage, (x_offset2 + symbol2_timage.size[0] + 7, 9)) x_offset2 += (golf_standings2_timage.size[0] + symbol2_timage.size[0] + 7) if league == 'LIV': if x_offset >= x_offset2: x_offset += 5 x_offset2 = x_offset else: x_offset2 += 5 x_offset = x_offset2 for each_team in golf_standings1_teams: symbol1_timage = self.textImage('|', small_font, r=0, g=255, b=0) img.paste(symbol1_timage, (x_offset + 5, 1)) golf_standings1_timage = self.textImage(each_team, small_font, r=255, g=255, b=255) img.paste(golf_standings1_timage, (x_offset + symbol1_timage.size[0] + 7, 1)) x_offset += (golf_standings1_timage.size[0] + symbol1_timage.size[0] + 7) for each_team2 in golf_standings2_teams: symbol2_timage = self.textImage('|', small_font, r=0, g=255, b=0) img.paste(symbol2_timage, (x_offset2 + 5, 9)) golf_standings2_timage = self.textImage(each_team2, small_font, r=255, g=255, b=255) img.paste(golf_standings2_timage, (x_offset2 + symbol2_timage.size[0] + 7, 9)) x_offset2 += (golf_standings2_timage.size[0] + symbol2_timage.size[0] + 7) if x_offset >= x_offset2: x_offset += (buff_size - 10) else: x_offset = x_offset2 x_offset += (buff_size - 10) else: strHomeTeam = match['home_team'] strAwayTeam = match['away_team'] if time != 'future': intHomeScore = str(match['home_score']) intAwayScore = str(match['away_score']) try: home_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strHomeTeam]['logo'])) width1, height1 = home_logo.size home_logo1 = home_logo.resize((int(width1/2), int(height1/2))) except Exception as e: home_logo1 = self.textImage(strHomeTeam, small_font, r = 255, g = 255, b = 255) try: away_logo = Image.open('logos/sports/{}/{}'.format(league, sports_info[strAwayTeam]['logo'])) width2, height2 = away_logo.size away_logo1 = away_logo.resize((int(width2/2), int(height2/2))) except Exception as e: away_logo1 = self.textImage(strAwayTeam, small_font, r = 255, g = 255, b = 255) error = False img.paste(away_logo1, (x_offset,0)) x_offset += (away_logo1.size[0] + 2) if time == 'future': try: h_colour = mcolors.to_rgb(sports_info[strHomeTeam]['colour'].replace(' ', '')) except: pass try: a_colour = mcolors.to_rgb(sports_info[strAwayTeam]['colour'].replace(' ', '')) except: pass try: hc_timage = self.textImage(sports_info[strHomeTeam]['code'], font, r = int(h_colour[0]*255), g = int(h_colour[1]*255), b = int(h_colour[2]*255)) except: hc_timage = self.textImage('.', small_font, r = 255, g = 255, b = 255) error = True try: ac_timage = self.textImage(sports_info[strAwayTeam]['code'], font, r = int(a_colour[0]*255), g = int(a_colour[1]*255), b = int(a_colour[2]*255)) except: ac_timage = self.textImage('.', small_font, r = 255, g = 255, b = 255) error = True vs_timage = self.textImage('vs', font, r = 255, g = 255, b = 255, h_buff = 5) x_offsetdate2 = x_offset + int((hc_timage.size[0] + vs_timage.size[0] + ac_timage.size[0])/2)- int(date_timage.size[0]/2) img.paste(date_timage, (x_offsetdate2,0)) x_offsetdate2 += date_timage.size[0] img.paste(ac_timage, (x_offset, 5)) x_offset += ac_timage.size[0] img.paste(vs_timage, (x_offset, 5)) x_offset += vs_timage.size[0] img.paste(hc_timage, (x_offset, 5)) x_offset += hc_timage.size[0] #x_offset += max(date_timage.size[0], (hc_timage.size[0] + vs_timage.size[0] + ac_timage.size[0])) else: score_image = self.textImage(intAwayScore + '-' + intHomeScore, font, h_buff = 5, r = 255, g = 255, b = 255) try: h_colour = mcolors.to_rgb(sports_info[strHomeTeam]['colour'].replace(' ', '')) except: pass try: a_colour = mcolors.to_rgb(sports_info[strAwayTeam]['colour'].replace(' ', '')) except: pass try: hc_timage = self.textImage(sports_info[strHomeTeam]['code'], font, r = int(h_colour[0]*255), g = int(h_colour[1]*255), b = int(h_colour[2]*255)) except: hc_timage = self.textImage('.', small_font, r = 255, g = 255, b = 255) error = True try: ac_timage = self.textImage(sports_info[strAwayTeam]['code'], font, r = int(a_colour[0]*255), g = int(a_colour[1]*255), b = int(a_colour[2]*255)) except: ac_timage = self.textImage('.', small_font, r = 255, g = 255, b = 255) error = True x_offsetdate2 = x_offset + ac_timage.size[0] + int(score_image.size[0]/2)- int(date_timage.size[0]/2) img.paste(date_timage, (x_offsetdate2,0)) x_offsetdate2 += date_timage.size[0] #img.paste(date_timage, (x_offset+20+int((score_image.size[0] - date_timage.size[0])/2),0)) img.paste(ac_timage, (x_offset, 5)) if int(intHomeScore) < int(intAwayScore) or int(intHomeScore) == int(intAwayScore): ua_image = Image.new("RGB", (ac_timage.size[0] -3, 1)) ua_image1 = ImageDraw.Draw(ua_image) ua_image1.line((0,0,ac_timage.size[0]-3,0), fill="red", width = 0) img.paste(ua_image, (x_offset, ac_timage.size[1]+4)) x_offset += ac_timage.size[0] img.paste(score_image, (x_offset, 5)) x_offset += score_image.size[0] img.paste(hc_timage, (x_offset, 5)) if int(intHomeScore) > int(intAwayScore) or int(intHomeScore) == int(intAwayScore): u_image = Image.new("RGB", (hc_timage.size[0] -3, 1)) u_image1 = ImageDraw.Draw(u_image) u_image1.line((0,0,hc_timage.size[0]-3,0), fill="red", width = 0) img.paste(u_image, (x_offset, hc_timage.size[1]+4)) x_offset += hc_timage.size[0] # if date_timage.size[0] > score_image.size[0]: # img.paste(date_timage, (x_offset+2, 0)) # img.paste(hc_timage, (x_offset+6, 5)) # img.paste(vs_timage, (x_offset+5 + hc_timage.size[0], 5)) # img.paste(ac_timage, (x_offset+6 + hc_timage.size[0] + vs_timage.size[0], 5)) # img.paste(score_image, (x_offset + 2 + int((date_timage.size[0] - score_image.size[0])/2), 5)) # else: # img.paste(date_timage, (x_offset+1+int((score_image.size[0] - date_timage.size[0] )/2), 0)) # vs_size = hc_timage.size[0] + vs_timage.size[0] + ac_timage.size[0] # img.paste(hc_timage, (x_offset + 1 + int((score_image.size[0] - vs_size)/2), 5)) # img.paste(vs_timage, (x_offset + int((score_image.size[0] - vs_size)/2) + hc_timage.size[0], 5)) # img.paste(ac_timage, (x_offset+1 + int((score_image.size[0] - vs_size)/2) + hc_timage.size[0] + vs_timage.size[0], 5)) # img.paste(score_image, (x_offset+1, 5)) # x_offset += max( date_timage.size[0]+4, hc_timage.size[0] + vs_timage.size[0] + ac_timage.size[0]+4, 2 + int(score_image.size[0])) if error: img.paste(home_logo1, (max(x_offset + date_timage.size[0], x_offsetdate2),0)) x_offset += (home_logo1.size[0] + date_timage.size[0]) else: img.paste(home_logo1, (max(x_offset, x_offsetdate2),0)) x_offset += home_logo1.size[0] x_offset += buff_size x_offset += 20 img = img.crop((0,0,x_offset ,16)) imgs.append(img) except: pass return self.stitchImage(imgs) def convertTemp(self,temp, setting): if setting == 'kelvin': temp = temp+ 273.15 elif setting == 'fahrenheit': temp = temp*9/5 + 32 return temp def getTodayWeatherImage(self): f = open('csv/current_weather.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/weather.png') imgs = [title_img, self.blank] else: imgs = [] current_weathers = all_settings['locations'] locations = list(current_weathers.keys()) for i, location in enumerate(locations): try: current_weather = current_weathers[location] small_font = ImageFont.load("./fonts/5x7.pil") large_font = ImageFont.load("./fonts/10x20.pil") location_img = self.textImage(location.upper(), small_font, r = 255, g = 255, b = 0) main = current_weather['main_weather'] if main == 'Clouds': main = current_weather['description'] if main == 'Rain': main = current_weather['description'] weather_ids = {'Clear': '01', 'few clouds': '02', 'scattered clouds': '03', 'broken clouds':'04', 'overcast clouds':'04', 'Drizzle':'09', 'Rain':'10', 'Thunderstorm':'11', 'Snow':'13', 'Mist': '50', 'Smoke': '50', 'Haze': '50', 'Dust': '50', 'Fog': '50', 'Sand': '50', 'Ash': '50', 'Squall': '50', 'Tornado': '50', 'light rain': '10', 'moderate rain': '10', 'heavy intensity rain': '10', 'very heavy rain': '10', 'extreme rain': '10', 'freezing rain': '13', 'light intensity shower rain': '09', 'shower rain': '09', 'heavy intensity shower rain': '09', 'ragged shower rain': '09'} weather_dir = './logos/weather_icons' weather_img = Image.open(weather_dir + '/weather_type_icons/' + weather_ids[main] + '.png') temp = self.convertTemp(current_weather['temp'], all_settings['temp']) feels_temp = self.convertTemp(current_weather['feels_like'], all_settings['temp']) temp_img = self.textImage(str("{0:.0f}".format(temp)), large_font) deg_img = self.textImage('o', small_font) main = current_weather['main_weather'] main_img = self.textImage(main.upper(), small_font) feels_img = self.textImage('Feels like:'.upper() + str("{0:.0f}".format(feels_temp)), small_font) min_img = self.textImage( "{0:.0f}".format(self.convertTemp(current_weather['min_temp'], all_settings['temp'])), small_font, r=0, g=0, b=255) max_img = self.textImage( "{0:.0f}".format(self.convertTemp(current_weather['max_temp'], all_settings['temp'])), small_font, r=255, g=0, b=0) hum_img = Image.open(weather_dir + '/humidity.png') htext_img = self.textImage(str(current_weather['humidity']) + '%', small_font) uv_img = Image.open(weather_dir + '/uv.png') utext_img = self.textImage(str(round(current_weather['uv'], 1)) , small_font) 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(), small_font) rain_img = Image.open(weather_dir + '/rain-chance.png') rtext_img = self.textImage(str(int(current_weather['rain_chance']*100)) + '%', small_font) cloud_img = Image.open(weather_dir + '/clouds.png') ctext_img = self.textImage(str(current_weather['clouds']) + '%', small_font) wind_img = Image.open(weather_dir + '/wind.png') w_speed = current_weather['wind_speed']*3.6 w_unit = 'K/H' if all_settings["wind_speed"] == "miles/hour": w_speed = current_weather['wind_speed']*2.236936 w_unit = 'M/H' wtext_img = self.textImage("{0:.0f}".format(w_speed) + w_unit, small_font) wdir_img = self.textImage(self.degreesToCompass(current_weather['wind_direction']).upper(), small_font) vis_img = Image.open(weather_dir + '/visibility.png') vtext_img = self.textImage(str(round(current_weather['visibility']/1000, 1)) + 'km'.upper(), small_font) '------------------------------------------' img = Image.new('RGB', (1000, 32)) img.paste(weather_img, (5,9)) x_offset = 5 + weather_img.size[0] + 1 img.paste(main_img, (x_offset, 26)) img.paste(temp_img, (x_offset + main_img.size[0]//2 - temp_img.size[0]//2,9)) img.paste(deg_img, (x_offset + main_img.size[0]//2 - temp_img.size[0]//2 + temp_img.size[0], 8)) x_offset += max( main_img.size[0], temp_img.size[0] + deg_img.size[0]) img.paste(min_img, (x_offset - 0, 12)) img.paste(max_img, (x_offset - 0, 21)) x_offset += max(min_img.size[0], max_img.size[0]) + 2 img.paste(hum_img, ( x_offset - 1, 8)) img.paste(uv_img, ( x_offset - 1, 22)) img.paste(htext_img, (x_offset + hum_img.size[0], 10)) img.paste(utext_img, (x_offset + uv_img.size[0], 23)) x_offset += max(hum_img.size[0], uv_img.size[0]+2) x_offset += max(htext_img.size[0], utext_img.size[0]) + 6 img.paste(rain_img, (x_offset,8)) img.paste(cloud_img, (x_offset,20)) img.paste(ctext_img, (x_offset + cloud_img.size[0] + 2, 22)) img.paste(rtext_img, (x_offset + rain_img.size[0]+ 2, 10)) x_offset += max(cloud_img.size[0], rain_img.size[0])+6 x_offset += max(ctext_img.size[0], rtext_img.size[0])+6 img.paste(wind_img, (x_offset,8)) img.paste(vis_img, (x_offset,20)) img.paste(wtext_img, (x_offset + wind_img.size[0] + 2, 10)) img.paste(vtext_img, (x_offset + vis_img.size[0] + 2, 22)) x_offset += wind_img.size[0] + wtext_img.size[0] + 4 img.paste(wdir_img, (x_offset, 10)) img.paste(location_img, (5,0)) img.paste(feels_img, (location_img.size[0] + 10, 0)) img.paste(date_img, (location_img.size[0] + feels_img.size[0] + 15, 0)) img = img.crop((0,0,max(x_offset +wdir_img.size[0] + 4, location_img.size[0] + feels_img.size[0] + 15 + date_img.size[0]) ,32)) imgs.append(img) imgs.append(self.blank) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() return self.stitchImage(imgs) def getTodayWeatherProfessional(self): f = open('csv/current_weather.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/weather.png') image_list = [title_img, Image.new('RGB', (3, 16))] else: image_list = [] current_weathers = all_settings['locations'] locations = list(current_weathers.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: img = Image.new('RGB', (1000, 32)) current_weather = current_weathers[location] small_font = ImageFont.load("./fonts/4x6.pil") font = ImageFont.load("./fonts/6x10.pil") large_font = ImageFont.load("./fonts/10x20.pil") main = current_weather['main_weather'] if main == 'Clouds': main = current_weather['description'] if main == 'Rain': main = current_weather['description'] weather_ids = {'Clear': '01', 'few clouds': '02', 'scattered clouds': '03', 'broken clouds':'04', 'overcast clouds':'04', 'Drizzle':'09', 'Rain':'10', 'Thunderstorm':'11', 'Snow':'13', 'Mist': '50', 'Smoke': '50', 'Haze': '50', 'Dust': '50', 'Fog': '50', 'Sand': '50', 'Ash': '50', 'Squall': '50', 'Tornado': '50', 'light rain': '10', 'moderate rain': '10', 'heavy intensity rain': '10', 'very heavy rain': '10', 'extreme rain': '10', 'freezing rain': '13', 'light intensity shower rain': '09', 'shower rain': '09', 'heavy intensity shower rain': '09', 'ragged shower rain': '09'} weather_dir = './logos/weather_icons' location_img = self.textImage(location.upper(), font, r = 255, g = 255, b = 0) img.paste(location_img, (5,3)) x_offset = location_img.size[0] + 8 date_img = self.textImage((month + ' ' + date + ',' + weekday).upper(), font) img.paste(date_img, (x_offset, 3)) x_offset += date_img.size[0] + 2 weather_img = Image.open(weather_dir + '/small_icons/' + weather_ids[main] + '.png') w, h = weather_img.size #weather_img = weather_img.resize((int(w/2), int(h/2))) main = current_weather['main_weather'] main_img = self.textImage(main.upper(), font) img.paste(main_img, (x_offset, 3)) x_offset += main_img.size[0] + 2 img.paste(weather_img, (x_offset,3)) x_offset += weather_img.size[0] + 2 temp = self.convertTemp(current_weather['temp'], all_settings['temp']) temp_img = self.textImage(str("{0:.0f}".format(temp)), font) img.paste(temp_img, (x_offset,3)) x_offset += temp_img.size[0]-3 deg_img = self.textImage('o', small_font) img.paste(deg_img, (x_offset+1, 1)) x_offset += deg_img.size[0] -2 min_img = self.textImage( "{0:.0f}".format(self.convertTemp(current_weather['min_temp'], all_settings['temp'])), small_font, r=0, g=0, b=255) img.paste(min_img, (x_offset+2, 2)) max_img = self.textImage( "{0:.0f}".format(self.convertTemp(current_weather['max_temp'], all_settings['temp'])), small_font, r=255, g=0, b=0) img.paste(max_img, (x_offset+2, 8)) x_offset += max_img.size[0] + 2 hum_img = Image.open(weather_dir + '/humidity.png') htext_img = self.textImage(str(current_weather['humidity']) + '%', font) uv_img = Image.open(weather_dir + '/uv.png') utext_img = self.textImage(str(round(current_weather['uv'], 1)), font) rain_img = Image.open(weather_dir + '/rain-chance.png') rtext_img = self.textImage(str(int(current_weather['rain_chance']*100)) + '%', font) cloud_img = Image.open(weather_dir + '/clouds.png') ctext_img = self.textImage(str(current_weather['clouds']) + '%', font) wind_img = Image.open(weather_dir + '/wind.png') w_speed = current_weather['wind_speed']*3.6 w_unit = 'K/H' if all_settings["wind_speed"] == "miles/hour": w_speed = current_weather['wind_speed']*2.236936 w_unit = 'M/H' wtext_img = self.textImage("{0:.0f}".format(w_speed) + w_unit, font) wdir_img = self.textImage(self.degreesToCompass(current_weather['wind_direction']).upper(), font) vis_img = Image.open(weather_dir + '/visibility.png') vtext_img = self.textImage(str(current_weather['visibility']/1000) + 'km', font) for image in [hum_img, htext_img, uv_img, utext_img, rain_img, rtext_img, cloud_img, ctext_img, wind_img, wtext_img, wdir_img, vis_img, vtext_img]: img.paste(image, (x_offset, 3)) x_offset += image.size[0] + 2 img = img.crop((0,0,x_offset +image.size[0] ,16)) image_list.append(img) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() return self.stitchImage(image_list) def getDailyWeatherImageAlt(self): f = open( "csv/weather_location.txt", 'r' ) location = f.read() f.close() img = Image.new('RGB', (128, 32)) current_weather = json.load(open('csv/current_weather.json', 'r')) small_font = ImageFont.load("./fonts/5x7.pil") extra_small_font = ImageFont.load("./fonts/4x6.pil") large_font = ImageFont.load("./fonts/10x20.pil") location_img = self.textImage(location, extra_small_font, r = 255, g = 255, b = 0) main = current_weather['main_weather'] if main == 'Clouds': main = current_weather['description'] weather_ids = {'Clear': '01', 'few clouds': '02', 'scattered clouds': '03', 'broken clouds':'04', 'overcast clouds':'04', 'Drizzle':'09', 'Rain':'10', 'Thunderstorm':'11', 'Snow':'13', 'Mist': '50', 'Smoke': '50', 'Haze': '50', 'Dust': '50', 'Fog': '50', 'Sand': '50', 'Ash': '50', 'Squall': '50', 'Tornado': '50'} weather_dir = './logos/weather_icons' weather_img = Image.open(weather_dir + '/weather_type_icons/' + weather_ids[main] + '.png') temp_img = self.textImage(str("{0:.0f}".format(current_weather['temp'])), large_font) deg_img = self.textImage('o', small_font) min_img = self.textImage( "{0:.0f}".format(current_weather['min_temp']), small_font, r=0, g=0, b=255) max_img = self.textImage( "{0:.0f}".format(current_weather['max_temp']), small_font, r=255, g=0, b=0) main = current_weather['main_weather'] main_img = self.textImage(main, small_font) 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'))] date = str(int(datetime.now().strftime('%d'))) weekday = weekdays[datetime.today().weekday()] date_img = self.textImage(month + ' ' + date + ',' + weekday, extra_small_font) rain_img = Image.open(weather_dir + '/rain-chance.png') rtext_img = self.textImage(str(int(current_weather['rain_chance']*100)) + '%', extra_small_font) hum_img = Image.open(weather_dir + '/humidity.png') htext_img = self.textImage(str(current_weather['humidity']) + '%', extra_small_font) uv_img = Image.open(weather_dir + '/uv.png') utext_img = self.textImage(str(current_weather['uv']) , extra_small_font) wind_img = Image.open(weather_dir + '/wind.png') wtext_img = self.textImage(str(current_weather['wind_speed']) + 'm/s', extra_small_font) img.paste(location_img, (0,0)) img.paste(weather_img, (0,12)) img.paste(temp_img, (30,9)) img.paste(deg_img, (50, 8)) img.paste(min_img, (55, 10)) img.paste(main_img, (30, 26)) img.paste(max_img, (55, 19)) img.paste(date_img, (location_img.size[0], 1)) img.paste(rain_img, (75,0)) img.paste(rtext_img, (88, 1)) img.paste(hum_img, (102, 0)) img.paste(htext_img, (113, 1)) #img.paste(uv_img, ( 96, 0)) #img.paste(utext_img, (109, 0)) #img.paste(wind_img, (96,0)) #img.paste(wtext_img, (109,0)) img0 = img img = Image.new('RGB', (1000, 32)) daily_weather = json.load(open('csv/daily_weather.json', 'r')) #img.paste(date_img, (70, 0)) x_offset = 64 for i in range(0,len(daily_weather)-1): weekday = weekdays[(datetime.today().weekday() + i)%7] day_img = self.textImage( weekday, small_font) weather = daily_weather[i] main = weather['main_weather'] if main == 'Clouds': main = weather['description'] weather_img = Image.open(weather_dir + '/small_icons/' + weather_ids[main] + '.png') min_img = self.textImage( "{0:.0f}".format(weather['min_temp']), small_font, r=0, g=0, b=255) max_img = self.textImage( "{0:.0f}".format(weather['max_temp']), small_font, r=255, g=0, b=0) img.paste(day_img, (x_offset +5, 9)) img.paste(weather_img, (x_offset +5, 16)) img.paste(min_img, (x_offset + 25, 10)) img.paste(max_img, (x_offset + 25, 20)) x_offset += 35 img1 = img.crop((64,0,x_offset ,32)) img1.save('display_images/weather.ppm') return img0, img1 def getDailyWeatherImage(self): f = open('csv/daily_weather.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/forecast.png') imgs = [title_img, self.blank] else: imgs = [] f = open('csv/daily_weather.json', 'r') daily_weathers = json.load(f) f.close() locations = list(daily_weathers['locations'].keys()) for i, location in enumerate(locations): try: img = Image.new('RGB', (1000, 32)) daily_weather = daily_weathers['locations'][location] small_font = ImageFont.load("./fonts/5x7.pil") extra_small_font = ImageFont.load("./fonts/4x6.pil") large_font = ImageFont.load("./fonts/10x20.pil") location_img = self.textImage(location.upper(), extra_small_font, r = 255, g = 255, b = 0) main = daily_weather[0]['main_weather'] if main == 'Clouds': main = daily_weather[0]['description'] if main == 'Rain': main = daily_weather[0]['description'] weather_ids = {'Clear': '01', 'few clouds': '02', 'scattered clouds': '03', 'broken clouds':'04', 'overcast clouds':'04', 'Drizzle':'09', 'Rain':'10', 'Thunderstorm':'11', 'Snow':'13', 'Mist': '50', 'Smoke': '50', 'Haze': '50', 'Dust': '50', 'Fog': '50', 'Sand': '50', 'Ash': '50', 'Squall': '50', 'Tornado': '50', 'light rain': '10', 'moderate rain': '10', 'heavy intensity rain': '10', 'very heavy rain': '10', 'extreme rain': '10', 'freezing rain': '13', 'light intensity shower rain': '09', 'shower rain': '09', 'heavy intensity shower rain': '09', 'ragged shower rain': '09'} weather_dir = './logos/weather_icons' weather_img = Image.open(weather_dir + '/weather_type_icons/' + weather_ids[main] + '.png') temp = self.convertTemp(daily_weather[0]['temp'], daily_weathers['temp']) min_temp = self.convertTemp(daily_weather[0]['min_temp'], daily_weathers['temp']) max_temp = self.convertTemp(daily_weather[0]['max_temp'], daily_weathers['temp']) temp_img = self.textImage(str("{0:.0f}".format(temp)), large_font) deg_img = self.textImage('o', small_font) min_img = self.textImage( "{0:.0f}".format(min_temp, daily_weathers['temp']), small_font, r=0, g=0, b=255) max_img = self.textImage( "{0:.0f}".format(max_temp, daily_weathers['temp']), small_font, r=255, g=0, b=0) main = daily_weather[0]['main_weather'] main_img = self.textImage(main.upper(), small_font) 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(), extra_small_font) rain_img = Image.open(weather_dir + '/rain-chance.png') rtext_img = self.textImage(str(int(daily_weather[0]['rain_chance']*100)) + '%', extra_small_font) hum_img = Image.open(weather_dir + '/humidity.png') htext_img = self.textImage(str(daily_weather[0]['humidity']) + '%', extra_small_font) wind_img = Image.open(weather_dir + '/wind.png') wtext_img = self.textImage(str(daily_weather[0]['wind_speed']) + 'm/s'.upper(), extra_small_font) uv_img = Image.open(weather_dir + '/uv.png') utext_img = self.textImage(str(round(daily_weather[0]['uv'], 1)) , small_font) cloud_img = Image.open(weather_dir + '/clouds.png') ctext_img = self.textImage(str(daily_weather[0]['clouds']) + '%', small_font) wind_img = Image.open(weather_dir + '/wind.png') w_speed = daily_weather[0]['wind_speed']*3.6 w_unit = 'K/H' if daily_weathers['wind_speed'] == "miles/hour": w_speed = daily_weather[0]['wind_speed']*2.236936 w_unit = 'M/H' wtext_img = self.textImage("{0:.0f}".format(w_speed) + w_unit, small_font) wdir_img = self.textImage(self.degreesToCompass(daily_weather[0]['wind_direction']), small_font) vis_img = Image.open(weather_dir + '/visibility.png') vtext_img = self.textImage(str(round(daily_weather[0]['visibility']/1000, 1)) + 'km'.upper(), small_font) img.paste(location_img, (0,0)) x_offset = location_img.size[0]+2 img.paste(weather_img, (5,9)) x_offset = 5 + weather_img.size[0] + 1 img.paste(main_img, (x_offset, 26)) img.paste(temp_img, (x_offset + main_img.size[0]//2 - temp_img.size[0]//2,9)) img.paste(deg_img, (x_offset + main_img.size[0]//2 - temp_img.size[0]//2 + temp_img.size[0], 8)) x_offset += max( main_img.size[0], temp_img.size[0] + deg_img.size[0]) img.paste(min_img, (x_offset - 0, 12)) img.paste(max_img, (x_offset - 0, 21)) x_offset += max(min_img.size[0], max_img.size[0]) + 2 img.paste(date_img, (x_offset, 1)) x_offset += date_img.size[0]+2 img.paste(rain_img, (x_offset,0)) x_offset += rain_img.size[0]+2 img.paste(rtext_img, (x_offset, 1)) x_offset += rtext_img.size[0]+2 img.paste(hum_img, (x_offset, 0)) x_offset += hum_img.size[0]+2 img.paste(htext_img, (x_offset, 1)) x_offset+= htext_img.size[0]+2 img.paste(uv_img, ( x_offset, 0)) x_offset += uv_img.size[0]+2 img.paste(utext_img, (x_offset, 1)) x_offset += utext_img.size[0]+2 img.paste(cloud_img, (x_offset,0)) x_offset += cloud_img.size[0]+2 img.paste(ctext_img, (x_offset, 1)) x_offset += ctext_img.size[0]+2 img.paste(wind_img, (x_offset,0)) x_offset += wind_img.size[0]+2 img.paste(wtext_img, (x_offset, 1)) x_offset += wtext_img.size[0]+2 img.paste(wdir_img, (x_offset, 1)) x_offset+= wdir_img.size[0]+2 img.paste(vis_img, (x_offset,0)) x_offset+= vis_img.size[0]+2 img.paste(vtext_img, (x_offset, 1)) x_offset += vtext_img.size[0] +2 crop_x = x_offset #img.paste(uv_img, ( 96, 0)) #img.paste(utext_img, (109, 0)) #img.paste(wind_img, (96,0)) #img.paste(wtext_img, (109,0)) #img.paste(date_img, (70, 0)) x_offset = 77 for i in range(1,len(daily_weather)): weekday = weekdays[(datetime.today().weekday() + i)%7] day_img = self.textImage( weekday.upper(), small_font) weather = daily_weather[i] main = weather['main_weather'] if main == 'Clouds': main = weather['description'] if main == 'Rain': main = weather['description'] min_temp = self.convertTemp(weather['min_temp'], daily_weathers['temp']) max_temp = self.convertTemp(weather['max_temp'], daily_weathers['temp']) weather_img = Image.open(weather_dir + '/small_icons/' + weather_ids[main] + '.png') min_img = self.textImage( "{0:.0f}".format(min_temp), small_font, r=0, g=0, b=255) max_img = self.textImage( "{0:.0f}".format(max_temp), small_font, r=255, g=0, b=0) img.paste(day_img, (x_offset +5, 9)) img.paste(weather_img, (x_offset +5, 16)) img.paste(min_img, (x_offset + 25, 10)) img.paste(max_img, (x_offset + 25, 18)) x_offset += 43 img1 = img.crop((0,0,max(x_offset, crop_x) ,32)) imgs.append(img1) imgs.append(self.blank) # add the image text except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() return self.stitchImage(imgs) def getDailyWeatherProfessional(self): f = open('csv/daily_weather.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/forecast.png') image_list = [title_img, Image.new('RGB', (3, 16))] else: image_list = [] f = open('csv/daily_weather.json', 'r') daily_weathers = json.load(f) 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: img = Image.new('RGB', (1000, 32)) daily_weather = daily_weathers['locations'][location] small_font = ImageFont.load("./fonts/4x6.pil") font = ImageFont.load("./fonts/6x10.pil") large_font = ImageFont.load("./fonts/10x20.pil") main = daily_weather[0]['main_weather'] if main == 'Clouds': main = daily_weather[0]['description'] if main == 'Rain': main = daily_weather[0]['description'] weather_ids = {'Clear': '01', 'few clouds': '02', 'scattered clouds': '03', 'broken clouds':'04', 'overcast clouds':'04', 'Drizzle':'09', 'Rain':'10', 'Thunderstorm':'11', 'Snow':'13', 'Mist': '50', 'Smoke': '50', 'Haze': '50', 'Dust': '50', 'Fog': '50', 'Sand': '50', 'Ash': '50', 'Squall': '50', 'Tornado': '50', 'light rain': '10', 'moderate rain': '10', 'heavy intensity rain': '10', 'very heavy rain': '10', 'extreme rain': '10', 'freezing rain': '13', 'light intensity shower rain': '09', 'shower rain': '09', 'heavy intensity shower rain': '09', 'ragged shower rain': '09'} weather_dir = './logos/weather_icons' location_img = self.textImage(location.upper(), font, r = 255, g = 255, b = 0) img.paste(location_img, (5,3)) x_offset = location_img.size[0] + 8 date_img = self.textImage((month + ' ' + date + ',' + weekday).upper(), font) img.paste(date_img, (x_offset, 3)) x_offset += date_img.size[0] + 2 weather_img = Image.open(weather_dir + '/small_icons/' + weather_ids[main] + '.png') w, h = weather_img.size #weather_img = weather_img.resize((int(w/2), int(h/2))) main = daily_weather[0]['main_weather'] main_img = self.textImage(main.upper(), font) img.paste(main_img, (x_offset, 3)) x_offset += main_img.size[0] + 2 img.paste(weather_img, (x_offset,3)) x_offset += weather_img.size[0] + 2 temp = self.convertTemp(daily_weather[0]['temp'], daily_weathers['temp']) temp_img = self.textImage(str("{0:.0f}".format(temp)), font) img.paste(temp_img, (x_offset,3)) x_offset += temp_img.size[0]-3 deg_img = self.textImage('o', small_font) img.paste(deg_img, (x_offset+1, 1)) x_offset += deg_img.size[0] -2 min_img = self.textImage( "{0:.0f}".format(self.convertTemp(daily_weather[0]['min_temp'], daily_weathers['temp'])), small_font, r=0, g=0, b=255) img.paste(min_img, (x_offset+2, 2)) max_img = self.textImage( "{0:.0f}".format(self.convertTemp(daily_weather[0]['max_temp'], daily_weathers['temp'])), small_font, r=255, g=0, b=0) img.paste(max_img, (x_offset+2, 8)) x_offset += max_img.size[0] + 15 crop_x = x_offset for i in range(1,len(daily_weather)): weekday = weekdays[(datetime.today().weekday() + i)%7] day_img = self.textImage( weekday.upper(), font) weather = daily_weather[i] main = weather['main_weather'] if main == 'Clouds': main = weather['description'] if main == 'Rain': main = weather['description'] min_img = self.textImage( "{0:.0f}".format(self.convertTemp(weather['min_temp'], daily_weathers['temp'])), small_font, r=0, g=0, b=255) max_img = self.textImage( "{0:.0f}".format(self.convertTemp(weather['max_temp'], daily_weathers['temp'])), small_font, r=255, g=0, b=0) weather_img = Image.open(weather_dir + '/small_icons/' + weather_ids[main] + '.png') img.paste(day_img, (x_offset, 3)) x_offset += (day_img.size[0]) img.paste(weather_img, (x_offset, 3)) x_offset += (weather_img.size[0]+2) img.paste(min_img, (x_offset, 2)) img.paste(max_img, (x_offset, 8)) x_offset += (max(min_img.size[0], max_img.size[0])+5) x_offset += 35 img1 = img.crop((0,0,x_offset,16)) # img1 = img.crop((0,0,max(x_offset, crop_x) ,16)) image_list.append(img1) except Exception as e: pass return self.stitchImage(image_list) def readSportsCSV(self, league): team_info = {} f = open('csv/sports/{}/team_info.csv'.format(league), 'r') CSV = csv.reader(f) next(CSV) for row in CSV: team_info[row[0]] = {} team_info[row[0]]['id'] = row[1] team_info[row[0]]['code'] = row[2] team_info[row[0]]['logo'] = row[4] team_info[row[0]]['colour'] = row[3] f.close() return team_info def displayDailyWeatherAlt(self): img0, img1 = self.getDailyWeatherImageAlt() while True: self.setImage(img0, offset_x = 0, offset_y = 0) image = img1 img_width, img_height = image.size offset_x = 64 offset_y = 0 while offset_x > 64-img_width: offset_x -= 1 self.setImage(image, offset_x = offset_x, offset_y = offset_y, min_x = 64, min_y = 9) if offset_x + img_width < self.matrix.width: # if the image is ending self.setImage(image, offset_x = offset_x + img_width, offset_y = offset_y, min_x = 64, min_y = 9) try: msg = getInput() if msg == 'K': self.resetMatrix() return True self.process_msg(msg) except KeyboardInterrupt: sys.stdout.flush() pass time.sleep(self.delay*1.1) def getUserImages(self): f = open('csv/image_settings.json', 'r') all_settings = json.load(f) f.close() imgs = [] for ind,image in enumerate(all_settings['images']): try: img = self.openImage(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'user_uploads'), image)) img.thumbnail((99999, 32)) if all_settings['title'] and ind == 0: title_img = self.openImage('feature_titles/images.png') imgs.append(self.stitchImage([title_img, img])) else: imgs.append(img) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() return imgs def getUserImagesProfessional(self): f = open('csv/image_settings.json', 'r') all_settings = json.load(f) f.close() if all_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/images.png') image_list = [title_img] else: image_list = [] blank = Image.new('RGB', (0, 16)) for i,image in enumerate(all_settings['images']): if (i == len(all_settings['images'])-1): try: user_image = self.openImage(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'user_uploads'), image)) user_image.thumbnail((99999, 16)) #user_image.convert('RGB') img = Image.new('RGB', (user_image.size[0] + 5, 32)) img.paste(user_image, (0,0)) image_list.append(img) image_list.append(blank) except Exception as e: pass else: try: user_image = self.openImage(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'user_uploads'), image)) user_image.thumbnail((99999, 16)) #user_image.convert('RGB') img = Image.new('RGB', (user_image.size[0] + 130, 32)) img.paste(user_image, (0,0)) image_list.append(img) image_list.append(blank) except Exception as e: pass return self.stitchImage(image_list) def getUserGIFs(self): f = open('csv/GIF_settings.json', 'r') all_settings = json.load(f) f.close() GIFs = [] for ind,fle in enumerate(all_settings['images']): try: GIF = Image.open(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'user_uploads'), fle)) frames = [] if ind == 0 and all_settings['title']: #title_img = self.openImage('feature_titles/gifs.png') for i, frame in enumerate(ImageSequence.Iterator(GIF)): frame = frame.convert('P') frame.thumbnail((128, 32),Image.NEAREST) #f = self.stitchImage([title_img, frame]) frames.append(frame) else: for i, frame in enumerate(ImageSequence.Iterator(GIF)): frame = frame.convert('P') frame.thumbnail((128, 32),Image.NEAREST) #frame = frame.resize((99999, 32)) #f = self.stitchImage([frame]) frames.append(frame) frames[0].save('./display_images/working_gif{}.gif'.format(str(ind)), save_all=True, append_images=frames[1:], loop=0, optimize = False) GIF = Image.open('./display_images/working_gif{}.gif'.format(str(ind))) GIFs.append(GIF) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close() #below code stitches title and GIF together # frames = [] # for i, frame in enumerate(ImageSequence.Iterator(gif)): # if all_settings['title']: # f = self.stitchImage([title_img, frame]) # else: # f = self.stitchImage([frame]) # frames.append(f) # frames[0].save('./display_images/Custom GIFs.gif', save_all=True, append_images=frames[1:], loop=0, optimize = False) return GIFs def getMoviesImage(self): f = open('csv/movie_settings.json', 'r') all_movie_settings = json.load(f) f.close() if all_movie_settings['title']: title_img = self.openImage('feature_titles/movies.png') image_list = [title_img] else: image_list = [] font = ImageFont.load("./fonts/6x13.pil") small_font = ImageFont.load("./fonts/5x8.pil") for movie in all_movie_settings['movies']: x_offset = 0 movie_title_img = self.textImage(movie['title'] + ' (' + movie['media_type'] + ')', font, r = 255, g = 180, b = 0) lang_img = self.textImage('Lan:' + movie['language'], small_font, r = 255, g = 0, b = 100) vote_img = self.textImage(movie['votes'], small_font, r = 255, g = 255, b = 255) star_img = Image.open('logos/star.png').convert('RGB') date_img = self.textImage(movie['date'], small_font, r = 0, g = 162, b = 255) try: if movie['media_type'] == 'Movie': if movie['budget'] == '0': budget_img = self.textImage('$N/A', small_font, r = 255, g = 0, b = 0) else: budget_img = self.textImage('$' + movie['budget'], small_font, r = 255, g = 0, b = 0) except: pass try: if movie['media_type'] == 'Movie': if movie['revenue'] == '0': rev_img = self.textImage('$N/A', small_font, r = 0, g = 255, b = 0) else: rev_img = self.textImage('$' + movie['revenue'], small_font, r = 0, g = 255, b = 0) except: pass try: logo = Image.open('logos/movies/' + movie['backdrop']) logo.thumbnail((9000,32)) logo.convert('P') except: logo = self.textImage('No Logo', small_font, r=255, g=255, b=255) x_offset += logo.size[0] + 3 genre_offset = 0 for genre in movie['genre']: genre_img = self.textImage(genre + ',', small_font, r = 255, g = 255, b = 255) genre_offset += genre_img.size[0] try: if movie['media_type'] == 'Movie': img = Image.new('RGB', (max(x_offset + movie_title_img.size[0], x_offset + date_img.size[0] + 3 + star_img.size[0] + vote_img.size[0] + 3 + 5 + budget_img.size[0] + 5 + rev_img.size[0], x_offset + date_img.size[0] + 3 + genre_offset) + 15, 32)) else: img = Image.new('RGB', (max(x_offset + movie_title_img.size[0], x_offset + date_img.size[0] + 3 + star_img.size[0] + vote_img.size[0] + 3, x_offset + date_img.size[0] + 3 + genre_offset) + 15, 32)) except: img = Image.new('RGB', (max(x_offset + movie_title_img.size[0], x_offset + date_img.size[0] + 3 + star_img.size[0] + vote_img.size[0] + 3, x_offset + date_img.size[0] + 3 + genre_offset) + 15, 32)) img.paste(logo, (0, 0)) img.paste(movie_title_img, (x_offset,0)) img.paste(date_img, (x_offset, 14)) img.paste(lang_img, (x_offset, 23)) x_offset += max(date_img.size[0], lang_img.size[0]) + 3 x_offset2 = x_offset img.paste(star_img, (x_offset2 , 14)) img.paste(vote_img, (x_offset2 + star_img.size[0] + 3, 14)) try: if movie['media_type'] == 'Movie': img.paste(budget_img, (x_offset2 + star_img.size[0] + 3 + vote_img.size[0] + 5, 14)) except: pass try: if movie['media_type'] == 'Movie': img.paste(rev_img,(x_offset2 + star_img.size[0] + 3 + vote_img.size[0] + 5 + budget_img.size[0] + 5, 14)) except: pass for genre in movie['genre'][:-1]: genre_img = self.textImage(genre + ',', small_font, r = 255, g = 255, b = 255) img.paste(genre_img, (x_offset2, 23)) x_offset2 += genre_img.size[0] else: genre_img2 = self.textImage(movie['genre'][-1], small_font, r = 255, g = 255, b = 255) img.paste(genre_img2, (x_offset2, 23)) x_offset2 += genre_img2.size[0] image_list.append(img) return self.stitchImage(image_list) def getMoviesProfessional(self): f = open('csv/movie_settings.json', 'r') all_movie_settings = json.load(f) f.close() if all_movie_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/movies.png') image_list = [title_img] else: image_list = [] font = ImageFont.load("./fonts/6x10.pil") small_font = ImageFont.load("./fonts/4x6.pil") for movie in all_movie_settings['movies']: x_offset = 0 movie_title_img = self.textImage(movie['title'] + ' (' + movie['media_type'] + ')', font, r = 255, g = 180, b = 0) lang_img = self.textImage('Lan:' + movie['language'], small_font, r = 255, g = 0, b = 100) vote_img = self.textImage(movie['votes'], small_font, r = 255, g = 255, b = 255) star_img = Image.open('logos/star.png').convert('RGB') date_img = self.textImage(movie['date'], small_font, r = 0, g = 162, b = 255) try: if movie['media_type'] == 'Movie': if movie['budget'] == '0': budget_img = self.textImage('$N/A', small_font, r = 255, g = 0, b = 0) else: budget_img = self.textImage('$' + movie['budget'], small_font, r = 255, g = 0, b = 0) except: pass try: if movie['media_type'] == 'Movie': if movie['revenue'] == '0': rev_img = self.textImage('$N/A', small_font, r = 0, g = 255, b = 0) else: rev_img = self.textImage('$' + movie['revenue'], small_font, r = 0, g = 255, b = 0) except: pass try: logo = Image.open('logos/movies/' + movie['backdrop']) logo.thumbnail((1000,16)) logo.convert('P') except: logo = self.textImage('No Logo', small_font, r=255, g=255, b=255) x_offset += logo.size[0] + 3 genre_offset = 0 # img = Image.new('RGB', (200,16)) for genre in movie['genre']: genre_img = self.textImage(genre + ',', small_font, r = 255, g = 255, b = 255) genre_offset += genre_img.size[0] try: if movie['media_type'] == 'Movie': img = Image.new('RGB', (max(x_offset + movie_title_img.size[0] + 3 + star_img.size[0] + 2 + vote_img.size[0] + 10 + 3 + budget_img.size[0] + 3 + rev_img.size[0], x_offset + date_img.size[0] + 7 + lang_img.size[0] + 7 + genre_offset + 10), 16)) else: img = Image.new('RGB', (max(x_offset + movie_title_img.size[0] + 3 + star_img.size[0] + 2 + vote_img.size[0] + 10, x_offset + date_img.size[0] + 7 + lang_img.size[0] + 7 + genre_offset + 10), 16)) except: img = Image.new('RGB', (max(x_offset + movie_title_img.size[0] + 3 + star_img.size[0] + 2 + vote_img.size[0] + 10, x_offset + date_img.size[0] + 7 + lang_img.size[0] + 7 + genre_offset + 10), 16)) img.paste(logo, (0, 0)) img.paste(movie_title_img, (x_offset,0)) x_offset2 = x_offset + movie_title_img.size[0] + 3 img.paste(star_img, (x_offset2, 1)) x_offset2 += star_img.size[0] + 2 img.paste(vote_img, (x_offset2, 2)) x_offset2 += vote_img.size[0] try: if movie['media_type'] == 'Movie': img.paste(budget_img, (x_offset2 + 3, 2)) except: pass try: if movie['media_type'] == 'Movie': img.paste(rev_img,(x_offset2 + 3 + budget_img.size[0] + 3, 2)) except: pass img.paste(date_img, (x_offset, 10)) x_offset += date_img.size[0] + 7 img.paste(lang_img, (x_offset, 10)) x_offset += lang_img.size[0] + 7 for genre in movie['genre'][:-1]: genre_img = self.textImage(genre + ',', small_font, r = 255, g = 255, b = 255) img.paste(genre_img, (x_offset, 10)) x_offset += genre_img.size[0] else: genre_img2 = self.textImage(movie['genre'][-1], small_font, r = 255, g = 255, b = 255) img.paste(genre_img2, (x_offset, 10)) x_offset += genre_img2.size[0] image_list.append(img) return self.stitchImage(image_list) def getIpoImage(self): f = open('csv/ipo_settings.json', 'r') ipo_settings = json.load(f) f.close() if ipo_settings['title']: title_img = self.openImage('feature_titles/ipo.png') image_list = [title_img] else: image_list = [] font = ImageFont.load("./fonts/7x14B.pil") font2 = ImageFont.load("./fonts/6x13.pil") small_font = ImageFont.load("./fonts/6x10.pil") if ipo_settings['symbols'][0] != 'No Data': try: for ipo in ipo_settings['symbols']: x_offset = 10 x_offset2 = 10 name_img = self.textImage(ipo['name'].upper(), font, r = 255, g = 255, b = 255) try: if ipo['symbol'] == "": symbol_img = self.textImage('($N/A)', font2, r = 255, g = 255, b = 255) else: symbol_img = self.textImage('($'+ ipo['symbol'] + ')', font2, r = 255, g = 255, b = 255) except: symbol_img = self.textImage('($N/A)', font2, r = 255, g = 255, b = 255) date_img = self.textImage(ipo['date'], font2, r = 255, g = 255, b = 0) status_1 = self.textImage('Status:', small_font, r=255, g=255, b=255) if ipo['status'] == 'expected': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 255, g = 255, b = 0) # diff color elif ipo['status'] == 'priced': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 0, g = 255, b = 0) # diff color elif ipo['status'] == 'withdrawn': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 255, g = 0, b = 0) # diff color elif ipo['status'] == 'filed': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 54, g = 69, b = 79) # diff color shares_1 = self.textImage('Shares:', small_font, r = 255, g = 255, b = 255) try: shares_img = self.textImage(ipo['shares'], small_font, r = 38, g = 59, b = 232) except: shares_img = self.textImage('N/A', small_font, r = 38, g = 59, b = 232) price_1 = self.textImage('Price:', small_font, r = 255, g = 255, b = 255) try: price_img = self.textImage(ipo['price'], small_font, r = 0, g = 255, b = 0) except: price_img = self.textImage('N/A', small_font, r = 0, g = 255, b = 0) sharesvalue_1 = self.textImage('Value:', small_font, r=255, g=255, b=255) try: sharesvalue_img = self.textImage(ipo['sharesvalue'], small_font, r = 213, g = 117, b = 0) except: sharesvalue_img = self.textImage('N/A', small_font, r = 213, g = 117, b = 0) img = Image.new('RGB', (max(x_offset + name_img.size[0] + 2 + symbol_img.size[0] + 8 + date_img.size[0], x_offset2 + status_1.size[0] + status_img.size[0] + 8 + price_1.size[0] + price_img.size[0] + 8 + shares_1.size[0] + shares_img.size[0] +8 + sharesvalue_1.size[0] + sharesvalue_img.size[0])+30,32)) img.paste(status_1,(x_offset2, 19)) x_offset2 += status_1.size[0] img.paste(status_img, (x_offset2, 19)) x_offset2 += status_img.size[0] + 8 img.paste(price_1, (x_offset2, 19)) x_offset2 += price_1.size[0] img.paste(price_img, (x_offset2, 19)) x_offset2 += price_img.size[0] + 8 img.paste(shares_1, (x_offset2, 19)) x_offset2 += shares_1.size[0] img.paste(shares_img, (x_offset2, 19)) x_offset2 += shares_img.size[0] + 8 img.paste(sharesvalue_1, (x_offset2, 19)) x_offset2 += sharesvalue_1.size[0] img.paste(sharesvalue_img, (x_offset2, 19)) img.paste(name_img, (x_offset,0)) x_offset += name_img.size[0] + 2 img.paste(symbol_img, (x_offset, 0)) x_offset += symbol_img.size[0] + 8 img.paste(date_img, (x_offset, 0)) line_image = Image.new("RGB", (name_img.size[0] + 2 + symbol_img.size[0] + 8 + date_img.size[0], 1)) line_image1 = ImageDraw.Draw(line_image) line_image1.line((0,0,name_img.size[0] + 2 + symbol_img.size[0] + 8 + date_img.size[0],0), fill="blue", width = 0) img.paste(line_image, (10, max(name_img.size[1],symbol_img.size[1])-1)) image_list.append(img) except: time.sleep(0.1) no_ipo = self.textImage('No Upcoming IPOs for the next 3 weeks.', font, r = 255, g = 255, b = 255) img = Image.new('RGB', (no_ipo.size[0] + 15, 32)) img.paste(no_ipo, (10, 10)) image_list.append(img) elif ipo_settings['symbols'][0] == 'No Data': time.sleep(0.1) no_ipo = self.textImage('No Upcoming IPOs for the next 3 weeks.', font, r = 255, g = 255, b = 255) img = Image.new('RGB', (no_ipo.size[0] + 15, 32)) img.paste(no_ipo, (10, 10)) image_list.append(img) return self.stitchImage(image_list) def getIpoProfessional(self): f = open('csv/ipo_settings.json', 'r') ipo_settings = json.load(f) f.close() if ipo_settings['title']: title_img = self.openImage('feature_titles/small_feature_titles/ipo.png') image_list = [title_img] else: image_list = [] font = ImageFont.load("./fonts/5x8.pil") small_font = ImageFont.load("./fonts/4x6.pil") if ipo_settings['symbols'][0] != 'No Data': try: for ipo in ipo_settings['symbols']: x_offset = 10 x_offset2 = 10 name_img = self.textImage(ipo['name'].upper(), font, r = 255, g = 255, b = 255) try: if ipo['symbol'] == "": symbol_img = self.textImage('($N/A)', font, r = 255, g = 255, b = 255) else: symbol_img = self.textImage('($'+ ipo['symbol'] + ')', font, r = 255, g = 255, b = 255) except: symbol_img = self.textImage('($N/A)', font, r = 255, g = 255, b = 255) date_img = self.textImage(ipo['date'], font, r = 255, g = 255, b = 0) status_1 = self.textImage('Status:', small_font, r=255, g=255, b=255) if ipo['status'] == 'expected': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 255, g = 255, b = 0) # diff color elif ipo['status'] == 'priced': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 0, g = 255, b = 0) # diff color elif ipo['status'] == 'withdrawn': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 255, g = 0, b = 0) # diff color elif ipo['status'] == 'filed': status_img = self.textImage(ipo['status'].capitalize(), small_font, r = 54, g = 69, b = 79) # diff color shares_1 = self.textImage('Shares:', small_font, r = 255, g = 255, b = 255) try: shares_img = self.textImage(ipo['shares'], small_font, r = 38, g = 59, b = 232) except: shares_img = self.textImage('N/A', small_font, r = 38, g = 59, b = 232) price_1 = self.textImage('Price:', small_font, r = 255, g = 255, b = 255) try: price_img = self.textImage(ipo['price'], small_font, r = 0, g = 255, b = 0) except: price_img = self.textImage('N/A', small_font, r = 0, g = 255, b = 0) sharesvalue_1 = self.textImage('Value:', small_font, r=255, g=255, b=255) try: sharesvalue_img = self.textImage(ipo['sharesvalue'], small_font, r = 213, g = 117, b = 0) except: sharesvalue_img = self.textImage('N/A', small_font, r = 213, g = 117, b = 0) img = Image.new('RGB', (max(x_offset + name_img.size[0] + 2 + symbol_img.size[0] + 5 + date_img.size[0], x_offset2 + status_1.size[0] + status_img.size[0] + 8 + price_1.size[0] + price_img.size[0] + 8 + shares_1.size[0] + shares_img.size[0] +8 + sharesvalue_1.size[0] + sharesvalue_img.size[0])+30,16)) img.paste(status_1,(x_offset2, 10)) x_offset2 += status_1.size[0] img.paste(status_img, (x_offset2, 10)) x_offset2 += status_img.size[0] + 8 img.paste(price_1, (x_offset2, 10)) x_offset2 += price_1.size[0] img.paste(price_img, (x_offset2, 10)) x_offset2 += price_img.size[0] + 8 img.paste(shares_1, (x_offset2, 10)) x_offset2 += shares_1.size[0] img.paste(shares_img, (x_offset2, 10)) x_offset2 += shares_img.size[0] + 8 img.paste(sharesvalue_1, (x_offset2, 10)) x_offset2 += sharesvalue_1.size[0] img.paste(sharesvalue_img, (x_offset2, 10)) img.paste(name_img, (x_offset,0)) x_offset += name_img.size[0] + 2 img.paste(symbol_img, (x_offset, 0)) x_offset += symbol_img.size[0] + 5 img.paste(date_img, (x_offset, 0)) line_image = Image.new("RGB", (name_img.size[0] + 2 + symbol_img.size[0] + 5 + date_img.size[0], 1)) line_image1 = ImageDraw.Draw(line_image) line_image1.line((0,0,name_img.size[0] + 2 + symbol_img.size[0] + 5 + date_img.size[0],0), fill="blue", width = 0) img.paste(line_image, (10, max(name_img.size[1],symbol_img.size[1])-2)) image_list.append(img) except: time.sleep(0.1) font = ImageFont.load("./fonts/6x13.pil") no_ipo = self.textImage('No Upcoming IPOs for the next 3 weeks.', font, r = 255, g = 255, b = 255) img = Image.new('RGB', (no_ipo.size[0] + 15, 16)) img.paste(no_ipo, (10, 1)) image_list.append(img) elif ipo_settings['symbols'][0] == 'No Data': time.sleep(0.1) font = ImageFont.load("./fonts/6x13.pil") no_ipo = self.textImage('No Upcoming IPOs for the next 3 weeks.', font, r = 255, g = 255, b = 255) img = Image.new('RGB', (no_ipo.size[0] + 15, 16)) img.paste(no_ipo, (10, 1)) image_list.append(img) return self.stitchImage(image_list) def displayStocks(self): self.scrollImageTransition(['final.ppm', 'final.ppm'], offset_x = 0, offset_y = 0) def displayProfessional(self): forex = self.getForexProfessional() crypto = self.getCryptoProfessional() news = self.getNewsProfessional() stock = self.getStockProfessional() weather = self.getTodayWeatherProfessional() commodities = self.getCommoditiesProfessional() indices = self.getIndicesProfessional() daily_forecast = self.getDailyWeatherProfessional() sports_stats = self.getLeagueTableProfessional() sports_upcoming = self.getLeagueProfessional() sports_past = self.getLeagueProfessional() sports_live = self.getLeagueProfessional() movies = self.getMoviesProfessional() messages = self.getUserMessagesProfessional() images = self.getUserImagesProfessional() ipo = self.getIpoProfessional() x_offset = 0 news.paste(weather, (x_offset, 16)) x_offset += weather.size[0] news.paste(crypto, (x_offset, 16)) x_offset += crypto.size[0] news.paste(stock, (x_offset, 16)) x_offset += stock.size[0] news.paste(forex, (x_offset, 16)) x_offset += forex.size[0] news.paste(commodities, (x_offset, 16)) x_offset += commodities.size[0] news.paste(indices, (x_offset, 16)) x_offset += indices.size[0] news.paste(daily_forecast, (x_offset, 16)) x_offset += daily_forecast.size[0] news.paste(sports_stats, (x_offset, 16)) x_offset += sports_stats.size[0] news.paste(sports_upcoming, (x_offset, 16)) x_offset += sports_upcoming.size[0] news.paste(sports_past, (x_offset, 16)) x_offset += sports_past.size[0] news.paste(sports_live, (x_offset, 16)) x_offset += sports_live.size[0] news.paste(movies, (x_offset, 16)) x_offset += movies.size[0] news.paste(messages, (x_offset, 16)) x_offset += messages.size[0] news.paste(images, (x_offset, 16)) x_offset += images.size[0] news.paste(ipo, (x_offset, 16)) x_offset += ipo.size[0] self.double_buffer = self.matrix.CreateFrameCanvas() while True: kill = stock_ticker.scrollImage(news, offset_x = 128) if kill: break def process_msg(self, msg): if msg == 'S': # stocks self.scrollFunctionsAnimated(['stocks', 'stocks'], animation = 'traditional') elif msg == 'C': # crypto self.scrollFunctionsAnimated(['crypto', 'crypto'], animation = 'traditional') elif msg == 'F': # forex self.scrollFunctionsAnimated(['forex', 'forex'], animation = 'traditional') elif msg == 'N': #news self.scrollFunctionsAnimated(['news', 'news'], animation = 'traditional') # speed settings elif msg == 's': self.delay = 0.03 elif msg == 'm': self.delay = 0.02 elif msg == 'f': self.delay = 0.01 elif msg in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: # birghtness ettings self.brightness = (float(msg)+1)*10 self.matrix.brightness = self.brightness elif msg == 'T':# text self.scrollFunctionsAnimated(['text', 'text'], animation = 'traditional') elif msg == 'I': # image self.scrollFunctionsAnimated(['display_image', 'display_image'], animation = 'traditional') elif msg == 'G': # gif self.scrollFunctionsAnimated(['display_gif', 'display_gif'], animation = 'traditional') elif msg == 'W': # weather self.scrollFunctionsAnimated(['today_weather', 'today_weather'], animation = 'traditional') elif msg == 'D': # daily weather self.scrollFunctionsAnimated(['daily_weather', 'daily_weather'],animation = 'traditional') elif msg == 'P': # past league self.scrollFunctionsAnimated(['past_games', 'past_games'],animation = 'traditional') elif msg == 'l': # future league self.scrollFunctionsAnimated(['future_games', 'future_games'],animation = 'traditional') elif msg == 'L': # live game self.scrollFunctionsAnimated(['live_games', 'live_games'],animation = 'traditional') elif msg == 't': #legue tble self.scrollFunctionsAnimated(['league_table', 'league_table'],animation = 'traditional') elif msg == 'CO': #commodities self.scrollFunctionsAnimated(['commodities', 'commodities'],animation = 'traditional') elif msg == 'WI': #indices self.scrollFunctionsAnimated(['indices', 'indices'],animation = 'traditional') elif msg == 'MO': #movies self.scrollFunctionsAnimated(['movies', 'movies'],animation = 'traditional') elif msg == 'IPO': #ipo self.scrollFunctionsAnimated(['ipo', 'ipo'],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 #userSettings = [ 'daily_weather'] #userSettings = ['crypto', 'stocks'] # these wil be read from csv, just for demo #userSettings = [ 'display_image', 'news'] # these wil be read from csv, just for demo f = open('csv/display_settings.json', 'r') user_settings = json.load(f) f.close() if 'Professional'==user_settings[0] and len(user_settings[1][0])>0 and len(user_settings[1][1])>0: #if professional display self.scrollProfessionalAnimated(user_settings[1]) elif len(user_settings[1][0])>0 and 'Standard'==user_settings[0]: self.scrollFunctionsAnimated(user_settings[1][0], animation = 'down') elif msg == 'b': userSettings = json.load(open('csv/display_settings.json')) self.scrollProfessionalAnimated(userSettings) #self.displayProfessional() elif msg == '+': stock_ticker.scrollMultiple() elif msg == 'K': # kill self.resetMatrix() elif msg =='-': self.run_intro_screen() elif msg == '*': # # start_GIF = Image.open('./logos/startup_logo1.gif') self.displayGIF(start_GIF, delay = 0.02, repeat = False) #stock_ticker.setImage(start_image) time.sleep(2) self.resetMatrix() def run_intro_screen(self): dct = {"feature": "Custom Messages", "speed": "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"}]} json.dump(dct, open('csv/message_settings.json', 'w')) self.scrollFunctionsAnimated(['Custom Messages'], repeat = True) if __name__ == '__main__': try: stock_ticker = StockTicker() while True: msg = getInput() stock_ticker.process_msg(msg) except Exception as e: pass # logf = open('log.txt', "a") # exc_type, exc_obj, exc_tb = sys.exc_info() # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] # logf.write(str(e)) # logf.write('. file: ' + fname) # logf.write('. line: ' + str(exc_tb.tb_lineno)) # logf.write('. type: ' + str(exc_type)) # logf.write('\n ' + "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # logf.close()