From b58f7e7a2f09bf6cf112817c01e5bf45611945d7 Mon Sep 17 00:00:00 2001 From: Justin Emter Date: Thu, 20 Jul 2017 02:09:47 -0700 Subject: [PATCH] Alpha --- .gitignore | 1 + PseudoChannel.py | 85 +++++++++++++++++++++++++++++++---- pseudo-channel.db | Bin 561152 -> 577536 bytes pseudo_schedule.xml | 8 ++-- src/PseudoChannelDatabase.py | 65 ++++++++++----------------- 5 files changed, 106 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 3c49506..2d2cad6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ schedules/ pseudo-tv.db-journal *.pyc old/ +pseudo-channel.db diff --git a/PseudoChannel.py b/PseudoChannel.py index 4154c89..816ad24 100644 --- a/PseudoChannel.py +++ b/PseudoChannel.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from src import PseudoChannelDatabase from src import Movie from src import Commercial @@ -8,6 +10,7 @@ from pseudo_config import * from plexapi.server import PlexServer +import sys import datetime from xml.dom import minidom import xml.etree.ElementTree as ET @@ -35,6 +38,29 @@ class PseudoChannel(): generate_daily_schedule(): Generates daily schedule based on the "schedule" table. """ + # Print iterations progress + def print_progress(self, iteration, total, prefix='', suffix='', decimals=1, bar_length=100): + """ + Call in a loop to create terminal progress bar + @params: + iteration - Required : current iteration (Int) + total - Required : total iterations (Int) + prefix - Optional : prefix string (Str) + suffix - Optional : suffix string (Str) + decimals - Optional : positive number of decimals in percent complete (Int) + bar_length - Optional : character length of bar (Int) + """ + str_format = "{0:." + str(decimals) + "f}" + percents = str_format.format(100 * (iteration / float(total))) + filled_length = int(round(bar_length * iteration / float(total))) + bar = '█' * filled_length + '-' * (bar_length - filled_length) + + sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix)), + + if iteration == total: + sys.stdout.write('\n') + sys.stdout.flush() + def update_db(self): print("Updating Local Database") @@ -49,15 +75,22 @@ class PseudoChannel(): sectionMedia = self.PLEX.library.section(section.title).all() - for media in sectionMedia: + self.print_progress(0, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50) + + for i, media in enumerate(sectionMedia): self.db.add_movies_to_db(1, media.title, media.duration) + self.print_progress(i + 1, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50) + + elif section.title == "TV Shows": sectionMedia = self.PLEX.library.section(section.title).all() - for media in sectionMedia: + self.print_progress(0, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50) + + for i, media in enumerate(sectionMedia): backgroundImagePath = self.PLEX.library.section(section.title).get(media.title) @@ -69,6 +102,8 @@ class PseudoChannel(): self.db.add_shows_to_db(2, media.title, media.duration, '', backgroundImgURL) + self.print_progress(i + 1, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50) + #add all episodes of each tv show to episodes table episodes = self.PLEX.library.section(section.title).get(media.title).episodes() @@ -88,12 +123,20 @@ class PseudoChannel(): sectionMedia = self.PLEX.library.section(section.title).all() - for media in sectionMedia: + self.print_progress(0, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50) + + for i, media in enumerate(sectionMedia): self.db.add_commercials_to_db(3, media.title, media.duration) + self.print_progress(i + 1, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50) + def update_schedule(self): + self.db.create_tables() + + self.db.remove_all_scheduled_items() + scheduled_days_list = [ "mondays", "tuesdays", @@ -122,24 +165,46 @@ class PseudoChannel(): if child.tag in scheduled_days_list: - print child.find( "time" ) - for time in child.iter("time"): for key, value in section_dict.items(): if time.attrib['type'] == key or time.attrib['type'] in value: - print time.tag, time.text, time.attrib['title'] - title = time.attrib['title'] natural_start_time = time.text + natural_end_time = 0 + section = key + day_of_week = child.tag + strict_time = time.attrib['strict-time'] + time_shift = time.attrib['time-shift'] + + overlap_max = time.attrib['overlap-max'] + + start_time_unix = datetime.datetime.strptime(time.text, '%I:%M %p') + + print "Adding: ", time.tag, section, time.text, time.attrib['title'] + + self.db.add_schedule_to_db( + 0, # mediaID + title, # title + 0, # duration + natural_start_time, # startTime + natural_end_time, # endTime + day_of_week, # dayOfWeek + start_time_unix, # startTimeUnix + section, # section + strict_time, # strictTime + time_shift, # timeShift + overlap_max, # overlapMax + ) + def drop_db(self): self.db.drop_db() @@ -189,6 +254,8 @@ class PseudoChannel(): if section == "TV Shows": + print "getting", entry[3] + next_episode = self.db.get_next_episode(entry[3]) if next_episode != None: @@ -294,9 +361,11 @@ if __name__ == '__main__': pseudo_channel = PseudoChannel() + pseudo_channel.update_db() + pseudo_channel.update_schedule() - #pseudo_channel.generate_daily_schedule() + pseudo_channel.generate_daily_schedule() """for item in pseudo_channel.MEDIA: diff --git a/pseudo-channel.db b/pseudo-channel.db index b92bbbf28d27e03c4b046492d43fcdce26df9795..5c91de317472725de8acc7a35dbd09c9bf3f9a3c 100644 GIT binary patch literal 577536 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 f1eN8$s+8E`kDs-n@CU^i=&7 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