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 b92bbbf..5c91de3 100644 Binary files a/pseudo-channel.db and b/pseudo-channel.db differ diff --git a/pseudo_schedule.xml b/pseudo_schedule.xml index eb223c2..d196c69 100644 --- a/pseudo_schedule.xml +++ b/pseudo_schedule.xml @@ -15,10 +15,10 @@ - - - - + + + + diff --git a/src/PseudoChannelDatabase.py b/src/PseudoChannelDatabase.py index 352ac83..8709158 100644 --- a/src/PseudoChannelDatabase.py +++ b/src/PseudoChannelDatabase.py @@ -48,7 +48,8 @@ class PseudoChannelDatabase(): self.cursor.execute('CREATE TABLE IF NOT EXISTS ' 'schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, ' 'mediaID INTEGER, title TEXT, duration INTEGER, startTime INTEGER, ' - 'endTime INTEGER, dayOfWeek TEXT, startTimeUnix INTEGER), section TEXT)') + 'endTime INTEGER, dayOfWeek TEXT, startTimeUnix INTEGER, section TEXT, ' + 'strictTime TEXT, timeShift TEXT, overlapMax TEXT)') self.cursor.execute('CREATE TABLE IF NOT EXISTS ' 'daily_schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, ' @@ -56,7 +57,7 @@ class PseudoChannelDatabase(): 'showTitle TEXT, duration INTEGER, startTime INTEGER, endTime INTEGER, dayOfWeek TEXT)') self.cursor.execute('CREATE TABLE IF NOT EXISTS ' - 'app_settings(id INTEGER PRIMARY KEY AUTOINCREMENT, version TEXT') + 'app_settings(id INTEGER PRIMARY KEY AUTOINCREMENT, version TEXT)') #index self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_episode_title ON episodes (title);') @@ -69,13 +70,15 @@ class PseudoChannelDatabase(): self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_commercial_title ON commercials (title);') + self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_settings_version ON app_settings (version);') + """Setting Basic Settings """ try: self.cursor.execute("INSERT OR REPLACE INTO app_settings " "(version) VALUES (?)", - ("0.1")) + ("0.1",)) self.conn.commit() # Catch the exception @@ -92,7 +95,7 @@ class PseudoChannelDatabase(): pass - def remove_all_scheduled_items(): + def remove_all_scheduled_items(self): sql = "DELETE FROM schedule WHERE id > -1" @@ -100,10 +103,6 @@ class PseudoChannelDatabase(): self.conn.commit() - self.cursor.close() - - self.conn.close() - """Database functions. Setters, etc. @@ -176,12 +175,13 @@ class PseudoChannelDatabase(): self.conn.rollback() raise e - def add_schedule_to_db(self, mediaID, title, duration, startTime, endTime, dayOfWeek, section): + def add_schedule_to_db(self, mediaID, title, duration, startTime, endTime, dayOfWeek, startTimeUnix, section, strictTime, timeShift, overlapMax): unix = int(time.time()) try: - self.cursor.execute("INSERT INTO schedule " - "(unix, mediaID, title, duration, startTime, endTime, dayOfWeek) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", - (unix, mediaID, title, duration, startTime, endTime, dayOfWeek, section)) + self.cursor.execute("INSERT OR REPLACE INTO schedule " + "(unix, mediaID, title, duration, startTime, endTime, dayOfWeek, startTimeUnix, section, strictTime, timeShift, overlapMax) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + (unix, mediaID, title, duration, startTime, endTime, dayOfWeek, startTimeUnix, section, strictTime, timeShift, overlapMax)) self.conn.commit() # Catch the exception except Exception as e: @@ -268,7 +268,7 @@ class PseudoChannelDatabase(): def update_shows_table_with_last_episode(self, showTitle, lastEpisodeTitle): - sql1 = "UPDATE shows SET lastEpisodeTitle = ? WHERE title = ?" + sql1 = "UPDATE shows SET lastEpisodeTitle = ? WHERE title LIKE ? COLLATE NOCASE" self.cursor.execute(sql1, (lastEpisodeTitle, showTitle, )) @@ -277,21 +277,13 @@ class PseudoChannelDatabase(): def get_first_episode(self, tvshow): sql = ("SELECT id, unix, mediaID, title, duration, MIN(episodeNumber), MIN(seasonNumber), " - "showTitle FROM episodes WHERE ( showTitle = ?) COLLATE NOCASE") + "showTitle FROM episodes WHERE ( showTitle LIKE ?) COLLATE NOCASE") self.cursor.execute(sql, (tvshow, )) - datalist = list(self.cursor.fetchone()) + first_episode = self.cursor.fetchone() - if datalist > 0: - - return datalist - - else: - - print("No entry found in DB to add to schedule.") - - return None + return first_episode ''' * @@ -300,21 +292,13 @@ class PseudoChannelDatabase(): ''' def get_episode_id(self, episodeTitle): - sql = "SELECT id FROM episodes WHERE ( title = ?) COLLATE NOCASE" + sql = "SELECT id FROM episodes WHERE ( title LIKE ?) COLLATE NOCASE" self.cursor.execute(sql, (episodeTitle, )) - datalist = list(self.cursor.fetchone()) + episode_id = self.cursor.fetchone() - if datalist > 0: - - return datalist[0] - - else: - - print("No entry found in DB to add to schedule.") - - return None + return episode_id def get_next_episode(self, series): @@ -325,15 +309,15 @@ class PseudoChannelDatabase(): * determine what has been previously scheduled for each show * ''' - self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title = ?", (series, )) + self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title LIKE ? COLLATE NOCASE", (series, )) - last_title_list = list(self.cursor.fetchone()) + last_title_list = self.cursor.fetchone() ''' * * If the last episode stored in the "shows" table is empty, then this is probably a first run... * ''' - if last_title_list[0] == '': + if last_title_list and last_title_list[0] == '': ''' * @@ -354,7 +338,7 @@ class PseudoChannelDatabase(): return first_episode - else: + elif last_title_list: ''' * * The last episode stored in the "shows" table was not empty... get the next episode in the series @@ -369,8 +353,7 @@ class PseudoChannelDatabase(): * If this isn't a first run, then grabbing the next episode by incrementing id * """ - sql = ("SELECT * FROM episodes WHERE ( id > " - +str(self.get_episode_id(last_title_list[0]))+ + sql = ("SELECT * FROM episodes WHERE ( id > "+str(self.get_episode_id(last_title_list[0])[0])+ " AND showTitle LIKE ? ) ORDER BY seasonNumber LIMIT 1 COLLATE NOCASE") self.cursor.execute(sql, (series, ))