diff --git a/PseudoChannel.py b/PseudoChannel.py
index cd072b3..5c46a78 100644
--- a/PseudoChannel.py
+++ b/PseudoChannel.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
from src import PseudoChannelDatabase
@@ -28,704 +29,763 @@ sys.setdefaultencoding('utf-8')
class PseudoChannel():
- PLEX = PlexServer(config.baseurl, config.token)
+ PLEX = PlexServer(config.baseurl, config.token)
+ MEDIA = []
- MEDIA = []
+ def __init__(self):
- def __init__(self):
+ self.db = PseudoChannelDatabase("pseudo-channel.db")
- self.db = PseudoChannelDatabase("pseudo-channel.db")
+ self.controller = PseudoDailyScheduleController(config.baseurl, config.token, config.plexClients)
- self.controller = PseudoDailyScheduleController(config.baseurl, config.token, config.plexClients)
+ """Database functions.
- """Database functions.
+ update_db(): Grab the media from the Plex DB and store it in the local pseudo-channel.db.
- update_db(): Grab the media from the Plex DB and store it in the local pseudo-channel.db.
+ drop_db(): Drop the local database. Fresh start.
- drop_db(): Drop the local database. Fresh start.
+ update_schedule(): Update schedule with user defined times.
- update_schedule(): Update schedule with user defined times.
+ drop_schedule(): Drop the user defined schedule table.
- drop_schedule(): Drop the user defined schedule table.
+ generate_daily_schedule(): Generates daily schedule based on the "schedule" table.
+ """
- 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)
- # 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)),
- sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix)),
+ if iteration == total:
+ sys.stdout.write('\n')
+ sys.stdout.flush()
- if iteration == total:
- sys.stdout.write('\n')
- sys.stdout.flush()
+ def update_db(self):
- def update_db(self):
+ print("#### Updating Local Database")
- print("#### Updating Local Database")
+ self.db.create_tables()
- self.db.create_tables()
+ libs_dict = config.plexLibraries
- libs_dict = config.plexLibraries
+ sections = self.PLEX.library.sections()
- sections = self.PLEX.library.sections()
+ for section in sections:
- for section in sections:
+ for correct_lib_name, user_lib_name in libs_dict.items():
- for correct_lib_name, user_lib_name in libs_dict.items():
+ if section.title.lower() in [x.lower() for x in user_lib_name]:
- if section.title.lower() in [x.lower() for x in user_lib_name]:
+ if correct_lib_name == "Movies":
- if correct_lib_name == "Movies":
+ sectionMedia = self.PLEX.library.section(section.title).all()
- sectionMedia = self.PLEX.library.section(section.title).all()
+ for i, media in enumerate(sectionMedia):
- for i, media in enumerate(sectionMedia):
+ self.db.add_movies_to_db(1, media.title, media.duration)
- 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 = 40
+ )
- self.print_progress(
- i + 1,
- len(sectionMedia),
- prefix = 'Progress '+section.title+": ",
- suffix = 'Complete',
- bar_length = 40
- )
+ elif correct_lib_name == "TV Shows":
- elif correct_lib_name == "TV Shows":
+ sectionMedia = self.PLEX.library.section(section.title).all()
- sectionMedia = self.PLEX.library.section(section.title).all()
+ for i, media in enumerate(sectionMedia):
- for i, media in enumerate(sectionMedia):
+ backgroundImagePath = self.PLEX.library.section(section.title).get(media.title)
- backgroundImagePath = self.PLEX.library.section(section.title).get(media.title)
+ backgroundImgURL = ''
- backgroundImgURL = ''
+ if isinstance(backgroundImagePath.art, str):
- if isinstance(backgroundImagePath.art, str):
+ backgroundImgURL = config.baseurl+backgroundImagePath.art+"?X-Plex-Token="+config.token
- backgroundImgURL = config.baseurl+backgroundImagePath.art+"?X-Plex-Token="+config.token
+ self.db.add_shows_to_db(2, media.title, media.duration, '', backgroundImgURL)
- 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 = 40
+ )
- self.print_progress(
- i + 1,
- len(sectionMedia),
- prefix = 'Progress '+section.title+": ",
- suffix = 'Complete',
- bar_length = 40
- )
+ #add all episodes of each tv show to episodes table
+ episodes = self.PLEX.library.section(section.title).get(media.title).episodes()
- #add all episodes of each tv show to episodes table
- episodes = self.PLEX.library.section(section.title).get(media.title).episodes()
+ for episode in episodes:
- for episode in episodes:
+ duration = episode.duration
- duration = episode.duration
+ if duration:
- if duration:
+ self.db.add_episodes_to_db(
+ 4,
+ episode.title,
+ duration,
+ episode.index,
+ episode.parentIndex,
+ media.title
+ )
- self.db.add_episodes_to_db(
- 4,
- episode.title,
- duration,
- episode.index,
- episode.parentIndex,
- media.title
- )
+ else:
- else:
+ self.db.add_episodes_to_db(
+ 4,
+ episode.title,
+ 0,
+ episode.index,
+ episode.parentIndex,
+ media.title
+ )
- self.db.add_episodes_to_db(
- 4,
- episode.title,
- 0,
- episode.index,
- episode.parentIndex,
- media.title
- )
+ elif correct_lib_name == "Commercials":
- elif correct_lib_name == "Commercials":
+ sectionMedia = self.PLEX.library.section(section.title).all()
- sectionMedia = self.PLEX.library.section(section.title).all()
+ media_length = len(sectionMedia)
- media_length = len(sectionMedia)
+ for i, media in enumerate(sectionMedia):
- for i, media in enumerate(sectionMedia):
+ self.db.add_commercials_to_db(3, media.title, media.duration)
- self.db.add_commercials_to_db(3, media.title, media.duration)
+ self.print_progress(
+ i + 1,
+ media_length,
+ prefix = 'Progress '+section.title+":",
+ suffix = 'Complete',
+ bar_length = 40
+ )
- self.print_progress(
- i + 1,
- media_length,
- prefix = 'Progress '+section.title+":",
- suffix = 'Complete',
- bar_length = 40
- )
+ def update_schedule(self):
- def update_schedule(self):
+ self.db.create_tables()
- self.db.create_tables()
+ self.db.remove_all_scheduled_items()
- self.db.remove_all_scheduled_items()
+ scheduled_days_list = [
+ "mondays",
+ "tuesdays",
+ "wednesdays",
+ "thursdays",
+ "fridays",
+ "saturdays",
+ "sundays",
+ "weekdays",
+ "weekends",
+ "everyday"
+ ]
- scheduled_days_list = [
- "mondays",
- "tuesdays",
- "wednesdays",
- "thursdays",
- "fridays",
- "saturdays",
- "sundays",
- "weekdays",
- "weekends",
- "everyday"
- ]
+ section_dict = {
+ "TV Shows" : ["series", "shows", "tv", "episodes", "tv shows", "show"],
+ "Movies" : ["movie", "movies", "films", "film"],
+ "Videos" : ["video", "videos", "vid"],
+ "Music" : ["music", "songs", "song", "tune", "tunes"]
+ }
- section_dict = {
- "TV Shows" : ["series", "shows", "tv", "episodes", "tv shows", "show"],
- "Movies" : ["movie", "movies", "films", "film"],
- "Videos" : ["video", "videos", "vid"],
- "Music" : ["music", "songs", "song", "tune", "tunes"]
- }
+ tree = ET.parse('pseudo_schedule.xml')
- tree = ET.parse('pseudo_schedule.xml')
+ root = tree.getroot()
- root = tree.getroot()
+ for child in root:
- for child in root:
+ if child.tag in scheduled_days_list:
- if child.tag in scheduled_days_list:
+ for time in child.iter("time"):
- for time in child.iter("time"):
+ for key, value in section_dict.items():
- for key, value in section_dict.items():
+ if time.attrib['type'] == key or time.attrib['type'] in value:
- if time.attrib['type'] == key or time.attrib['type'] in value:
+ title = time.attrib['title']
- title = time.attrib['title']
+ natural_start_time = self.translate_time(time.text)
- natural_start_time = self.translate_time(time.text)
+ natural_end_time = 0
- natural_end_time = 0
+ section = key
- section = key
+ day_of_week = child.tag
- day_of_week = child.tag
+ strict_time = time.attrib['strict-time']
- strict_time = time.attrib['strict-time']
+ time_shift = time.attrib['time-shift']
- time_shift = time.attrib['time-shift']
+ overlap_max = time.attrib['overlap-max']
- overlap_max = time.attrib['overlap-max']
+ start_time_unix = datetime.datetime.strptime(
+ self.translate_time(time.text),
+ '%I:%M %p').strftime('%Y-%m-%d %H:%M:%S')
- start_time_unix = datetime.datetime.strptime(
- self.translate_time(time.text),
- '%I:%M %p').strftime('%Y-%m-%d %H:%M:%S')
+ print "Adding: ", time.tag, section, time.text, time.attrib['title']
- 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
+ )
- 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):
- def drop_db(self):
+ self.db.drop_db()
- self.db.drop_db()
+ def drop_schedule(self):
- def drop_schedule(self):
+ self.db.drop_schedule()
- self.db.drop_schedule()
+ def remove_all_scheduled_items():
- def remove_all_scheduled_items():
+ self.db.remove_all_scheduled_items()
- self.db.remove_all_scheduled_items()
+ """App functions.
- """App functions.
+ generate_daily_schedule(): Generate the daily_schedule table.
+ """
- generate_daily_schedule(): Generate the daily_schedule table.
- """
+ '''
+ *
+ * Using datetime to figure out when the media item will end based on the scheduled start time or the offset
+ * generated by the previous media item.
- '''
- *
- * Using datetime to figure out when the media item will end based on the scheduled start time or the offset
- * generated by the previous media item.
+ * Returns time
+ *
+ '''
+ '''
+ *
+ * Returns time difference in minutes
+ *
+ '''
- * Returns time
- *
- '''
- '''
- *
- * Returns time difference in minutes
- *
- '''
+ def translate_time(self, timestr):
- def translate_time(self, timestr):
+ try:
- try:
+ return datetime.datetime.strptime(timestr, "%I:%M %p").strftime("%-I:%M %p")
- return datetime.datetime.strptime(timestr, "%I:%M %p").strftime("%-I:%M %p")
+ except ValueError as e:
- except ValueError as e:
+ pass
- pass
+ try:
- try:
+ return datetime.datetime.strptime(timestr, "%H:%M").strftime("%-I:%M %p")
- return datetime.datetime.strptime(timestr, "%H:%M").strftime("%-I:%M %p")
+ except ValueError as e:
- except ValueError as e:
+ pass
- pass
+ def time_diff(self, time1,time2):
+ '''
+ *
+ * Getting the offest by comparing both times from the unix epoch time and getting the difference.
+ *
+ '''
+ timeA = datetime.datetime.strptime(time1, "%I:%M %p")
+ timeB = datetime.datetime.strptime(time2, "%I:%M %p")
+
+ timeAEpoch = calendar.timegm(timeA.timetuple())
+ timeBEpoch = calendar.timegm(timeB.timetuple())
- def time_diff(self, time1,time2):
- '''
- *
- * Getting the offest by comparing both times from the unix epoch time and getting the difference.
- *
- '''
- timeA = datetime.datetime.strptime(time1, "%I:%M %p")
- timeB = datetime.datetime.strptime(time2, "%I:%M %p")
-
- timeAEpoch = calendar.timegm(timeA.timetuple())
- timeBEpoch = calendar.timegm(timeB.timetuple())
+ tdelta = abs(timeAEpoch) - abs(timeBEpoch)
- tdelta = abs(timeAEpoch) - abs(timeBEpoch)
+ return int(tdelta/60)
- return int(tdelta/60)
+ '''
+ *
+ * Passing in the endtime from the prev episode and desired start time of this episode, calculate the best start time
- '''
- *
- * Passing in the endtime from the prev episode and desired start time of this episode, calculate the best start time
+ * Returns time - for new start time
+ *
+ '''
+ def calculate_start_time(self, prevEndTime, intendedStartTime, timeGap, overlapMax):
- * Returns time - for new start time
- *
- '''
- def calculate_start_time(self, prevEndTime, intendedStartTime, timeGap, overlapMax):
+ self.TIME_GAP = timeGap
- self.TIME_GAP = timeGap
+ self.OVERLAP_GAP = timeGap
- self.OVERLAP_GAP = timeGap
+ self.OVERLAP_MAX = overlapMax
- self.OVERLAP_MAX = overlapMax
+ time1 = prevEndTime.strftime('%-I:%M %p')
- time1 = prevEndTime.strftime('%-I:%M %p')
+ timeB = datetime.datetime.strptime(intendedStartTime, '%I:%M %p').strftime('%-I:%M %p')
- timeB = datetime.datetime.strptime(intendedStartTime, '%I:%M %p').strftime('%-I:%M %p')
+ print "++++ Previous End Time: ", time1, "Intended start time: ", timeB
- print "++++ Previous End Time: ", time1, "Intended start time: ", timeB
+ timeDiff = self.time_diff(time1, timeB)
- timeDiff = self.time_diff(time1, timeB)
+ """print("timeDiff "+ str(timeDiff))
+ print("startTimeUNIX: "+ str(intendedStartTime))"""
- """print("timeDiff "+ str(timeDiff))
- print("startTimeUNIX: "+ str(intendedStartTime))"""
+ newTimeObj = timeB
- newTimeObj = timeB
+ newStartTime = timeB
- newStartTime = timeB
+ '''
+ *
+ * If time difference is negative, then we know there is overlap
+ *
+ '''
+ if timeDiff < 0:
+ '''
+ *
+ * If there is an overlap, then the overlapGap var in config will determine the next increment. If it is set to "15", then the show will will bump up to the next 15 minute interval past the hour.
+ *
+ '''
+ timeset=[datetime.time(h,m).strftime("%H:%M") for h,m in itertools.product(xrange(0,24),xrange(0,60,int(self.OVERLAP_GAP)))]
+
+ #print(timeset)
- '''
- *
- * If time difference is negative, then we know there is overlap
- *
- '''
- if timeDiff < 0:
- '''
- *
- * If there is an overlap, then the overlapGap var in config will determine the next increment. If it is set to "15", then the show will will bump up to the next 15 minute interval past the hour.
- *
- '''
- timeset=[datetime.time(h,m).strftime("%H:%M") for h,m in itertools.product(xrange(0,24),xrange(0,60,int(self.OVERLAP_GAP)))]
-
- #print(timeset)
+ timeSetToUse = None
- timeSetToUse = None
+ for time in timeset:
- for time in timeset:
+ #print(time)
+ theTimeSetInterval = datetime.datetime.strptime(time, '%H:%M')
- #print(time)
- theTimeSetInterval = datetime.datetime.strptime(time, '%H:%M')
+ # print(theTimeSetInterval)
- # print(theTimeSetInterval)
+ # print(prevEndTime)
- # print(prevEndTime)
+ if theTimeSetInterval >= prevEndTime:
- if theTimeSetInterval >= prevEndTime:
+ print "++++ There is overlap. Setting new time-interval:", theTimeSetInterval
- print "++++ There is overlap. Setting new time-interval:", theTimeSetInterval
+ newStartTime = theTimeSetInterval
- newStartTime = theTimeSetInterval
+ break
- break
+ #newStartTime = newTimeObj + datetime.timedelta(minutes=abs(timeDiff + overlapGap))
- #newStartTime = newTimeObj + datetime.timedelta(minutes=abs(timeDiff + overlapGap))
+ elif (timeDiff >= 0) and (self.TIME_GAP != -1):
- elif (timeDiff >= 0) and (self.TIME_GAP != -1):
+ '''
+ *
+ * If there this value is configured, then the timeGap var in config will determine the next increment.
+ * If it is set to "15", then the show will will bump up to the next 15 minute interval past the hour.
+ *
+ '''
+ timeset=[datetime.time(h,m).strftime("%H:%M") for h,m in itertools.product(xrange(0,24),xrange(0,60,int(self.TIME_GAP)))]
+
+ # print(timeset)
- '''
- *
- * If there this value is configured, then the timeGap var in config will determine the next increment.
- * If it is set to "15", then the show will will bump up to the next 15 minute interval past the hour.
- *
- '''
- timeset=[datetime.time(h,m).strftime("%H:%M") for h,m in itertools.product(xrange(0,24),xrange(0,60,int(self.TIME_GAP)))]
-
- # print(timeset)
+ for time in timeset:
- for time in timeset:
+ theTimeSetInterval = datetime.datetime.strptime(time, '%H:%M')
- theTimeSetInterval = datetime.datetime.strptime(time, '%H:%M')
+ tempTimeTwoStr = datetime.datetime.strptime(time1, '%I:%M %p').strftime('%H:%M')
- tempTimeTwoStr = datetime.datetime.strptime(time1, '%I:%M %p').strftime('%H:%M')
+ formatted_time_two = datetime.datetime.strptime(tempTimeTwoStr, '%H:%M')
- formatted_time_two = datetime.datetime.strptime(tempTimeTwoStr, '%H:%M')
+ if theTimeSetInterval >= formatted_time_two:
- if theTimeSetInterval >= formatted_time_two:
+ print "++++ Setting new time-interval:", theTimeSetInterval
- print "++++ Setting new time-interval:", theTimeSetInterval
+ newStartTime = theTimeSetInterval
- newStartTime = theTimeSetInterval
+ break
- break
+ else:
- else:
+ print("Not sure what to do here")
- print("Not sure what to do here")
+ return newStartTime.strftime('%-I:%M %p')
- return newStartTime.strftime('%-I:%M %p')
+ def get_end_time_from_duration(self, startTime, duration):
- def get_end_time_from_duration(self, startTime, duration):
+ time = datetime.datetime.strptime(startTime, '%I:%M %p')
- time = datetime.datetime.strptime(startTime, '%I:%M %p')
+ show_time_plus_duration = time + datetime.timedelta(milliseconds=duration)
- show_time_plus_duration = time + datetime.timedelta(milliseconds=duration)
+ #print(show_time_plus_duration.minute)
- #print(show_time_plus_duration.minute)
+ return show_time_plus_duration
- return show_time_plus_duration
+ def generate_daily_schedule(self):
- def generate_daily_schedule(self):
+ print("#### Generating Daily Schedule")
- print("#### Generating Daily Schedule")
+ schedule = self.db.get_schedule()
- schedule = self.db.get_schedule()
+ weekday_dict = {
+ "0" : ["mondays", "weekdays", "everyday"],
+ "1" : ["tuesdays", "weekdays", "everyday"],
+ "2" : ["wednesdays", "weekdays", "everyday"],
+ "3" : ["thursdays", "weekdays", "everyday"],
+ "4" : ["fridays", "weekdays", "everyday"],
+ "5" : ["saturdays", "weekends", "everyday"],
+ "6" : ["sundays", "weekends", "everyday"],
+ }
- weekday_dict = {
- "0" : ["mondays", "weekdays", "everyday"],
- "1" : ["tuesdays", "weekdays", "everyday"],
- "2" : ["wednesdays", "weekdays", "everyday"],
- "3" : ["thursdays", "weekdays", "everyday"],
- "4" : ["fridays", "weekdays", "everyday"],
- "5" : ["saturdays", "weekends", "everyday"],
- "6" : ["sundays", "weekends", "everyday"],
- }
+ weekno = datetime.datetime.today().weekday()
- weekno = datetime.datetime.today().weekday()
+ schedule_advance_watcher = 0
- schedule_advance_watcher = 0
+ for entry in schedule:
- for entry in schedule:
+ schedule_advance_watcher += 1
- schedule_advance_watcher += 1
+ section = entry[9]
- section = entry[9]
+ for key, val in weekday_dict.iteritems():
- for key, val in weekday_dict.iteritems():
+ if str(entry[7]) in str(val) and int(weekno) == int(key):
- if str(entry[7]) in str(val) and int(weekno) == int(key):
+ if section == "TV Shows":
- if section == "TV Shows":
+ if entry[3] == "random":
- if entry[3] == "random":
+ next_episode = self.db.get_random_episode()
- next_episode = self.db.get_random_episode()
+ else:
- else:
+ next_episode = self.db.get_next_episode(entry[3])
- next_episode = self.db.get_next_episode(entry[3])
+ if next_episode != None:
+
+ episode = Episode(
+ section, # section_type
+ next_episode[3], # title
+ entry[5], # natural_start_time
+ self.get_end_time_from_duration(entry[5], next_episode[4]), # natural_end_time
+ next_episode[4], # duration
+ entry[7], # day_of_week
+ entry[10], # is_strict_time
+ entry[11], # time_shift
+ entry[12], # overlap_max
+ entry[3], # show_series_title
+ next_episode[5], # episode_number
+ next_episode[6] # season_number
+ )
- if next_episode != None:
-
- episode = Episode(
- section, # section_type
- next_episode[3], # title
- entry[5], # natural_start_time
- self.get_end_time_from_duration(entry[5], next_episode[4]), # natural_end_time
- next_episode[4], # duration
- entry[7], # day_of_week
- entry[10], # is_strict_time
- entry[11], # time_shift
- entry[12], # overlap_max
- entry[3], # show_series_title
- next_episode[5], # episode_number
- next_episode[6] # season_number
- )
+ self.MEDIA.append(episode)
- self.MEDIA.append(episode)
+ else:
- else:
+ print("Cannot find TV Show Episode, {} in the local db".format(entry[3]))
- print("Cannot find TV Show Episode, {} in the local db".format(entry[3]))
+ #print(episode)
- #print(episode)
+ elif section == "Movies":
- elif section == "Movies":
+ if entry[3] == "random":
- if entry[3] == "random":
+ the_movie = self.db.get_random_movie()
- the_movie = self.db.get_random_movie()
+ else:
- else:
+ the_movie = self.db.get_movie(entry[3])
- the_movie = self.db.get_movie(entry[3])
+ if the_movie != None:
- if the_movie != None:
+ movie = Movie(
+ section, # section_type
+ the_movie[3], # title
+ entry[5], # natural_start_time
+ self.get_end_time_from_duration(entry[5], the_movie[4]), # natural_end_time
+ the_movie[4], # duration
+ entry[7], # day_of_week
+ entry[10], # is_strict_time
+ entry[11], # time_shift
+ entry[12] # overlap_max
+ )
- movie = Movie(
- section, # section_type
- the_movie[3], # title
- entry[5], # natural_start_time
- self.get_end_time_from_duration(entry[5], the_movie[4]), # natural_end_time
- the_movie[4], # duration
- entry[7], # day_of_week
- entry[10], # is_strict_time
- entry[11], # time_shift
- entry[12] # overlap_max
- )
+ #print(movie.natural_end_time)
- #print(movie.natural_end_time)
+ self.MEDIA.append(movie)
- self.MEDIA.append(movie)
+ else:
- else:
+ print("Cannot find Movie, {} in the local db".format(entry[3]))
- print("Cannot find Movie, {} in the local db".format(entry[3]))
+ elif section == "Music":
- elif section == "Music":
+ the_music = self.db.get_music(entry[3])
- the_music = self.db.get_music(entry[3])
+ if the_music != None:
- if the_music != None:
+ music = Music(
+ section, # section_type
+ the_music[3], # title
+ entry[5], # natural_start_time
+ self.get_end_time_from_duration(entry[5], the_music[4]), # natural_end_time
+ the_music[4], # duration
+ entry[7], # day_of_week
+ entry[10], # is_strict_time
+ entry[11], # time_shift
+ entry[12] # overlap_max
+ )
- music = Music(
- section, # section_type
- the_music[3], # title
- entry[5], # natural_start_time
- self.get_end_time_from_duration(entry[5], the_music[4]), # natural_end_time
- the_music[4], # duration
- entry[7], # day_of_week
- entry[10], # is_strict_time
- entry[11], # time_shift
- entry[12] # overlap_max
- )
+ #print(music.natural_end_time)
- #print(music.natural_end_time)
+ self.MEDIA.append(music)
- self.MEDIA.append(music)
+ else:
- else:
+ print("Cannot find Music, {} in the local db".format(entry[3]))
- print("Cannot find Music, {} in the local db".format(entry[3]))
+ elif section == "Video":
- elif section == "Video":
+ the_video = self.db.get_video(entry[3])
- the_video = self.db.get_video(entry[3])
+ if the_music != None:
- if the_music != None:
+ video = Video(
+ section, # section_type
+ the_video[3], # title
+ entry[5], # natural_start_time
+ self.get_end_time_from_duration(entry[5], the_video[4]), # natural_end_time
+ the_video[4], # duration
+ entry[7], # day_of_week
+ entry[10], # is_strict_time
+ entry[11], # time_shift
+ entry[12] # overlap_max
+ )
- video = Video(
- section, # section_type
- the_video[3], # title
- entry[5], # natural_start_time
- self.get_end_time_from_duration(entry[5], the_video[4]), # natural_end_time
- the_video[4], # duration
- entry[7], # day_of_week
- entry[10], # is_strict_time
- entry[11], # time_shift
- entry[12] # overlap_max
- )
+ #print(music.natural_end_time)
- #print(music.natural_end_time)
+ self.MEDIA.append(video)
- self.MEDIA.append(video)
+ else:
- else:
+ print("Cannot find Video, {} in the local db".format(entry[3]))
- print("Cannot find Video, {} in the local db".format(entry[3]))
+ else:
- else:
+ pass
- pass
+ """If we reached the end of the scheduled items for today, add them to the daily schedule
- """If we reached the end of the scheduled items for today, add them to the daily schedule
+ """
+ if schedule_advance_watcher >= len(schedule):
- """
- if schedule_advance_watcher >= len(schedule):
+ print "+++++ Finished processing time entries, recreating daily_schedule"
- print "+++++ Finished processing time entries, recreating daily_schedule"
+ previous_episode = None
- previous_episode = None
+ self.db.remove_all_daily_scheduled_items()
- self.db.remove_all_daily_scheduled_items()
+ for entry in self.MEDIA:
- for entry in self.MEDIA:
+ #print entry.natural_end_time
- #print entry.natural_end_time
+ if previous_episode != None:
- if previous_episode != None:
+ natural_start_time = datetime.datetime.strptime(entry.natural_start_time, '%I:%M %p')
- natural_start_time = datetime.datetime.strptime(entry.natural_start_time, '%I:%M %p')
+ natural_end_time = entry.natural_end_time
- natural_end_time = entry.natural_end_time
+ if entry.is_strict_time.lower() == "true":
- if entry.is_strict_time.lower() == "true":
+ print "++++ Strict-time: {}".format(str(entry.title))
- print "++++ Strict-time: {}".format(str(entry.title))
+ entry.end_time = self.get_end_time_from_duration(
+ self.translate_time(entry.start_time),
+ entry.duration
+ )
- entry.end_time = self.get_end_time_from_duration(
- self.translate_time(entry.start_time),
- entry.duration
- )
+ self.db.add_media_to_daily_schedule(entry)
- self.db.add_media_to_daily_schedule(entry)
+ previous_episode = entry
- previous_episode = entry
+ else:
- else:
+ print "++++ NOT strict-time: {}".format(str(entry.title).encode(sys.stdout.encoding, errors='replace'))
- print "++++ NOT strict-time: {}".format(str(entry.title).encode(sys.stdout.encoding, errors='replace'))
+ new_starttime = self.calculate_start_time(
+ previous_episode.end_time,
+ entry.natural_start_time,
+ previous_episode.time_shift,
+ previous_episode.overlap_max
+ )
- new_starttime = self.calculate_start_time(
- previous_episode.end_time,
- entry.natural_start_time,
- previous_episode.time_shift,
- previous_episode.overlap_max
- )
+ print "++++ New start time:", new_starttime
- print "++++ New start time:", new_starttime
+ entry.start_time = datetime.datetime.strptime(new_starttime, '%I:%M %p').strftime('%-I:%M %p')
- entry.start_time = datetime.datetime.strptime(new_starttime, '%I:%M %p').strftime('%-I:%M %p')
+ entry.end_time = self.get_end_time_from_duration(entry.start_time, entry.duration)
- entry.end_time = self.get_end_time_from_duration(entry.start_time, entry.duration)
+ self.db.add_media_to_daily_schedule(entry)
- self.db.add_media_to_daily_schedule(entry)
+ previous_episode = entry
- previous_episode = entry
+ else:
- else:
+ self.db.add_media_to_daily_schedule(entry)
- self.db.add_media_to_daily_schedule(entry)
+ previous_episode = entry
- previous_episode = entry
+ def show_clients(self):
+
+ print "##### Connected Clients:"
+
+ for i, client in enumerate(self.PLEX.clients()):
+
+ print "+++++", str(i + 1)+".", "Client:", client.title
+
+ def show_schedule(self):
+
+ print "##### Daily Pseudo Schedule:"
+
+ daily_schedule = self.db.get_daily_schedule()
+
+ for i , entry in enumerate(daily_schedule):
+
+ print "+++++", str(i + 1)+".", entry[11], entry[8], entry[6], " - ", entry[3]
+
+ def exit_app(self):
+
+ print "Exiting Pseudo TV & cleaning up."
+
+ for i in self.MEDIA:
+
+ del i
+
+ self.MEDIA = None
+
+ self.controller = None
+
+ self.db = None
+
+ sleep(1)
if __name__ == '__main__':
- pseudo_channel = PseudoChannel()
+ pseudo_channel = PseudoChannel()
- #pseudo_channel.db.create_tables()
+ #pseudo_channel.db.create_tables()
- #pseudo_channel.update_db()
+ #pseudo_channel.update_db()
- #pseudo_channel.update_schedule()
+ #pseudo_channel.update_schedule()
- #pseudo_channel.generate_daily_schedule()
+ #pseudo_channel.generate_daily_schedule()
- parser = argparse.ArgumentParser(
- description="Pseudo Channel for Plex. Update pseduo_config.py & pseudo_schedule.xml before this step.",
- usage="PseudoChannel.py [-u] update local db with plex db [-xml] update db with xml schedule data [-g] generate daily schedule [-r] run the app"
+ parser = argparse.ArgumentParser(
+ description="Pseudo Channel for Plex. Update pseduo_config.py & pseudo_schedule.xml before this step.",
+ usage="PseudoChannel.py [-u] update local db with plex db [-xml] update db " \
+ "with xml schedule data [-g] generate daily schedule [-r] run the app"
)
- parser.add_argument('-u', action='store_true')
- parser.add_argument('-xml', action='store_true')
- parser.add_argument('-g', action='store_true')
- parser.add_argument('-r', action='store_true')
+ '''
+ *
+ * Primary arguments: "python PseudoChannel.py -u -xml -g -r"
+ *
+ '''
- '''
- *
- * Show connected clients: "python PseudoChannel.py -u -xml -g -r"
- *
- '''
- parser.add_argument('-sc', action='store_true')
+ parser.add_argument('-u', action='store_true')
+ parser.add_argument('-xml', action='store_true')
+ parser.add_argument('-g', action='store_true')
+ parser.add_argument('-r', action='store_true')
- globals().update(vars(parser.parse_args()))
+ '''
+ *
+ * Show connected clients: "python PseudoChannel.py -c"
+ *
+ '''
+ parser.add_argument('-c', action='store_true')
- args = parser.parse_args()
+ '''
+ *
+ * Show schedule (daily): "python PseudoChannel.py -s"
+ *
+ '''
+ parser.add_argument('-s', action='store_true')
- print(args)
+ globals().update(vars(parser.parse_args()))
- if args.u:
+ args = parser.parse_args()
- pseudo_channel.update_db()
+ #print(args)
- if args.xml:
+ if args.u:
- pseudo_channel.update_schedule()
+ pseudo_channel.update_db()
- if args.g:
+ if args.xml:
- pseudo_channel.generate_daily_schedule()
+ pseudo_channel.update_schedule()
- if args.r:
+ if args.g:
- try:
+ pseudo_channel.generate_daily_schedule()
- print "++++ Running TV Controller"
-
- """Every minute on the minute check the DB startTimes of all media to
- determine whether or not to play. Also, check the now_time to
- see if it's midnight (or 23.59), if so then generate a new daily_schedule
-
- """
- while True:
+ if args.c:
- now = datetime.datetime.now()
+ pseudo_channel.show_clients()
- now_time = now.time()
+ if args.s:
- if now_time == time(23,59):
+ pseudo_channel.show_schedule()
- pseudo_channel.generate_daily_schedule()
+ if args.r:
- pseudo_channel.controller.tv_controller(pseudo_channel.db.get_daily_schedule())
+ try:
- t = datetime.datetime.utcnow()
+ print "##### Running TV Controller"
+ print "+++++ To run this in the background:"
+ print "+++++", "screen -d -m bash -c 'python PseudoChannel.py -r; exec sh'"
+
+ """Every minute on the minute check the DB startTimes of all media to
+ determine whether or not to play. Also, check the now_time to
+ see if it's midnight (or 23.59), if so then generate a new daily_schedule
+
+ """
+ while True:
- sleeptime = 60 - (t.second + t.microsecond/1000000.0)
+ now = datetime.datetime.now()
- sleep(sleeptime)
+ now_time = now.time()
- except KeyboardInterrupt, e:
+ if now_time == time(23,59):
- pass
-
+ pseudo_channel.generate_daily_schedule()
+
+ pseudo_channel.controller.tv_controller(pseudo_channel.db.get_daily_schedule())
+
+ t = datetime.datetime.utcnow()
+
+ sleeptime = 60 - (t.second + t.microsecond/1000000.0)
+
+ sleep(sleeptime)
+
+ except KeyboardInterrupt, e:
+
+ pseudo_channel.exit_app()
+
+ del pseudo_channel
+
diff --git a/pseudo_config.py b/pseudo_config.py
index bd79793..07f3c50 100644
--- a/pseudo_config.py
+++ b/pseudo_config.py
@@ -1,23 +1,24 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+
"""
- 1) Create a file outside of this proj dir called "plex_token.py":
+ 1) Create a file outside of this proj dir called "plex_token.py":
- touch ../plex_token.py
-
- 2) add this line to the newly created file:
+ touch ../plex_token.py
+
+ 2) add this line to the newly created file:
- token = 'your plex token'
+ token = 'your plex token'
- 3) Edit the "basurl" variable below to point to your Plex server
+ 3) Edit the "basurl" variable below to point to your Plex server
- 4) Edit the "plexClients" variable to include the name of your plex client(s) this app will control.
+ 4) Edit the "plexClients" variable to include the name of your plex client(s) this app will control.
- 5) Edit the "plexLibraries" variable to remap your specific library names to the app specific names.
- ...for instance, if your Plex "Movies" are located in your Plex library as "Films", update that
- line so it looks like:
+ 5) Edit the "plexLibraries" variable to remap your specific library names to the app specific names.
+ ...for instance, if your Plex "Movies" are located in your Plex library as "Films", update that
+ line so it looks like:
- "Movies" : ["Films"],
-
+ "Movies" : ["Films"],
+
"""
import os, sys
@@ -36,8 +37,8 @@ token = plex_token.token
plexClients = ['RasPlex']
plexLibraries = {
- "TV Shows" : ["TV Shows"],
- "Movies" : ["Movies"],
- "Music" : ["Music"],
- "Commercials" : ["Commercials"],
+ "TV Shows" : ["TV Shows"],
+ "Movies" : ["Movies"],
+ "Music" : ["Music"],
+ "Commercials" : ["Commercials"],
}
diff --git a/pseudo_schedule.xml b/pseudo_schedule.xml
index f5e7ac8..9c0e60f 100644
--- a/pseudo_schedule.xml
+++ b/pseudo_schedule.xml
@@ -1,65 +1,65 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
@@ -92,7 +92,7 @@
-
+
-
+
diff --git a/src/Commercial.py b/src/Commercial.py
index 10b9a92..254c4da 100644
--- a/src/Commercial.py
+++ b/src/Commercial.py
@@ -1,8 +1,10 @@
+#!/usr/bin/env python
+
from Media import Media
class Commercial(Media):
- """Inherits Media.
+ """Inherits Media.
Attributes:
section_type: The type of library this is (i.e. "TV Shows")
@@ -14,27 +16,27 @@ class Commercial(Media):
is_strict_time: If strict time, then anchor to "natural_start_time"
"""
- def __init__(
- self,
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- ):
+ def __init__(
+ self,
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ ):
- super(Commercial, self).__init__(
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- )
+ super(Commercial, self).__init__(
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ )
diff --git a/src/Episode.py b/src/Episode.py
index 3c579d5..a9f902e 100644
--- a/src/Episode.py
+++ b/src/Episode.py
@@ -1,8 +1,10 @@
+#!/usr/bin/env python
+
from Media import Media
class Episode(Media):
- """Inherits Media.
+ """Inherits Media.
Attributes:
section_type: The type of library this is (i.e. "TV Shows")
@@ -13,38 +15,38 @@ class Episode(Media):
day_of_week: When the content is scheduled to play
is_strict_time: If strict time, then anchor to "natural_start_time"
show_series_title: The series title (i.e. "Friends")
- episode_number: The episode number in the Season
- season_number: The number of season in the series.
+ episode_number: The episode number in the Season
+ season_number: The number of season in the series.
"""
- def __init__(
- self,
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max,
- show_series_title,
- episode_number,
- season_number
- ):
+ def __init__(
+ self,
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max,
+ show_series_title,
+ episode_number,
+ season_number
+ ):
- super(Episode, self).__init__(
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- )
+ super(Episode, self).__init__(
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ )
- self.show_series_title = show_series_title
- self.episode_number = episode_number
- self.season_number = season_number
+ self.show_series_title = show_series_title
+ self.episode_number = episode_number
+ self.season_number = season_number
diff --git a/src/Media.py b/src/Media.py
index 66e72d7..992261f 100644
--- a/src/Media.py
+++ b/src/Media.py
@@ -1,13 +1,15 @@
+#!/usr/bin/env python
+
"""
*** Inherited by Commercial, Episode & Movie
"""
class Media(object):
- plex_server_url = ''
- plex_server_token = ''
- media_image = ''
+ plex_server_url = ''
+ plex_server_token = ''
+ media_image = ''
- """A base class for media objects.
+ """A base class for media objects.
Attributes:
section_type: The type of library this is (i.e. "TV Shows")
@@ -19,29 +21,29 @@ class Media(object):
is_strict_time: If strict time, then anchor to "natural_start_time"
"""
- def __init__(
- self,
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- ):
+ def __init__(
+ self,
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ ):
- self.section_type = section_type
- self.title = title
- self.natural_start_time = natural_start_time
- self.natural_end_time = natural_end_time
- self.duration = duration
- self.day_of_week = day_of_week
- self.is_strict_time = is_strict_time
- self.time_shift = time_shift
- self.overlap_max = overlap_max
+ self.section_type = section_type
+ self.title = title
+ self.natural_start_time = natural_start_time
+ self.natural_end_time = natural_end_time
+ self.duration = duration
+ self.day_of_week = day_of_week
+ self.is_strict_time = is_strict_time
+ self.time_shift = time_shift
+ self.overlap_max = overlap_max
- self.start_time = natural_start_time
- self.end_time = natural_end_time
+ self.start_time = natural_start_time
+ self.end_time = natural_end_time
diff --git a/src/Movie.py b/src/Movie.py
index a8258b0..d2975d8 100644
--- a/src/Movie.py
+++ b/src/Movie.py
@@ -1,8 +1,10 @@
+#!/usr/bin/env python
+
from Media import Media
class Movie(Media):
- """Inherits Media.
+ """Inherits Media.
Attributes:
section_type: The type of library this is (i.e. "TV Shows")
@@ -14,27 +16,27 @@ class Movie(Media):
is_strict_time: If strict time, then anchor to "natural_start_time"
"""
- def __init__(
- self,
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- ):
+ def __init__(
+ self,
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ ):
- super(Movie, self).__init__(
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- )
+ super(Movie, self).__init__(
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ )
diff --git a/src/Music.py b/src/Music.py
index 0ac53bb..4b8ee25 100644
--- a/src/Music.py
+++ b/src/Music.py
@@ -1,8 +1,10 @@
+#!/usr/bin/env python
+
from Media import Media
class Music(Media):
- """Inherits Media.
+ """Inherits Media.
Attributes:
section_type: The type of library this is (i.e. "TV Shows")
@@ -14,27 +16,27 @@ class Music(Media):
is_strict_time: If strict time, then anchor to "natural_start_time"
"""
- def __init__(
- self,
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- ):
+ def __init__(
+ self,
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ ):
- super(Music, self).__init__(
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- )
+ super(Music, self).__init__(
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ )
diff --git a/src/PseudoChannelDatabase.py b/src/PseudoChannelDatabase.py
index bed59f8..5391edd 100644
--- a/src/PseudoChannelDatabase.py
+++ b/src/PseudoChannelDatabase.py
@@ -1,472 +1,474 @@
+#!/usr/bin/env python
+
import sqlite3
import datetime
import time
class PseudoChannelDatabase():
- def __init__(self, db):
+ def __init__(self, db):
- self.db = db
+ self.db = db
- self.conn = sqlite3.connect(self.db)
+ self.conn = sqlite3.connect(self.db)
- self.cursor = self.conn.cursor()
+ self.cursor = self.conn.cursor()
- """Database functions.
+ """Database functions.
- Utilities, etc.
- """
+ Utilities, etc.
+ """
- def create_tables(self):
+ def create_tables(self):
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'movies(id INTEGER PRIMARY KEY AUTOINCREMENT, '
- 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, lastPlayedDate TEXT)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'movies(id INTEGER PRIMARY KEY AUTOINCREMENT, '
+ 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, lastPlayedDate TEXT)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'videos(id INTEGER PRIMARY KEY AUTOINCREMENT, '
- 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'videos(id INTEGER PRIMARY KEY AUTOINCREMENT, '
+ 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'music(id INTEGER PRIMARY KEY AUTOINCREMENT, '
- 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'music(id INTEGER PRIMARY KEY AUTOINCREMENT, '
+ 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'shows(id INTEGER PRIMARY KEY AUTOINCREMENT, '
- 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, '
- 'lastEpisodeTitle TEXT, fullImageURL TEXT)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'shows(id INTEGER PRIMARY KEY AUTOINCREMENT, '
+ 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, '
+ 'lastEpisodeTitle TEXT, fullImageURL TEXT)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'episodes(id INTEGER PRIMARY KEY AUTOINCREMENT, '
- 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, '
- 'episodeNumber INTEGER, seasonNumber INTEGER, showTitle TEXT)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'episodes(id INTEGER PRIMARY KEY AUTOINCREMENT, '
+ 'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, '
+ 'episodeNumber INTEGER, seasonNumber INTEGER, showTitle TEXT)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'commercials(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
- 'mediaID INTEGER, title TEXT, duration INTEGER)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'commercials(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
+ 'mediaID INTEGER, title TEXT, duration INTEGER)')
- 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, '
- 'strictTime TEXT, timeShift TEXT, overlapMax TEXT)')
+ 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, '
+ 'strictTime TEXT, timeShift TEXT, overlapMax TEXT)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'daily_schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
- 'mediaID INTEGER, title TEXT, episodeNumber INTEGER, seasonNumber INTEGER, '
- 'showTitle TEXT, duration INTEGER, startTime INTEGER, endTime INTEGER, '
- 'dayOfWeek TEXT, sectionType TEXT)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ 'daily_schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
+ 'mediaID INTEGER, title TEXT, episodeNumber INTEGER, seasonNumber INTEGER, '
+ 'showTitle TEXT, duration INTEGER, startTime INTEGER, endTime INTEGER, '
+ 'dayOfWeek TEXT, sectionType TEXT)')
- self.cursor.execute('CREATE TABLE IF NOT EXISTS '
- 'app_settings(id INTEGER PRIMARY KEY AUTOINCREMENT, version TEXT)')
+ self.cursor.execute('CREATE TABLE IF NOT EXISTS '
+ '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);')
+ #index
+ self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_episode_title ON episodes (title);')
- self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_movie_title ON movies (title);')
+ self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_movie_title ON movies (title);')
- self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_movie_title ON videos (title);')
+ self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_movie_title ON videos (title);')
- self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_music_title ON music (title);')
+ self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_music_title ON music (title);')
- 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_commercial_title ON commercials (title);')
- self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_settings_version ON app_settings (version);')
+ 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",))
+ """Setting Basic Settings
+
+ """
+ try:
+ self.cursor.execute("INSERT OR REPLACE INTO app_settings "
+ "(version) VALUES (?)",
+ ("0.1",))
- self.conn.commit()
- # Catch the exception
- except Exception as e:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- def drop_db(self):
-
- pass
-
- def drop_schedule(self):
-
- pass
-
- def remove_all_scheduled_items(self):
-
- sql = "DELETE FROM schedule WHERE id > -1"
-
- self.cursor.execute(sql)
-
- self.conn.commit()
-
- def remove_all_daily_scheduled_items(self):
-
- sql = "DELETE FROM daily_schedule WHERE id > -1"
-
- self.cursor.execute(sql)
-
- self.conn.commit()
-
- """Database functions.
-
- Setters, etc.
- """
-
- def add_movies_to_db(self, mediaID, title, duration):
- unix = int(time.time())
- try:
- self.cursor.execute("INSERT OR REPLACE INTO movies "
- "(unix, mediaID, title, duration) VALUES (?, ?, ?, ?)",
- (unix, mediaID, title, duration))
-
- self.conn.commit()
- # Catch the exception
- except Exception as e:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- def add_videos_to_db(self, mediaID, title, duration):
- unix = int(time.time())
- try:
- self.cursor.execute("INSERT OR REPLACE INTO videos "
- "(unix, mediaID, title, duration) VALUES (?, ?, ?, ?)",
- (unix, mediaID, title, duration))
-
- self.conn.commit()
- # Catch the exception
- except Exception as e:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- def add_shows_to_db(self, mediaID, title, duration, lastEpisodeTitle, fullImageURL):
- unix = int(time.time())
- try:
- self.cursor.execute("INSERT OR REPLACE INTO shows "
- "(unix, mediaID, title, duration, lastEpisodeTitle, fullImageURL) VALUES (?, ?, ?, ?, ?, ?)",
- (unix, mediaID, title, duration, lastEpisodeTitle, fullImageURL))
- self.conn.commit()
- # Catch the exception
- except Exception as e:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- def add_episodes_to_db(self, mediaID, title, duration, episodeNumber, seasonNumber, showTitle):
- unix = int(time.time())
- try:
- self.cursor.execute("INSERT OR REPLACE INTO episodes "
- "(unix, mediaID, title, duration, episodeNumber, seasonNumber, showTitle) VALUES (?, ?, ?, ?, ?, ?, ?)",
- (unix, mediaID, title, duration, episodeNumber, seasonNumber, showTitle))
- self.conn.commit()
- # Catch the exception
- except Exception as e:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- def add_commercials_to_db(self, mediaID, title, duration):
- unix = int(time.time())
- try:
- self.cursor.execute("INSERT OR REPLACE INTO commercials "
- "(unix, mediaID, title, duration) VALUES (?, ?, ?, ?)",
- (unix, mediaID, title, duration))
- self.conn.commit()
- # Catch the exception
- except Exception as e:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- 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 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:
- # Roll back any change if something goes wrong
- self.conn.rollback()
- raise e
-
- def add_daily_schedule_to_db(
- self,
- mediaID,
- title,
- episodeNumber,
- seasonNumber,
- showTitle,
- duration,
- startTime,
- endTime,
- dayOfWeek,
- sectionType
- ):
-
- unix = int(time.time())
-
- try:
-
- self.cursor.execute("INSERT OR REPLACE INTO daily_schedule "
- "(unix, mediaID, title, episodeNumber, seasonNumber, "
- "showTitle, duration, startTime, endTime, dayOfWeek, sectionType) "
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- (
- unix,
- mediaID,
- title,
- episodeNumber,
- seasonNumber,
- showTitle,
- duration,
- startTime,
- endTime,
- dayOfWeek,
- sectionType
- ))
+ self.conn.commit()
+ # Catch the exception
+ except Exception as e:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ def drop_db(self):
+
+ pass
+
+ def drop_schedule(self):
+
+ pass
+
+ def remove_all_scheduled_items(self):
+
+ sql = "DELETE FROM schedule WHERE id > -1"
+
+ self.cursor.execute(sql)
+
+ self.conn.commit()
+
+ def remove_all_daily_scheduled_items(self):
+
+ sql = "DELETE FROM daily_schedule WHERE id > -1"
+
+ self.cursor.execute(sql)
+
+ self.conn.commit()
+
+ """Database functions.
+
+ Setters, etc.
+ """
+
+ def add_movies_to_db(self, mediaID, title, duration):
+ unix = int(time.time())
+ try:
+ self.cursor.execute("INSERT OR REPLACE INTO movies "
+ "(unix, mediaID, title, duration) VALUES (?, ?, ?, ?)",
+ (unix, mediaID, title, duration))
+
+ self.conn.commit()
+ # Catch the exception
+ except Exception as e:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ def add_videos_to_db(self, mediaID, title, duration):
+ unix = int(time.time())
+ try:
+ self.cursor.execute("INSERT OR REPLACE INTO videos "
+ "(unix, mediaID, title, duration) VALUES (?, ?, ?, ?)",
+ (unix, mediaID, title, duration))
+
+ self.conn.commit()
+ # Catch the exception
+ except Exception as e:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ def add_shows_to_db(self, mediaID, title, duration, lastEpisodeTitle, fullImageURL):
+ unix = int(time.time())
+ try:
+ self.cursor.execute("INSERT OR REPLACE INTO shows "
+ "(unix, mediaID, title, duration, lastEpisodeTitle, fullImageURL) VALUES (?, ?, ?, ?, ?, ?)",
+ (unix, mediaID, title, duration, lastEpisodeTitle, fullImageURL))
+ self.conn.commit()
+ # Catch the exception
+ except Exception as e:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ def add_episodes_to_db(self, mediaID, title, duration, episodeNumber, seasonNumber, showTitle):
+ unix = int(time.time())
+ try:
+ self.cursor.execute("INSERT OR REPLACE INTO episodes "
+ "(unix, mediaID, title, duration, episodeNumber, seasonNumber, showTitle) VALUES (?, ?, ?, ?, ?, ?, ?)",
+ (unix, mediaID, title, duration, episodeNumber, seasonNumber, showTitle))
+ self.conn.commit()
+ # Catch the exception
+ except Exception as e:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ def add_commercials_to_db(self, mediaID, title, duration):
+ unix = int(time.time())
+ try:
+ self.cursor.execute("INSERT OR REPLACE INTO commercials "
+ "(unix, mediaID, title, duration) VALUES (?, ?, ?, ?)",
+ (unix, mediaID, title, duration))
+ self.conn.commit()
+ # Catch the exception
+ except Exception as e:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ 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 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:
+ # Roll back any change if something goes wrong
+ self.conn.rollback()
+ raise e
+
+ def add_daily_schedule_to_db(
+ self,
+ mediaID,
+ title,
+ episodeNumber,
+ seasonNumber,
+ showTitle,
+ duration,
+ startTime,
+ endTime,
+ dayOfWeek,
+ sectionType
+ ):
+
+ unix = int(time.time())
+
+ try:
+
+ self.cursor.execute("INSERT OR REPLACE INTO daily_schedule "
+ "(unix, mediaID, title, episodeNumber, seasonNumber, "
+ "showTitle, duration, startTime, endTime, dayOfWeek, sectionType) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ (
+ unix,
+ mediaID,
+ title,
+ episodeNumber,
+ seasonNumber,
+ showTitle,
+ duration,
+ startTime,
+ endTime,
+ dayOfWeek,
+ sectionType
+ ))
- self.conn.commit()
+ self.conn.commit()
- # Catch the exception
- except Exception as e:
+ # Catch the exception
+ except Exception as e:
- # Roll back any change if something goes wrong
+ # Roll back any change if something goes wrong
- self.conn.rollback()
+ self.conn.rollback()
- raise e
+ raise e
- def add_media_to_daily_schedule(self, media):
+ def add_media_to_daily_schedule(self, media):
- print "#### Adding media to db", media.title, media.start_time
+ print "#### Adding media to db", media.title, media.start_time
- self.add_daily_schedule_to_db(
- 0,
- media.title,
- media.episode_number if media.__class__.__name__ == "Episode" else 0,
- media.season_number if media.__class__.__name__ == "Episode" else 0,
- media.show_series_title if media.__class__.__name__ == "Episode" else '',
- media.duration,
- media.start_time,
- media.end_time,
- media.day_of_week,
- media.section_type
- )
+ self.add_daily_schedule_to_db(
+ 0,
+ media.title,
+ media.episode_number if media.__class__.__name__ == "Episode" else 0,
+ media.season_number if media.__class__.__name__ == "Episode" else 0,
+ media.show_series_title if media.__class__.__name__ == "Episode" else '',
+ media.duration,
+ media.start_time,
+ media.end_time,
+ media.day_of_week,
+ media.section_type
+ )
- """Database functions.
+ """Database functions.
- Getters, etc.
- """
- def get_media(self, title, mediaType):
+ Getters, etc.
+ """
+ def get_media(self, title, mediaType):
- media = mediaType
+ media = mediaType
- sql = "SELECT * FROM "+media+" WHERE (title LIKE ?) COLLATE NOCASE"
- self.cursor.execute(sql, ("%"+title+"%", ))
- media_item = self.cursor.fetchone()
+ sql = "SELECT * FROM "+media+" WHERE (title LIKE ?) COLLATE NOCASE"
+ self.cursor.execute(sql, ("%"+title+"%", ))
+ media_item = self.cursor.fetchone()
- return media_item
+ return media_item
- def get_schedule(self):
+ def get_schedule(self):
- self.cursor.execute("SELECT * FROM schedule ORDER BY datetime(startTimeUnix) ASC")
+ self.cursor.execute("SELECT * FROM schedule ORDER BY datetime(startTimeUnix) ASC")
- datalist = list(self.cursor.fetchall())
+ datalist = list(self.cursor.fetchall())
- return datalist
+ return datalist
- def get_daily_schedule(self):
+ def get_daily_schedule(self):
- self.cursor.execute("SELECT * FROM daily_schedule ORDER BY datetime(startTime) ASC")
+ self.cursor.execute("SELECT * FROM daily_schedule ORDER BY datetime(startTime) ASC")
- datalist = list(self.cursor.fetchall())
+ datalist = list(self.cursor.fetchall())
- return datalist
+ return datalist
- def get_movie(self, title):
+ def get_movie(self, title):
- media = "movies"
+ media = "movies"
- return self.get_media(title, media)
+ return self.get_media(title, media)
- def get_shows(self, title):
+ def get_shows(self, title):
- media = "shows"
+ media = "shows"
- return self.get_media(title, media)
+ return self.get_media(title, media)
- def get_music(self, title):
+ def get_music(self, title):
- media = "music"
+ media = "music"
- return self.get_media(title, media)
+ return self.get_media(title, media)
- def get_video(self, title):
+ def get_video(self, title):
- media = "videos"
+ media = "videos"
- return self.get_media(title, media)
+ return self.get_media(title, media)
- def get_episodes(self, title):
+ def get_episodes(self, title):
- media = "episodes"
+ media = "episodes"
- return self.get_media(title, media)
+ return self.get_media(title, media)
- def update_shows_table_with_last_episode(self, showTitle, lastEpisodeTitle):
+ def update_shows_table_with_last_episode(self, showTitle, lastEpisodeTitle):
- sql1 = "UPDATE shows SET lastEpisodeTitle = ? WHERE title LIKE ? COLLATE NOCASE"
+ sql1 = "UPDATE shows SET lastEpisodeTitle = ? WHERE title LIKE ? COLLATE NOCASE"
- self.cursor.execute(sql1, (lastEpisodeTitle, showTitle, ))
+ self.cursor.execute(sql1, (lastEpisodeTitle, showTitle, ))
- self.conn.commit()
+ self.conn.commit()
- def get_first_episode(self, tvshow):
+ def get_first_episode(self, tvshow):
- sql = ("SELECT id, unix, mediaID, title, duration, MIN(episodeNumber), MIN(seasonNumber), "
- "showTitle FROM episodes WHERE ( showTitle LIKE ?) COLLATE NOCASE")
+ sql = ("SELECT id, unix, mediaID, title, duration, MIN(episodeNumber), MIN(seasonNumber), "
+ "showTitle FROM episodes WHERE ( showTitle LIKE ?) COLLATE NOCASE")
- self.cursor.execute(sql, (tvshow, ))
+ self.cursor.execute(sql, (tvshow, ))
- first_episode = self.cursor.fetchone()
+ first_episode = self.cursor.fetchone()
- return first_episode
+ return first_episode
- '''
- *
- * When incrementing episodes in a series I am advancing by "id"
- *
- '''
- def get_episode_id(self, episodeTitle):
+ '''
+ *
+ * When incrementing episodes in a series I am advancing by "id"
+ *
+ '''
+ def get_episode_id(self, episodeTitle):
- sql = "SELECT id FROM episodes WHERE ( title LIKE ?) COLLATE NOCASE"
+ sql = "SELECT id FROM episodes WHERE ( title LIKE ?) COLLATE NOCASE"
- self.cursor.execute(sql, (episodeTitle, ))
+ self.cursor.execute(sql, (episodeTitle, ))
- episode_id = self.cursor.fetchone()
+ episode_id = self.cursor.fetchone()
- return episode_id
+ return episode_id
- def get_random_episode(self):
+ def get_random_episode(self):
- sql = "SELECT * FROM episodes WHERE id IN (SELECT id FROM episodes ORDER BY RANDOM() LIMIT 1)"
+ sql = "SELECT * FROM episodes WHERE id IN (SELECT id FROM episodes ORDER BY RANDOM() LIMIT 1)"
- self.cursor.execute(sql)
+ self.cursor.execute(sql)
- return self.cursor.fetchone()
+ return self.cursor.fetchone()
- def get_random_movie(self):
+ def get_random_movie(self):
- sql = "SELECT * FROM movies WHERE id IN (SELECT id FROM movies ORDER BY RANDOM() LIMIT 1)"
+ sql = "SELECT * FROM movies WHERE id IN (SELECT id FROM movies ORDER BY RANDOM() LIMIT 1)"
- self.cursor.execute(sql)
+ self.cursor.execute(sql)
- return self.cursor.fetchone()
+ return self.cursor.fetchone()
- def get_next_episode(self, series):
+ def get_next_episode(self, series):
- #print(series)
- '''
- *
- * As a way of storing a "queue", I am storing the *next episode title in the "shows" table so I can
- * determine what has been previously scheduled for each show
- *
- '''
- self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title LIKE ? COLLATE NOCASE", (series, ))
+ #print(series)
+ '''
+ *
+ * As a way of storing a "queue", I am storing the *next episode title in the "shows" table so I can
+ * determine what has been previously scheduled for each show
+ *
+ '''
+ self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title LIKE ? COLLATE NOCASE", (series, ))
- 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 and last_title_list[0] == '':
+ 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 and last_title_list[0] == '':
- '''
- *
- * Find the first episode of the series
- *
- '''
- first_episode = self.get_first_episode(series)
+ '''
+ *
+ * Find the first episode of the series
+ *
+ '''
+ first_episode = self.get_first_episode(series)
- first_episode_title = first_episode[3]
+ first_episode_title = first_episode[3]
- #print(first_episode_title)
- '''
- *
- * Add this episdoe title to the "shows" table for the queue functionality to work
- *
- '''
- self.update_shows_table_with_last_episode(series, first_episode_title)
+ #print(first_episode_title)
+ '''
+ *
+ * Add this episdoe title to the "shows" table for the queue functionality to work
+ *
+ '''
+ self.update_shows_table_with_last_episode(series, first_episode_title)
- return first_episode
+ return first_episode
- elif last_title_list:
- '''
- *
- * The last episode stored in the "shows" table was not empty... get the next episode in the series
- *
- '''
- #print("First episode already set in shows, advancing episodes forward")
+ elif last_title_list:
+ '''
+ *
+ * The last episode stored in the "shows" table was not empty... get the next episode in the series
+ *
+ '''
+ #print("First episode already set in shows, advancing episodes forward")
- #print(str(self.get_episode_id(last_title_list[0])))
+ #print(str(self.get_episode_id(last_title_list[0])))
- """
- *
- * 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])[0])+
- " AND showTitle LIKE ? ) ORDER BY seasonNumber LIMIT 1 COLLATE NOCASE")
+ """
+ *
+ * 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])[0])+
+ " AND showTitle LIKE ? ) ORDER BY seasonNumber LIMIT 1 COLLATE NOCASE")
- self.cursor.execute(sql, (series, ))
- '''
- *
- * Try and advance to the next episode in the series, if it returns None then that means it reached the end...
- *
- '''
- next_episode = self.cursor.fetchone()
+ self.cursor.execute(sql, (series, ))
+ '''
+ *
+ * Try and advance to the next episode in the series, if it returns None then that means it reached the end...
+ *
+ '''
+ next_episode = self.cursor.fetchone()
- if next_episode != None:
+ if next_episode != None:
- #print(next_episode[3])
+ #print(next_episode[3])
- self.update_shows_table_with_last_episode(series, next_episode[3])
+ self.update_shows_table_with_last_episode(series, next_episode[3])
- return next_episode
+ return next_episode
- else:
+ else:
- print("Not grabbing next episode restarting series, series must be over. Restarting from episode 1.")
+ print("Not grabbing next episode restarting series, series must be over. Restarting from episode 1.")
- first_episode = self.get_first_episode(series)
+ first_episode = self.get_first_episode(series)
- self.update_shows_table_with_last_episode(series, first_episode[3])
+ self.update_shows_table_with_last_episode(series, first_episode[3])
- return first_episode
-
- def get_commercials(self, title):
+ return first_episode
+
+ def get_commercials(self, title):
- media = "commercials"
+ media = "commercials"
- sql = "SELECT * FROM "+media+" WHERE (title LIKE ?) COLLATE NOCASE"
- self.cursor.execute(sql, (title, ))
- datalist = list(self.cursor.fetchone())
- if datalist > 0:
- print(datalist)
+ sql = "SELECT * FROM "+media+" WHERE (title LIKE ?) COLLATE NOCASE"
+ self.cursor.execute(sql, (title, ))
+ datalist = list(self.cursor.fetchone())
+ if datalist > 0:
+ print(datalist)
- return datalist
+ return datalist
- else:
+ else:
- return None
+ return None
diff --git a/src/PseudoDailyScheduleController.py b/src/PseudoDailyScheduleController.py
index 08e8448..dde5d78 100644
--- a/src/PseudoDailyScheduleController.py
+++ b/src/PseudoDailyScheduleController.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
from plexapi.server import PlexServer
from datetime import datetime
import sqlite3
@@ -10,328 +12,328 @@ import logging.handlers
class PseudoDailyScheduleController():
- def __init__(self, server, token, clients):
+ def __init__(self, server, token, clients):
- self.PLEX = PlexServer(server, token)
+ self.PLEX = PlexServer(server, token)
- self.BASE_URL = server
+ self.BASE_URL = server
- self.TOKEN = token
+ self.TOKEN = token
- self.PLEX_CLIENTS = clients
+ self.PLEX_CLIENTS = clients
- self.my_logger = logging.getLogger('MyLogger')
- self.my_logger.setLevel(logging.DEBUG)
+ self.my_logger = logging.getLogger('MyLogger')
+ self.my_logger.setLevel(logging.DEBUG)
- self.handler = logging.handlers.SysLogHandler(address = '/dev/log')
+ self.handler = logging.handlers.SysLogHandler(address = '/dev/log')
- self.my_logger.addHandler(self.handler)
+ self.my_logger.addHandler(self.handler)
- '''
- *
- * Get the full image url (including plex token) from the local db.
- * @param seriesTitle: case-unsensitive string of the series title
- * @return string: full path of to the show image
- *
- '''
- def get_show_photo(self, section, title):
+ '''
+ *
+ * Get the full image url (including plex token) from the local db.
+ * @param seriesTitle: case-unsensitive string of the series title
+ * @return string: full path of to the show image
+ *
+ '''
+ def get_show_photo(self, section, title):
- backgroundImagePath = None
+ backgroundImagePath = None
- backgroundImgURL = ''
+ backgroundImgURL = ''
- try:
+ try:
- backgroundImagePath = self.PLEX.library.section(section).get(title)
+ backgroundImagePath = self.PLEX.library.section(section).get(title)
- except:
+ except:
- return backgroundImgURL
+ return backgroundImgURL
- if backgroundImagePath != None and isinstance(backgroundImagePath.art, str):
+ if backgroundImagePath != None and isinstance(backgroundImagePath.art, str):
- backgroundImgURL = self.BASE_URL+backgroundImagePath.art+"?X-Plex-Token="+self.TOKEN
+ backgroundImgURL = self.BASE_URL+backgroundImagePath.art+"?X-Plex-Token="+self.TOKEN
- return backgroundImgURL
+ return backgroundImgURL
- '''
- *
- * Get the generated html for the .html file that is the schedule.
- * ...This is used whenever a show starts or stops in order to add and remove various styles.
- * @param currentTime: datetime object
- * @param bgImageURL: str of the image used for the background
- * @return string: the generated html content
- *
- '''
- def get_html_from_daily_schedule(self, currentTime, bgImageURL, datalist):
+ '''
+ *
+ * Get the generated html for the .html file that is the schedule.
+ * ...This is used whenever a show starts or stops in order to add and remove various styles.
+ * @param currentTime: datetime object
+ * @param bgImageURL: str of the image used for the background
+ * @return string: the generated html content
+ *
+ '''
+ def get_html_from_daily_schedule(self, currentTime, bgImageURL, datalist):
- now = datetime.now()
+ now = datetime.now()
- time = now.strftime("%B %d, %Y")
+ time = now.strftime("%B %d, %Y")
- doc, tag, text, line = Doc(
+ doc, tag, text, line = Doc(
- ).ttl()
+ ).ttl()
- doc.asis('')
+ doc.asis('')
- with tag('html'):
+ with tag('html'):
- with tag('head'):
+ with tag('head'):
- with tag('title'):
+ with tag('title'):
- text(time + " - Daily Pseudo Schedule")
+ text(time + " - Daily Pseudo Schedule")
- doc.asis('')
- doc.asis('')
+ doc.asis('')
+ doc.asis('')
- if bgImageURL != None:
- doc.asis('')
+ if bgImageURL != None:
+ doc.asis('')
- with tag('body'):
+ with tag('body'):
- with tag('div', klass='container mt-3'):
+ with tag('div', klass='container mt-3'):
- with tag('div', klass='row make-white'):
+ with tag('div', klass='row make-white'):
- with tag('div'):
+ with tag('div'):
- with tag('div'):
+ with tag('div'):
- line('h1', "Daily Pseudo Schedule", klass='col-12 pl-0')
+ line('h1', "Daily Pseudo Schedule", klass='col-12 pl-0')
- with tag('div'):
+ with tag('div'):
- line('h3', time, klass='col-12 pl-1')
+ line('h3', time, klass='col-12 pl-1')
- with tag('table', klass='col-12 table table-bordered table-hover'):
+ with tag('table', klass='col-12 table table-bordered table-hover'):
- with tag('thead', klass='table-info'):
- with tag('tr'):
- with tag('th'):
- text('#')
- with tag('th'):
- text('Type')
- with tag('th'):
- text('Series')
- with tag('th'):
- text('Title')
- with tag('th'):
- text('Start Time')
+ with tag('thead', klass='table-info'):
+ with tag('tr'):
+ with tag('th'):
+ text('#')
+ with tag('th'):
+ text('Type')
+ with tag('th'):
+ text('Series')
+ with tag('th'):
+ text('Title')
+ with tag('th'):
+ text('Start Time')
- numberIncrease = 0
+ numberIncrease = 0
- for row in datalist:
+ for row in datalist:
- numberIncrease += 1
+ numberIncrease += 1
- with tag('tbody'):
+ with tag('tbody'):
- timeB = datetime.strptime(row[8], '%I:%M %p')
+ timeB = datetime.strptime(row[8], '%I:%M %p')
- if currentTime == None:
+ if currentTime == None:
- with tag('tr'):
- with tag('th', scope='row'):
- text(numberIncrease)
- with tag('td'):
- text(row[11])
- with tag('td'):
- text(row[6])
- with tag('td'):
- text(row[3])
- with tag('td'):
- text(row[8])
+ with tag('tr'):
+ with tag('th', scope='row'):
+ text(numberIncrease)
+ with tag('td'):
+ text(row[11])
+ with tag('td'):
+ text(row[6])
+ with tag('td'):
+ text(row[3])
+ with tag('td'):
+ text(row[8])
- elif currentTime.hour == timeB.hour and currentTime.minute == timeB.minute:
+ elif currentTime.hour == timeB.hour and currentTime.minute == timeB.minute:
- with tag('tr', klass='bg-info'):
+ with tag('tr', klass='bg-info'):
- with tag('th', scope='row'):
- text(numberIncrease)
- with tag('td'):
- text(row[11])
- with tag('td'):
- text(row[6])
- with tag('td'):
- text(row[3])
- with tag('td'):
- text(row[8])
+ with tag('th', scope='row'):
+ text(numberIncrease)
+ with tag('td'):
+ text(row[11])
+ with tag('td'):
+ text(row[6])
+ with tag('td'):
+ text(row[3])
+ with tag('td'):
+ text(row[8])
- else:
+ else:
- with tag('tr'):
- with tag('th', scope='row'):
- text(numberIncrease)
- with tag('td'):
- text(row[11])
- with tag('td'):
- text(row[6])
- with tag('td'):
- text(row[3])
- with tag('td'):
- text(row[8])
+ with tag('tr'):
+ with tag('th', scope='row'):
+ text(numberIncrease)
+ with tag('td'):
+ text(row[11])
+ with tag('td'):
+ text(row[6])
+ with tag('td'):
+ text(row[3])
+ with tag('td'):
+ text(row[8])
- return doc.getvalue()
+ return doc.getvalue()
- '''
- *
- * Create 'schedules' dir & write the generated html to .html file.
- * @param data: html string
- * @return null
- *
- '''
- def write_schedule_to_file(self, data):
+ '''
+ *
+ * Create 'schedules' dir & write the generated html to .html file.
+ * @param data: html string
+ * @return null
+ *
+ '''
+ def write_schedule_to_file(self, data):
- now = datetime.now()
+ now = datetime.now()
- fileName = "index.html"
+ fileName = "index.html"
- writepath = './schedules/'
+ writepath = './schedules/'
- if not os.path.exists(writepath):
+ if not os.path.exists(writepath):
- os.makedirs(writepath)
+ os.makedirs(writepath)
- if os.path.exists(writepath+fileName):
-
- os.remove(writepath+fileName)
+ if os.path.exists(writepath+fileName):
+
+ os.remove(writepath+fileName)
- mode = 'a' if os.path.exists(writepath) else 'w'
+ mode = 'a' if os.path.exists(writepath) else 'w'
- with open(writepath+fileName, mode) as f:
+ with open(writepath+fileName, mode) as f:
- f.write(data)
+ f.write(data)
- '''
- *
- * Trigger "playMedia()" on the Python Plex API for specified media.
- * @param mediaType: str: "TV Shows"
- * @param mediaParentTitle: str: "Seinfeld"
- * @param mediaTitle: str: "The Soup Nazi"
- * @return null
- *
- '''
- def play_media(self, mediaType, mediaParentTitle, mediaTitle):
+ '''
+ *
+ * Trigger "playMedia()" on the Python Plex API for specified media.
+ * @param mediaType: str: "TV Shows"
+ * @param mediaParentTitle: str: "Seinfeld"
+ * @param mediaTitle: str: "The Soup Nazi"
+ * @return null
+ *
+ '''
+ def play_media(self, mediaType, mediaParentTitle, mediaTitle):
- if mediaType == "TV Shows":
+ if mediaType == "TV Shows":
- mediaItems = self.PLEX.library.section(mediaType).get(mediaParentTitle).episodes()
+ mediaItems = self.PLEX.library.section(mediaType).get(mediaParentTitle).episodes()
- for item in mediaItems:
+ for item in mediaItems:
- # print(part.title)
+ # print(part.title)
- if item.title == mediaTitle:
+ if item.title == mediaTitle:
- for client in self.PLEX_CLIENTS:
+ for client in self.PLEX_CLIENTS:
- clientItem = self.PLEX.client(client)
+ clientItem = self.PLEX.client(client)
- clientItem.playMedia(item)
-
- break
+ clientItem.playMedia(item)
+
+ break
- elif mediaType == "Movies":
+ elif mediaType == "Movies":
- movie = self.PLEX.library.section(mediaType).get(mediaTitle)
+ movie = self.PLEX.library.section(mediaType).get(mediaTitle)
- for client in self.PLEX_CLIENTS:
+ for client in self.PLEX_CLIENTS:
- clientItem = self.PLEX.client(client)
+ clientItem = self.PLEX.client(client)
- clientItem.playMedia(movie)
+ clientItem.playMedia(movie)
- else:
+ else:
- print("Not sure how to play {}".format(mediaType))
-
- '''
- *
- * If tv_controller() does not find a "startTime" for scheduled media, search for an "endTime" match for now time.
- * ...This is useful for clearing the generated html schedule when media ends and there is a gap before the next media.
- * @param null
- * @return null
- *
- '''
- def check_for_end_time(self, datalist):
+ print("Not sure how to play {}".format(mediaType))
+
+ '''
+ *
+ * If tv_controller() does not find a "startTime" for scheduled media, search for an "endTime" match for now time.
+ * ...This is useful for clearing the generated html schedule when media ends and there is a gap before the next media.
+ * @param null
+ * @return null
+ *
+ '''
+ def check_for_end_time(self, datalist):
- currentTime = datetime.now()
+ currentTime = datetime.now()
- """c.execute("SELECT * FROM daily_schedule")
+ """c.execute("SELECT * FROM daily_schedule")
- datalist = list(c.fetchall())
- """
- for row in datalist:
+ datalist = list(c.fetchall())
+ """
+ for row in datalist:
- try:
-
- endTime = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S.%f')
+ try:
+
+ endTime = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S.%f')
- except ValueError:
+ except ValueError:
- endTime = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S')
+ endTime = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S')
- if currentTime.hour == endTime.hour:
+ if currentTime.hour == endTime.hour:
- if currentTime.minute == endTime.minute:
+ if currentTime.minute == endTime.minute:
- print("Ok end time found")
+ print("Ok end time found")
- self.write_schedule_to_file(self.get_html_from_daily_schedule(None, None, datalist))
+ self.write_schedule_to_file(self.get_html_from_daily_schedule(None, None, datalist))
- break
- '''
- *
- * Check DB / current time. If that matches a scheduled shows startTime then trigger play via Plex API
- * @param null
- * @return null
- *
- '''
- def tv_controller(self, datalist):
+ break
+ '''
+ *
+ * Check DB / current time. If that matches a scheduled shows startTime then trigger play via Plex API
+ * @param null
+ * @return null
+ *
+ '''
+ def tv_controller(self, datalist):
- datalistLengthMonitor = 0;
+ datalistLengthMonitor = 0;
- currentTime = datetime.now()
+ currentTime = datetime.now()
- """c.execute("SELECT * FROM daily_schedule ORDER BY datetime(startTimeUnix) ASC")
+ """c.execute("SELECT * FROM daily_schedule ORDER BY datetime(startTimeUnix) ASC")
- datalist = list(c.fetchall())"""
+ datalist = list(c.fetchall())"""
- self.my_logger.debug('TV Controller')
+ self.my_logger.debug('TV Controller')
- for row in datalist:
+ for row in datalist:
- timeB = datetime.strptime(row[8], '%I:%M %p')
+ timeB = datetime.strptime(row[8], '%I:%M %p')
- if currentTime.hour == timeB.hour:
+ if currentTime.hour == timeB.hour:
- if currentTime.minute == timeB.minute:
+ if currentTime.minute == timeB.minute:
- print("Starting Epsisode: " + row[3])
- print(row)
+ print("Starting Epsisode: " + row[3])
+ print(row)
- self.play_media(row[11], row[6], row[3])
+ self.play_media(row[11], row[6], row[3])
- self.write_schedule_to_file(
- self.get_html_from_daily_schedule(
- timeB,
- self.get_show_photo(
- row[11],
- row[6] if row[11] == "TV Shows" else row[3]
- ),
- datalist
- )
- )
+ self.write_schedule_to_file(
+ self.get_html_from_daily_schedule(
+ timeB,
+ self.get_show_photo(
+ row[11],
+ row[6] if row[11] == "TV Shows" else row[3]
+ ),
+ datalist
+ )
+ )
- self.my_logger.debug('Trying to play: ' + row[3])
+ self.my_logger.debug('Trying to play: ' + row[3])
- break
+ break
- datalistLengthMonitor += 1
+ datalistLengthMonitor += 1
- if datalistLengthMonitor >= len(datalist):
+ if datalistLengthMonitor >= len(datalist):
- self.check_for_end_time(datalist)
\ No newline at end of file
+ self.check_for_end_time(datalist)
\ No newline at end of file
diff --git a/src/Video.py b/src/Video.py
index d9f6a5d..d09fa8d 100644
--- a/src/Video.py
+++ b/src/Video.py
@@ -1,8 +1,10 @@
+#!/usr/bin/env python
+
from Media import Media
class Video(Media):
- """Inherits Media.
+ """Inherits Media.
Attributes:
section_type: The type of library this is (i.e. "TV Shows")
@@ -14,27 +16,27 @@ class Video(Media):
is_strict_time: If strict time, then anchor to "natural_start_time"
"""
- def __init__(
- self,
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- ):
+ def __init__(
+ self,
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ ):
- super(Video, self).__init__(
- section_type,
- title,
- natural_start_time,
- natural_end_time,
- duration,
- day_of_week,
- is_strict_time,
- time_shift,
- overlap_max
- )
+ super(Video, self).__init__(
+ section_type,
+ title,
+ natural_start_time,
+ natural_end_time,
+ duration,
+ day_of_week,
+ is_strict_time,
+ time_shift,
+ overlap_max
+ )