mirror of
https://github.com/FakeTV/pseudo-channel.git
synced 2026-01-09 11:43:15 +00:00
Cleaning up code base, etc. getting ready for release.
This commit is contained in:
565
PseudoChannel.py
565
PseudoChannel.py
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
|
||||
"Movies" : ["Films"],
|
||||
|
||||
6) *Skip this feature for now* For Google Calendar integration add your "gkey" to the "plex_token.py" file
|
||||
6) *Skip this feature for now*
|
||||
|
||||
For Google Calendar integration add your "gkey" to the "plex_token.py" file
|
||||
...(https://docs.simplecalendar.io/find-google-calendar-id/):
|
||||
|
||||
gkey = "the key"
|
||||
@@ -36,7 +38,7 @@
|
||||
* List of plex clients to use (add multiple clients to control multiple TV's)
|
||||
*
|
||||
'''
|
||||
plexClients = ['RasPlex']
|
||||
plexClients = ['RasPlex2']
|
||||
|
||||
plexLibraries = {
|
||||
"TV Shows" : ["TV Shows"],
|
||||
@@ -68,18 +70,22 @@ useDailyOverlapCache = True
|
||||
|
||||
dailyUpdateTime = "12:00 AM"
|
||||
|
||||
"""Debug mode will give you more output in your terminal to help problem solve issues."""
|
||||
debug_mode = True
|
||||
|
||||
"""---"""
|
||||
useGoogleCalendar = False
|
||||
|
||||
"""When to delete / remake the pseudo-channel.log - right at midnight, (i.e. 'friday') """
|
||||
rotateLog = "friday"
|
||||
|
||||
"""Debug mode will give you more output in your terminal to help problem solve issues."""
|
||||
debug_mode = True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
##### Do not edit below this line.
|
||||
##### Do not edit below this line---------------------------------------------------------------
|
||||
|
||||
Below is logic to grab your Plex 'token' & Plex 'baseurl'. If you are following along and have created a 'plex_token.py'
|
||||
file as instructed, you do not need to edit below this line.
|
||||
|
||||
@@ -24,7 +24,7 @@ by adding a '<time></time>' block within the part of the week you want it to be
|
||||
below I have "Looney Tunes" scheduled to play "everyday" starting at "6:00 AM", whereas I have "Garfield & Friends"
|
||||
playing only on "weekday" mornings scheduled for after Looney Tunes starting at "8:00 AM". Also notice that
|
||||
"Garfield & Friends" below is actually written as, "Garfield & Friends". This is especially important
|
||||
to those new to editing XML. In XML, "UTF-8", you are forbidden from using certain characters like the "&"
|
||||
to those new to editing XML. In XML, "UTF-8", you are forbidden from using certain characters like the and
|
||||
character. It is important to convert your titles to XML friendly text (this is also important for non-english characters).
|
||||
You can find all of this information by googling "xml ascii character conversion".
|
||||
|
||||
@@ -36,7 +36,7 @@ to either "series" or "movie". The attribute "strict-time" can either be "true"
|
||||
whether or not the particular "<time>" block will be scheduled for the exact time you specify or if it will
|
||||
shift around to fill up gaps. This is useful as sometimes episodes are as short as 5 minutes (cartoons) while
|
||||
other episodes that are normally ~25 minutes are an hour or so long. Setting "strict-time" to "false" will
|
||||
tell the app to movie that time block closer to the previous episode. The corrisponding, "time-shift" attribute
|
||||
tell the app to shift that time block closer to the previous episode. The corresponding, "time-shift" attribute
|
||||
tells the app how to shift the item. Its value can be "1" or more and will help the scheduler determine when to schedule the
|
||||
shifting time according to that value. So for instance, if you'd like no gaps between your content, then you want
|
||||
to set "strict-time='false'" and "time-shift='1'". However if you want your content to shift but would rather
|
||||
@@ -48,7 +48,7 @@ nearest multiple of "5". You could use "15" or "30" too for even prettier times.
|
||||
|
||||
Well, since the app is supposed to work like a real TV Channel, you aren't supposed to have that kind of
|
||||
control. If you want to watch "Billy Madison" then why not just turn on your Plex TV app and play it? Instead
|
||||
here you want to always use "random" tor the "title=" value. But let's say you have a ton of Adam Sandler
|
||||
here you want to always use "random" tor the "title=" value of movie content. But let's say you have a ton of Adam Sandler
|
||||
movies and want to schedule a "random" Adam Sandler movie on Saturday afternoon? That makes more sense, that way
|
||||
you aren't playing the same movie every Saturday afternoon! For movies specifically, you have a new
|
||||
attribute called "xtra". There you can add various parameters to narrow in on the random movie type you
|
||||
@@ -63,12 +63,11 @@ The available "xtra" paramters are as follows (http://python-plexapi.readthedocs
|
||||
* duplicate: Display or hide duplicate items (True, False). [movie]
|
||||
* actor: List of actors to search ([actor_or_id, ...]). [movie]
|
||||
* collection: List of collections to search within ([collection_or_id, ...]). [all]
|
||||
* contentRating: List of content ratings to search within ([rating_or_key, ...]). [movie,tv]
|
||||
* contentRating: List of content ratings to search within ([rating_or_key, ...]). [movie]
|
||||
* country: List of countries to search within ([country_or_key, ...]). [movie,music]
|
||||
* decade: List of decades to search within ([yyy0, ...]). [movie]
|
||||
* director: List of directors to search ([director_or_id, ...]). [movie]
|
||||
* genre: List Genres to search within ([genere_or_id, ...]). [all]
|
||||
* network: List of TV networks to search within ([resolution_or_key, ...]). [tv]
|
||||
* resolution: List of video resolutions to search within ([resolution_or_key, ...]). [movie]
|
||||
* studio: List of studios to search within ([studio_or_key, ...]). [music]
|
||||
* year: List of years to search within ([yyyy, ...]). [all]
|
||||
@@ -83,7 +82,7 @@ or whatever you can come up with. All you have to do is set the commercial flag
|
||||
file to tell the app to use "commercial injection" and make sure you have a "Commercials" library in your
|
||||
plex media library. In that library, fill it with as many commercials or short videos as you can. The more
|
||||
the better! I have close to a thousand commercials in mine - this helps the app fill up the gaps with a
|
||||
wide variety of video content of different durations. (hint: use a tool like 'youtube-dl' to download full
|
||||
wide variety of video content of varied durations. (hint: use a tool like 'youtube-dl' to download full
|
||||
playlists from yourtube. You can fill up your "Commercials" library quick). Once you have your commercials library
|
||||
setup, make sure to run, "python PseudoChannel.py -u" once more to update your local db with your new commercials
|
||||
library. Commercials will now be "injected" to fill up gaps upon the next days schedule (or you can manually
|
||||
@@ -101,7 +100,8 @@ using the XML ascii character "&". Well you cannot do that. I usually like t
|
||||
open in a tab while making my XML. That way for each "series" title I can double check the library to make sure I
|
||||
am using the series title exactly as Plex is.
|
||||
|
||||
Ok, that is it. If you have questions feel free to e-mail me at justin@pseudochannel.tv. Have fun!
|
||||
Ok, that is it. If you have questions feel free to e-mail me at justin@pseudochannel.tv or open an 'issue' on the
|
||||
github repository. Have fun!
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
@@ -16,147 +16,86 @@ class PseudoChannelCommercial():
|
||||
def __init__(self, commercials, commercialPadding):
|
||||
|
||||
self.commercials = commercials
|
||||
|
||||
self.COMMERCIAL_PADDING_IN_SECONDS = commercialPadding
|
||||
|
||||
def get_commercials_to_inject(self):
|
||||
|
||||
self.go()
|
||||
|
||||
return None
|
||||
|
||||
def get_random_commercial(self):
|
||||
|
||||
random_commercial = random.choice(self.commercials)
|
||||
|
||||
random_commercial_dur_seconds = (int(random_commercial[4])/1000)%60
|
||||
|
||||
while random_commercial_dur_seconds < self.MIN_DURATION_FOR_COMMERCIAL:
|
||||
|
||||
random_commercial = random.choice(self.commercials)
|
||||
|
||||
random_commercial_dur_seconds = (int(random_commercial[4])/1000)%60
|
||||
|
||||
return random_commercial
|
||||
|
||||
def go(self):
|
||||
|
||||
shuffled_commercial_list = copy.deepcopy(self.commercials)
|
||||
|
||||
random.shuffle(self.commercials, random.random)
|
||||
|
||||
#print shuffled_commercial_list
|
||||
|
||||
prev_item = None
|
||||
|
||||
for entry in self.daily_schedule:
|
||||
|
||||
"""First Episode"""
|
||||
if prev_item == None:
|
||||
|
||||
prev_item = entry
|
||||
|
||||
else:
|
||||
|
||||
prev_item_end_time = datetime.datetime.strptime(prev_item[9], '%Y-%m-%d %H:%M:%S.%f')
|
||||
|
||||
curr_item_start_time = datetime.datetime.strptime(entry[8], '%I:%M:%S %p')
|
||||
|
||||
time_diff = (curr_item_start_time - prev_item_end_time)
|
||||
|
||||
days, hours, minutes = time_diff.days, time_diff.seconds // 3600, time_diff.seconds // 60 % 60
|
||||
|
||||
count = 0
|
||||
|
||||
commercial_list = []
|
||||
|
||||
commercial_dur_sum = 0
|
||||
|
||||
while int(time_diff.total_seconds()) >= commercial_dur_sum and count < len(self.commercials):
|
||||
|
||||
|
||||
random_commercial = self.get_random_commercial()
|
||||
|
||||
commercial_list.append(random_commercial)
|
||||
|
||||
commercial_dur_sum += int(random_commercial[4])
|
||||
|
||||
print commercial_list
|
||||
|
||||
prev_item = entry
|
||||
|
||||
def timedelta_milliseconds(self, td):
|
||||
|
||||
return td.days*86400000 + td.seconds*1000 + td.microseconds/1000
|
||||
|
||||
def pad_the_commercial_dur(self, commercial):
|
||||
|
||||
commercial_as_list = list(commercial)
|
||||
|
||||
commercial_as_list[4] = int(commercial_as_list[4]) + (self.COMMERCIAL_PADDING_IN_SECONDS * 1000)
|
||||
|
||||
commercial = tuple(commercial_as_list)
|
||||
|
||||
return commercial
|
||||
|
||||
def get_commercials_to_place_between_media(self, last_ep, now_ep):
|
||||
|
||||
#print last_ep.end_time, now_ep.start_time
|
||||
|
||||
prev_item_end_time = datetime.strptime(last_ep.end_time.strftime('%Y-%m-%d %H:%M:%S.%f'), '%Y-%m-%d %H:%M:%S.%f')
|
||||
|
||||
curr_item_start_time = datetime.strptime(now_ep.start_time, '%I:%M:%S %p')
|
||||
|
||||
time_diff = (curr_item_start_time - prev_item_end_time)
|
||||
|
||||
count = 0
|
||||
|
||||
commercial_list = []
|
||||
|
||||
commercial_dur_sum = 0
|
||||
|
||||
time_diff_milli = self.timedelta_milliseconds(time_diff)
|
||||
|
||||
last_commercial = None
|
||||
|
||||
time_watch = prev_item_end_time
|
||||
|
||||
new_commercial_start_time = prev_item_end_time
|
||||
|
||||
#print "here", time_diff.seconds
|
||||
|
||||
while curr_item_start_time > new_commercial_start_time and (count) < len(self.commercials)*100:
|
||||
|
||||
random_commercial_without_pad = self.get_random_commercial()
|
||||
|
||||
"""
|
||||
Padding the duration of commercials as per user specified padding.
|
||||
"""
|
||||
random_commercial = self.pad_the_commercial_dur(random_commercial_without_pad)
|
||||
|
||||
#new_commercial_seconds = (int(random_commercial[4])/1000)%60
|
||||
|
||||
new_commercial_milli = int(random_commercial[4])
|
||||
|
||||
if last_commercial != None:
|
||||
|
||||
#print last_commercial[3]
|
||||
|
||||
new_commercial_start_time = last_commercial.end_time
|
||||
|
||||
new_commercial_end_time = new_commercial_start_time + \
|
||||
timedelta(milliseconds=int(new_commercial_milli))
|
||||
|
||||
else:
|
||||
|
||||
new_commercial_start_time = prev_item_end_time
|
||||
|
||||
new_commercial_end_time = new_commercial_start_time + \
|
||||
timedelta(milliseconds=int(new_commercial_milli))
|
||||
|
||||
commercial_dur_sum += new_commercial_milli
|
||||
|
||||
formatted_time_for_new_commercial = new_commercial_start_time.strftime('%I:%M:%S %p')
|
||||
|
||||
new_commercial = Commercial(
|
||||
"Commercials",
|
||||
random_commercial[3],
|
||||
@@ -169,15 +108,8 @@ class PseudoChannelCommercial():
|
||||
"0", # overlap_max
|
||||
"", # plex_media_id
|
||||
)
|
||||
|
||||
last_commercial = new_commercial
|
||||
|
||||
if new_commercial_end_time > curr_item_start_time:
|
||||
|
||||
break
|
||||
|
||||
commercial_list.append(new_commercial)
|
||||
|
||||
#print "here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
|
||||
return commercial_list
|
||||
@@ -9,83 +9,61 @@ class PseudoChannelDatabase():
|
||||
def __init__(self, db):
|
||||
|
||||
self.db = db
|
||||
|
||||
self.conn = sqlite3.connect(self.db, check_same_thread=False)
|
||||
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
"""Database functions.
|
||||
|
||||
Utilities, etc.
|
||||
"""
|
||||
|
||||
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, plexMediaID TEXT)')
|
||||
|
||||
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
||||
'videos(id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
||||
'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, plexMediaID TEXT)')
|
||||
|
||||
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
||||
'music(id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
||||
'unix INTEGER, mediaID INTEGER, title TEXT, duration INTEGER, plexMediaID 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, plexMediaID 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, plexMediaID TEXT)')
|
||||
|
||||
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
||||
'commercials(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
|
||||
'mediaID INTEGER, title TEXT, duration INTEGER, plexMediaID 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, xtra 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, plexMediaID 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);')
|
||||
|
||||
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_shows_title ON shows (title);')
|
||||
|
||||
self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_video_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_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",))
|
||||
|
||||
self.conn.commit()
|
||||
# Catch the exception
|
||||
except Exception as e:
|
||||
@@ -104,9 +82,7 @@ class PseudoChannelDatabase():
|
||||
def drop_daily_schedule_table(self):
|
||||
|
||||
sql = "DROP TABLE IF EXISTS daily_schedule"
|
||||
|
||||
self.cursor.execute(sql)
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
def create_daily_schedule_table(self):
|
||||
@@ -116,45 +92,36 @@ class PseudoChannelDatabase():
|
||||
'mediaID INTEGER, title TEXT, episodeNumber INTEGER, seasonNumber INTEGER, '
|
||||
'showTitle TEXT, duration INTEGER, startTime INTEGER, endTime INTEGER, '
|
||||
'dayOfWeek TEXT, sectionType TEXT, plexMediaID TEXT)')
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
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"
|
||||
|
||||
self.cursor.execute(sql)
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
def clear_shows_table(self):
|
||||
|
||||
sql = "DELETE FROM shows"
|
||||
|
||||
self.cursor.execute(sql)
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
"""Database functions.
|
||||
|
||||
Setters, etc.
|
||||
"""
|
||||
|
||||
def add_movies_to_db(self, mediaID, title, duration, plexMediaID):
|
||||
|
||||
unix = int(time.time())
|
||||
try:
|
||||
self.cursor.execute("REPLACE INTO movies "
|
||||
"(unix, mediaID, title, duration, plexMediaID) VALUES (?, ?, ?, ?, ?)",
|
||||
(unix, mediaID, title, duration, plexMediaID))
|
||||
|
||||
self.conn.commit()
|
||||
# Catch the exception
|
||||
except Exception as e:
|
||||
@@ -163,6 +130,7 @@ class PseudoChannelDatabase():
|
||||
raise e
|
||||
|
||||
def add_videos_to_db(self, mediaID, title, duration, plexMediaID):
|
||||
|
||||
unix = int(time.time())
|
||||
try:
|
||||
self.cursor.execute("REPLACE INTO videos "
|
||||
@@ -177,6 +145,7 @@ class PseudoChannelDatabase():
|
||||
raise e
|
||||
|
||||
def add_shows_to_db(self, mediaID, title, duration, lastEpisodeTitle, fullImageURL, plexMediaID):
|
||||
|
||||
unix = int(time.time())
|
||||
try:
|
||||
self.cursor.execute("INSERT OR IGNORE INTO shows "
|
||||
@@ -190,6 +159,7 @@ class PseudoChannelDatabase():
|
||||
raise e
|
||||
|
||||
def add_episodes_to_db(self, mediaID, title, duration, episodeNumber, seasonNumber, showTitle, plexMediaID):
|
||||
|
||||
unix = int(time.time())
|
||||
try:
|
||||
self.cursor.execute("REPLACE INTO episodes "
|
||||
@@ -203,6 +173,7 @@ class PseudoChannelDatabase():
|
||||
raise e
|
||||
|
||||
def add_commercials_to_db(self, mediaID, title, duration, plexMediaID):
|
||||
|
||||
unix = int(time.time())
|
||||
try:
|
||||
self.cursor.execute("REPLACE INTO commercials "
|
||||
@@ -258,9 +229,7 @@ class PseudoChannelDatabase():
|
||||
):
|
||||
|
||||
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, plexMediaID) "
|
||||
@@ -279,16 +248,11 @@ class PseudoChannelDatabase():
|
||||
sectionType,
|
||||
plexMediaID
|
||||
))
|
||||
|
||||
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_media_to_daily_schedule(self, media):
|
||||
@@ -297,7 +261,6 @@ class PseudoChannelDatabase():
|
||||
print str("#### Adding media to db: {} {}".format(media.title, media.start_time)).encode('UTF-8')
|
||||
except:
|
||||
print "----- Not outputting media info due to ascii code issues."
|
||||
|
||||
self.add_daily_schedule_to_db(
|
||||
0,
|
||||
media.title,
|
||||
@@ -313,6 +276,7 @@ class PseudoChannelDatabase():
|
||||
)
|
||||
|
||||
def import_shows_table_by_row(self, mediaID, title, duration, lastEpisodeTitle, fullImageURL, plexMediaID):
|
||||
|
||||
unix = int(time.time())
|
||||
try:
|
||||
self.cursor.execute("REPLACE INTO shows "
|
||||
@@ -326,102 +290,79 @@ class PseudoChannelDatabase():
|
||||
raise e
|
||||
|
||||
"""Database functions.
|
||||
|
||||
Getters, etc.
|
||||
"""
|
||||
def get_shows_table(self):
|
||||
|
||||
sql = "SELECT * FROM shows"
|
||||
|
||||
self.cursor.execute(sql)
|
||||
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def get_media(self, title, mediaType):
|
||||
|
||||
media = mediaType
|
||||
|
||||
sql = "SELECT * FROM "+media+" WHERE (title LIKE ?) COLLATE NOCASE"
|
||||
self.cursor.execute(sql, ("%"+title+"%", ))
|
||||
media_item = self.cursor.fetchone()
|
||||
|
||||
return media_item
|
||||
|
||||
def get_schedule(self):
|
||||
|
||||
self.cursor.execute("SELECT * FROM schedule ORDER BY datetime(startTimeUnix) ASC")
|
||||
|
||||
datalist = list(self.cursor.fetchall())
|
||||
|
||||
return datalist
|
||||
|
||||
def get_daily_schedule(self):
|
||||
|
||||
print "##### Getting Daily Schedule from DB."
|
||||
|
||||
self.cursor.execute("SELECT * FROM daily_schedule ORDER BY datetime(startTime) ASC")
|
||||
|
||||
datalist = list(self.cursor.fetchall())
|
||||
|
||||
print "+++++ Done."
|
||||
|
||||
return datalist
|
||||
|
||||
def get_movie(self, title):
|
||||
|
||||
media = "movies"
|
||||
|
||||
return self.get_media(title, media)
|
||||
|
||||
def get_shows(self, title):
|
||||
|
||||
media = "shows"
|
||||
|
||||
return self.get_media(title, media)
|
||||
|
||||
def get_music(self, title):
|
||||
|
||||
media = "music"
|
||||
|
||||
return self.get_media(title, media)
|
||||
|
||||
def get_video(self, title):
|
||||
|
||||
media = "videos"
|
||||
|
||||
return self.get_media(title, media)
|
||||
|
||||
def get_episodes(self, title):
|
||||
|
||||
media = "episodes"
|
||||
|
||||
return self.get_media(title, media)
|
||||
|
||||
def get_commercials(self):
|
||||
|
||||
self.cursor.execute("SELECT * FROM commercials ORDER BY duration ASC")
|
||||
|
||||
datalist = list(self.cursor.fetchall())
|
||||
|
||||
return datalist
|
||||
|
||||
def update_shows_table_with_last_episode(self, showTitle, lastEpisodeTitle):
|
||||
|
||||
sql1 = "UPDATE shows SET lastEpisodeTitle = ? WHERE title LIKE ? COLLATE NOCASE"
|
||||
|
||||
self.cursor.execute(sql1, (lastEpisodeTitle, showTitle, ))
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
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")
|
||||
|
||||
self.cursor.execute(sql, (tvshow, ))
|
||||
|
||||
first_episode = self.cursor.fetchone()
|
||||
|
||||
return first_episode
|
||||
|
||||
'''
|
||||
@@ -432,32 +373,24 @@ class PseudoChannelDatabase():
|
||||
def get_episode_id(self, episodeTitle):
|
||||
|
||||
sql = "SELECT id FROM episodes WHERE ( title LIKE ?) COLLATE NOCASE"
|
||||
|
||||
self.cursor.execute(sql, (episodeTitle, ))
|
||||
|
||||
episode_id = self.cursor.fetchone()
|
||||
|
||||
return episode_id
|
||||
|
||||
def get_random_episode(self):
|
||||
|
||||
sql = "SELECT * FROM episodes WHERE id IN (SELECT id FROM episodes ORDER BY RANDOM() LIMIT 1)"
|
||||
|
||||
self.cursor.execute(sql)
|
||||
|
||||
return self.cursor.fetchone()
|
||||
|
||||
def get_random_movie(self):
|
||||
|
||||
sql = "SELECT * FROM movies WHERE id IN (SELECT id FROM movies ORDER BY RANDOM() LIMIT 1)"
|
||||
|
||||
self.cursor.execute(sql)
|
||||
|
||||
return self.cursor.fetchone()
|
||||
|
||||
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
|
||||
@@ -465,7 +398,6 @@ class PseudoChannelDatabase():
|
||||
*
|
||||
'''
|
||||
self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title LIKE ? COLLATE NOCASE", (series, ))
|
||||
|
||||
last_title_list = self.cursor.fetchone()
|
||||
'''
|
||||
*
|
||||
@@ -480,17 +412,13 @@ class PseudoChannelDatabase():
|
||||
*
|
||||
'''
|
||||
first_episode = self.get_first_episode(series)
|
||||
|
||||
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)
|
||||
|
||||
return first_episode
|
||||
|
||||
elif last_title_list:
|
||||
@@ -499,10 +427,6 @@ class PseudoChannelDatabase():
|
||||
* 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])))
|
||||
|
||||
"""
|
||||
*
|
||||
* If this isn't a first run, then grabbing the next episode by incrementing id
|
||||
@@ -510,7 +434,6 @@ class PseudoChannelDatabase():
|
||||
"""
|
||||
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, ))
|
||||
'''
|
||||
*
|
||||
@@ -518,38 +441,23 @@ class PseudoChannelDatabase():
|
||||
*
|
||||
'''
|
||||
next_episode = self.cursor.fetchone()
|
||||
|
||||
if next_episode != None:
|
||||
|
||||
#print(next_episode[3])
|
||||
|
||||
self.update_shows_table_with_last_episode(series, next_episode[3])
|
||||
|
||||
return next_episode
|
||||
|
||||
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)
|
||||
|
||||
self.update_shows_table_with_last_episode(series, first_episode[3])
|
||||
|
||||
return first_episode
|
||||
|
||||
def get_commercial(self, title):
|
||||
|
||||
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)
|
||||
|
||||
return datalist
|
||||
|
||||
else:
|
||||
|
||||
return None
|
||||
|
||||
return None
|
||||
@@ -1,18 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from plexapi.server import PlexServer
|
||||
from datetime import datetime
|
||||
import sqlite3
|
||||
|
||||
import thread,SocketServer,SimpleHTTPServer
|
||||
|
||||
from yattag import Doc
|
||||
from yattag import indent
|
||||
import os, sys
|
||||
import socket
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
from datetime import datetime
|
||||
import sqlite3
|
||||
import thread,SocketServer,SimpleHTTPServer
|
||||
from plexapi.server import PlexServer
|
||||
from yattag import Doc
|
||||
from yattag import indent
|
||||
|
||||
class PseudoDailyScheduleController():
|
||||
|
||||
@@ -26,32 +23,19 @@ class PseudoDailyScheduleController():
|
||||
):
|
||||
|
||||
self.PLEX = PlexServer(server, token)
|
||||
|
||||
self.BASE_URL = server
|
||||
|
||||
self.TOKEN = token
|
||||
|
||||
self.PLEX_CLIENTS = clients
|
||||
|
||||
self.CONTROLLER_SERVER_PATH = controllerServerPath
|
||||
|
||||
self.CONTROLLER_SERVER_PORT = controllerServerPort if controllerServerPort != '' else '80'
|
||||
|
||||
self.DEBUG = debugMode
|
||||
|
||||
self.webserverStarted = False
|
||||
|
||||
try:
|
||||
|
||||
self.my_logger = logging.getLogger('MyLogger')
|
||||
self.my_logger.setLevel(logging.DEBUG)
|
||||
|
||||
self.handler = logging.handlers.SysLogHandler(address = '/dev/log')
|
||||
|
||||
self.my_logger.addHandler(self.handler)
|
||||
|
||||
except:
|
||||
|
||||
pass
|
||||
|
||||
'''
|
||||
@@ -64,33 +48,22 @@ class PseudoDailyScheduleController():
|
||||
def get_show_photo(self, section, title):
|
||||
|
||||
backgroundImagePath = None
|
||||
|
||||
backgroundImgURL = ''
|
||||
|
||||
try:
|
||||
|
||||
backgroundImagePath = self.PLEX.library.section(section).get(title)
|
||||
|
||||
except:
|
||||
|
||||
return backgroundImgURL
|
||||
|
||||
if backgroundImagePath != None and isinstance(backgroundImagePath.art, str):
|
||||
|
||||
backgroundImgURL = self.BASE_URL+backgroundImagePath.art+"?X-Plex-Token="+self.TOKEN
|
||||
|
||||
return backgroundImgURL
|
||||
|
||||
def start_server(self):
|
||||
|
||||
if self.webserverStarted == False and self.CONTROLLER_SERVER_PATH != '':
|
||||
|
||||
"""Changing dir to the schedules dir."""
|
||||
web_dir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'schedules'))
|
||||
os.chdir(web_dir)
|
||||
|
||||
PORT = int(self.CONTROLLER_SERVER_PORT)
|
||||
|
||||
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||
|
||||
def log_message(self, format, *args):
|
||||
@@ -104,49 +77,34 @@ class PseudoDailyScheduleController():
|
||||
class ReusableTCPServer(SocketServer.TCPServer): allow_reuse_address=True
|
||||
# specify the httpd service on 0.0.0.0 (all interfaces) on port 80
|
||||
httpd = ReusableTCPServer(("0.0.0.0", PORT),MyHandler)
|
||||
|
||||
# thread this mofo
|
||||
thread.start_new_thread(httpd.serve_forever,())
|
||||
|
||||
# handle keyboard interrupts
|
||||
except KeyboardInterrupt:
|
||||
core.print_info("Exiting the SET web server...")
|
||||
httpd.socket.close()
|
||||
|
||||
except socket.error, exc:
|
||||
print "Caught exception socket.error : %s" % exc
|
||||
|
||||
# handle the rest
|
||||
#except Exception:
|
||||
# print "[*] Exiting the SET web server...\n"
|
||||
# httpd.socket.close()
|
||||
|
||||
self.webserverStarted = True
|
||||
|
||||
def get_xml_from_daily_schedule(self, currentTime, bgImageURL, datalist):
|
||||
|
||||
now = datetime.now()
|
||||
|
||||
time = now.strftime("%B %d, %Y")
|
||||
|
||||
doc, tag, text, line = Doc(
|
||||
|
||||
).ttl()
|
||||
|
||||
doc.asis('<?xml version="1.0" encoding="UTF-8"?>')
|
||||
|
||||
with tag('schedule', currently_playing_bg_image=bgImageURL if bgImageURL != None else ''):
|
||||
|
||||
for row in datalist:
|
||||
|
||||
if str(row[11]) == "Commercials" and self.DEBUG == False:
|
||||
|
||||
continue
|
||||
|
||||
timeB = datetime.strptime(row[8], '%I:%M:%S %p')
|
||||
|
||||
if currentTime == None:
|
||||
|
||||
with tag('time',
|
||||
('data-key', str(row[12])),
|
||||
('data-current', 'false'),
|
||||
@@ -154,11 +112,8 @@ class PseudoDailyScheduleController():
|
||||
('data-title', str(row[3])),
|
||||
('data-start-time', str(row[8])),
|
||||
):
|
||||
|
||||
text(row[8])
|
||||
|
||||
elif currentTime.hour == timeB.hour and currentTime.minute == timeB.minute:
|
||||
|
||||
with tag('time',
|
||||
('data-key', str(row[12])),
|
||||
('data-current', 'true'),
|
||||
@@ -166,11 +121,8 @@ class PseudoDailyScheduleController():
|
||||
('data-title', str(row[3])),
|
||||
('data-start-time', str(row[8])),
|
||||
):
|
||||
|
||||
text(row[8])
|
||||
|
||||
else:
|
||||
|
||||
with tag('time',
|
||||
('data-key', str(row[12])),
|
||||
('data-current', 'false'),
|
||||
@@ -178,12 +130,9 @@ class PseudoDailyScheduleController():
|
||||
('data-title', str(row[3])),
|
||||
('data-start-time', str(row[8])),
|
||||
):
|
||||
|
||||
text(row[8])
|
||||
|
||||
return indent(doc.getvalue())
|
||||
|
||||
|
||||
'''
|
||||
*
|
||||
* Get the generated html for the .html file that is the schedule.
|
||||
@@ -196,27 +145,18 @@ class PseudoDailyScheduleController():
|
||||
def get_html_from_daily_schedule(self, currentTime, bgImageURL, datalist):
|
||||
|
||||
now = datetime.now()
|
||||
|
||||
time = now.strftime("%B %d, %Y")
|
||||
|
||||
doc, tag, text, line = Doc(
|
||||
|
||||
).ttl()
|
||||
|
||||
doc.asis('<!DOCTYPE html>')
|
||||
|
||||
with tag('html'):
|
||||
|
||||
with tag('head'):
|
||||
|
||||
with tag('title'):
|
||||
|
||||
text(time + " - Daily Pseudo Schedule")
|
||||
|
||||
doc.asis('<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">')
|
||||
doc.asis('<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">')
|
||||
doc.asis('<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>')
|
||||
|
||||
doc.asis("""
|
||||
<script>
|
||||
$(function(){
|
||||
@@ -271,28 +211,17 @@ class PseudoDailyScheduleController():
|
||||
});
|
||||
</script>
|
||||
""")
|
||||
|
||||
if bgImageURL != None:
|
||||
doc.asis('<style>body{ background:transparent!important; } html { background: url('+bgImageURL+') no-repeat center center fixed; -webkit-background-size: cover;-moz-background-size: cover;-o-background-size: cover;background-size: cover;}.make-white { padding: 24px; background:rgba(255,255,255, 0.9); }</style>')
|
||||
|
||||
with tag('body'):
|
||||
|
||||
with tag('div', klass='container mt-3'):
|
||||
|
||||
with tag('div', klass='row make-white'):
|
||||
|
||||
with tag('div'):
|
||||
|
||||
with tag('div'):
|
||||
|
||||
line('h1', "Daily Pseudo Schedule", klass='col-12 pl-0')
|
||||
|
||||
with tag('div'):
|
||||
|
||||
line('h3', time, klass='col-12 pl-1')
|
||||
|
||||
with tag('table', klass='col-12 table table-bordered table-hover'):
|
||||
|
||||
with tag('thead', klass='table-info'):
|
||||
with tag('tr'):
|
||||
with tag('th'):
|
||||
@@ -305,23 +234,14 @@ class PseudoDailyScheduleController():
|
||||
text('Title')
|
||||
with tag('th'):
|
||||
text('Start Time')
|
||||
|
||||
numberIncrease = 0
|
||||
|
||||
for row in datalist:
|
||||
|
||||
if str(row[11]) == "Commercials" and self.DEBUG == False:
|
||||
|
||||
continue
|
||||
|
||||
numberIncrease += 1
|
||||
|
||||
with tag('tbody'):
|
||||
|
||||
timeB = datetime.strptime(row[8], '%I:%M:%S %p')
|
||||
|
||||
if currentTime == None:
|
||||
|
||||
with tag('tr'):
|
||||
with tag('th', scope='row'):
|
||||
text(numberIncrease)
|
||||
@@ -333,11 +253,8 @@ class PseudoDailyScheduleController():
|
||||
text(row[3])
|
||||
with tag('td'):
|
||||
text(row[8])
|
||||
|
||||
elif currentTime.hour == timeB.hour and currentTime.minute == timeB.minute:
|
||||
|
||||
with tag('tr', klass='bg-info'):
|
||||
|
||||
with tag('th', scope='row'):
|
||||
text(numberIncrease)
|
||||
with tag('td'):
|
||||
@@ -348,9 +265,7 @@ class PseudoDailyScheduleController():
|
||||
text(row[3])
|
||||
with tag('td'):
|
||||
text(row[8])
|
||||
|
||||
else:
|
||||
|
||||
with tag('tr'):
|
||||
with tag('th', scope='row'):
|
||||
text(numberIncrease)
|
||||
@@ -362,8 +277,6 @@ class PseudoDailyScheduleController():
|
||||
text(row[3])
|
||||
with tag('td'):
|
||||
text(row[8])
|
||||
|
||||
|
||||
return indent(doc.getvalue())
|
||||
|
||||
'''
|
||||
@@ -376,25 +289,15 @@ class PseudoDailyScheduleController():
|
||||
def write_schedule_to_file(self, data):
|
||||
|
||||
now = datetime.now()
|
||||
|
||||
fileName = "index.html"
|
||||
|
||||
writepath = './' if os.path.basename(os.getcwd()) == "schedules" else "./schedules/"
|
||||
|
||||
if not os.path.exists(writepath):
|
||||
|
||||
os.makedirs(writepath)
|
||||
|
||||
if os.path.exists(writepath+fileName):
|
||||
|
||||
os.remove(writepath+fileName)
|
||||
|
||||
mode = 'a' if os.path.exists(writepath) else 'w'
|
||||
|
||||
with open(writepath+fileName, mode) as f:
|
||||
|
||||
f.write(data)
|
||||
|
||||
self.start_server()
|
||||
|
||||
'''
|
||||
@@ -407,26 +310,16 @@ class PseudoDailyScheduleController():
|
||||
def write_xml_to_file(self, data):
|
||||
|
||||
now = datetime.now()
|
||||
|
||||
fileName = "pseudo_schedule.xml"
|
||||
|
||||
writepath = './' if os.path.basename(os.getcwd()) == "schedules" else "./schedules/"
|
||||
|
||||
if not os.path.exists(writepath):
|
||||
|
||||
os.makedirs(writepath)
|
||||
|
||||
if os.path.exists(writepath+fileName):
|
||||
|
||||
os.remove(writepath+fileName)
|
||||
|
||||
mode = 'a' if os.path.exists(writepath) else 'w'
|
||||
|
||||
with open(writepath+fileName, mode) as f:
|
||||
|
||||
f.write(data)
|
||||
|
||||
|
||||
'''
|
||||
*
|
||||
* Write 0 or 1 to file for the ajax in the schedule.html to know when to refresh
|
||||
@@ -437,44 +330,27 @@ class PseudoDailyScheduleController():
|
||||
def write_refresh_bool_to_file(self):
|
||||
|
||||
fileName = "pseudo_refresh.txt"
|
||||
|
||||
writepath = './' if os.path.basename(os.getcwd()) == "schedules" else "./schedules/"
|
||||
|
||||
first_line = ''
|
||||
|
||||
if not os.path.exists(writepath):
|
||||
|
||||
os.makedirs(writepath)
|
||||
|
||||
if not os.path.exists(writepath+fileName):
|
||||
|
||||
file(writepath+fileName, 'w').close()
|
||||
|
||||
mode = 'r+'
|
||||
|
||||
with open(writepath+fileName, mode) as f:
|
||||
|
||||
f.seek(0)
|
||||
|
||||
first_line = f.read()
|
||||
|
||||
if self.DEBUG:
|
||||
print "+++++ Html refresh flag: {}".format(first_line)
|
||||
|
||||
if first_line == '' or first_line == "0":
|
||||
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write("1")
|
||||
|
||||
else:
|
||||
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write("0")
|
||||
|
||||
#f.close()
|
||||
|
||||
'''
|
||||
*
|
||||
* Trigger "playMedia()" on the Python Plex API for specified media.
|
||||
@@ -486,61 +362,32 @@ class PseudoDailyScheduleController():
|
||||
'''
|
||||
def play_media(self, mediaType, mediaParentTitle, mediaTitle, offset):
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if mediaType == "TV Shows":
|
||||
|
||||
mediaItems = self.PLEX.library.section(mediaType).get(mediaParentTitle).episodes()
|
||||
|
||||
for item in mediaItems:
|
||||
|
||||
# print(part.title)
|
||||
|
||||
if item.title == mediaTitle:
|
||||
|
||||
for client in self.PLEX_CLIENTS:
|
||||
|
||||
clientItem = self.PLEX.client(client)
|
||||
|
||||
clientItem.playMedia(item, offset=offset)
|
||||
|
||||
break
|
||||
|
||||
elif mediaType == "Movies":
|
||||
|
||||
movie = self.PLEX.library.section(mediaType).get(mediaTitle)
|
||||
|
||||
for client in self.PLEX_CLIENTS:
|
||||
|
||||
clientItem = self.PLEX.client(client)
|
||||
|
||||
clientItem.playMedia(movie, offset=offset)
|
||||
|
||||
elif mediaType == "Commercials":
|
||||
|
||||
movie = self.PLEX.library.section(mediaType).get(mediaTitle)
|
||||
|
||||
for client in self.PLEX_CLIENTS:
|
||||
|
||||
clientItem = self.PLEX.client(client)
|
||||
|
||||
clientItem.playMedia(movie, offset=offset)
|
||||
|
||||
else:
|
||||
|
||||
print("##### Not sure how to play {}".format(mediaType))
|
||||
|
||||
print "+++++ Done."
|
||||
|
||||
except Exception as e:
|
||||
|
||||
print e.__doc__
|
||||
|
||||
print e.message
|
||||
|
||||
print "##### There was an error trying to play the media."
|
||||
|
||||
pass
|
||||
|
||||
'''
|
||||
@@ -554,49 +401,32 @@ class PseudoDailyScheduleController():
|
||||
def check_for_end_time(self, datalist):
|
||||
|
||||
currentTime = datetime.now()
|
||||
|
||||
"""c.execute("SELECT * FROM daily_schedule")
|
||||
|
||||
datalist = list(c.fetchall())
|
||||
"""
|
||||
for row in datalist:
|
||||
|
||||
try:
|
||||
|
||||
endTime = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S.%f')
|
||||
|
||||
except ValueError:
|
||||
|
||||
endTime = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S')
|
||||
|
||||
if currentTime.hour == endTime.hour:
|
||||
|
||||
if currentTime.minute == endTime.minute:
|
||||
|
||||
if currentTime.second == endTime.second:
|
||||
|
||||
if self.DEBUG:
|
||||
print("Ok end time found")
|
||||
|
||||
self.write_schedule_to_file(self.get_html_from_daily_schedule(None, None, datalist))
|
||||
self.write_xml_to_file(self.get_xml_from_daily_schedule(None, None, datalist))
|
||||
|
||||
self.write_refresh_bool_to_file()
|
||||
|
||||
break
|
||||
|
||||
def play(self, row, datalist, offset=0):
|
||||
|
||||
print str("##### Starting Media: '{}'".format(row[3])).encode('UTF-8')
|
||||
print str("##### Media Offset: '{}' seconds.".format(int(offset / 1000))).encode('UTF-8')
|
||||
|
||||
if self.DEBUG:
|
||||
print str(row).encode('UTF-8')
|
||||
|
||||
timeB = datetime.strptime(row[8], '%I:%M:%S %p')
|
||||
|
||||
self.play_media(row[11], row[6], row[3], offset)
|
||||
|
||||
self.write_schedule_to_file(
|
||||
self.get_html_from_daily_schedule(
|
||||
timeB,
|
||||
@@ -607,9 +437,7 @@ class PseudoDailyScheduleController():
|
||||
datalist
|
||||
)
|
||||
)
|
||||
|
||||
self.write_refresh_bool_to_file()
|
||||
|
||||
"""Generate / write XML to file
|
||||
"""
|
||||
self.write_xml_to_file(
|
||||
@@ -622,15 +450,11 @@ class PseudoDailyScheduleController():
|
||||
datalist
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
self.my_logger.debug('Trying to play: ' + row[3])
|
||||
|
||||
except:
|
||||
|
||||
pass
|
||||
|
||||
|
||||
'''
|
||||
*
|
||||
* Check DB / current time. If that matches a scheduled shows startTime then trigger play via Plex API
|
||||
@@ -641,36 +465,21 @@ class PseudoDailyScheduleController():
|
||||
def tv_controller(self, datalist):
|
||||
|
||||
datalistLengthMonitor = 0;
|
||||
|
||||
currentTime = datetime.now()
|
||||
|
||||
"""c.execute("SELECT * FROM daily_schedule ORDER BY datetime(startTimeUnix) ASC")
|
||||
|
||||
datalist = list(c.fetchall())"""
|
||||
|
||||
try:
|
||||
|
||||
self.my_logger.debug('TV Controller')
|
||||
|
||||
except:
|
||||
|
||||
pass
|
||||
|
||||
for row in datalist:
|
||||
|
||||
timeB = datetime.strptime(row[8], '%I:%M:%S %p')
|
||||
|
||||
if currentTime.hour == timeB.hour:
|
||||
|
||||
if currentTime.minute == timeB.minute:
|
||||
|
||||
if currentTime.second == timeB.second:
|
||||
|
||||
print("Starting Media: " + row[3])
|
||||
print(row)
|
||||
|
||||
self.play_media(row[11], row[6], row[3])
|
||||
|
||||
self.write_schedule_to_file(
|
||||
self.get_html_from_daily_schedule(
|
||||
timeB,
|
||||
@@ -681,9 +490,7 @@ class PseudoDailyScheduleController():
|
||||
datalist
|
||||
)
|
||||
)
|
||||
|
||||
self.write_refresh_bool_to_file()
|
||||
|
||||
"""Generate / write XML to file
|
||||
"""
|
||||
self.write_xml_to_file(
|
||||
@@ -696,26 +503,18 @@ class PseudoDailyScheduleController():
|
||||
datalist
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
self.my_logger.debug('Trying to play: ' + row[3])
|
||||
|
||||
except:
|
||||
|
||||
pass
|
||||
|
||||
break
|
||||
|
||||
datalistLengthMonitor += 1
|
||||
|
||||
if datalistLengthMonitor >= len(datalist):
|
||||
|
||||
self.check_for_end_time(datalist)
|
||||
|
||||
def make_xml_schedule(self, datalist):
|
||||
|
||||
print "+++++ ", "Writing XML / HTML to file."
|
||||
|
||||
self.write_refresh_bool_to_file()
|
||||
self.write_schedule_to_file(self.get_html_from_daily_schedule(None, None, datalist))
|
||||
self.write_xml_to_file(self.get_xml_from_daily_schedule(None, None, datalist))
|
||||
Reference in New Issue
Block a user