Cleanup / added cli flags for info gathering / debugging.

This commit is contained in:
Justin Emter
2017-07-22 19:38:05 -07:00
parent 693a9784ff
commit 78f4aeb7cb
11 changed files with 1318 additions and 1241 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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"],
}

View File

@@ -1,65 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<schedule>
<everyday>
<time title="Looney Tunes" type="series" strict-time="true" time-shift="1" overlap-max="">6:00 AM</time>
<time title="Looney Tunes" type="series" strict-time="false" time-shift="1" overlap-max="">6:30 AM</time>
<time title="Looney Tunes" type="series" strict-time="false" time-shift="1" overlap-max="">7:00 AM</time>
<time title="Looney Tunes" type="series" strict-time="false" time-shift="1" overlap-max="">7:30 AM</time>
</everyday>
<everyday>
<time title="Looney Tunes" type="series" strict-time="true" time-shift="1" overlap-max="">6:00 AM</time>
<time title="Looney Tunes" type="series" strict-time="false" time-shift="1" overlap-max="">6:30 AM</time>
<time title="Looney Tunes" type="series" strict-time="false" time-shift="1" overlap-max="">7:00 AM</time>
<time title="Looney Tunes" type="series" strict-time="false" time-shift="1" overlap-max="">7:30 AM</time>
</everyday>
<mondays></mondays>
<tuesdays></tuesdays>
<wednesdays></wednesdays>
<thursdays></thursdays>
<fridays>
<time title="Looney Tunes" type="series" strict-time="true" time-shift="1" overlap-max="">12:30 AM</time>
</fridays>
<time title="Looney Tunes" type="series" strict-time="true" time-shift="1" overlap-max="">12:30 AM</time>
</fridays>
<saturdays></saturdays>
<sundays></sundays>
<weekends>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:30 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:30 AM</time>
<time title="Batman" type="series" strict-time="false" time-shift="5" overlap-max="">10:00 AM</time>
<time title="Batman" type="series" strict-time="false" time-shift="5" overlap-max="">10:30 AM</time>
<time title="Batman" type="series" strict-time="false" time-shift="5" overlap-max="">10:00 AM</time>
<time title="Batman" type="series" strict-time="false" time-shift="5" overlap-max="">10:30 AM</time>
<time title="random" type="movie" strict-time="false" time-shift="5" overlap-max="">11:00 AM</time>
<time title="random" type="movie" strict-time="false" time-shift="5" overlap-max="">11:00 AM</time>
<time title="The Adventures of Pete &#38; Pete" type="series" strict-time="false" time-shift="5" overlap-max="">12:30 PM</time>
<time title="The Adventures of Pete &#38; Pete" type="series" strict-time="false" time-shift="5" overlap-max="">1:00 PM</time>
<time title="Gilligan's Island" type="series" strict-time="false" time-shift="5" overlap-max="">1:30 PM</time>
<time title="Gilligan's Island" type="series" strict-time="false" time-shift="5" overlap-max="">1:40 PM</time>
<time title="The Jetsons" type="series" strict-time="false" time-shift="5" overlap-max="">2:00 PM</time>
<time title="The Adventures of Pete &#38; Pete" type="series" strict-time="false" time-shift="5" overlap-max="">12:30 PM</time>
<time title="The Adventures of Pete &#38; Pete" type="series" strict-time="false" time-shift="5" overlap-max="">1:00 PM</time>
<time title="Gilligan's Island" type="series" strict-time="false" time-shift="5" overlap-max="">1:30 PM</time>
<time title="Gilligan's Island" type="series" strict-time="false" time-shift="5" overlap-max="">1:40 PM</time>
<time title="The Jetsons" type="series" strict-time="false" time-shift="5" overlap-max="">2:00 PM</time>
<time title="random" type="movie" strict-time="true" time-shift="5" overlap-max="">2:30 PM</time>
<time title="random" type="movie" strict-time="true" time-shift="5" overlap-max="">2:30 PM</time>
<time title="The Wonder Years" type="series" strict-time="false" time-shift="5" overlap-max="">4:30 PM</time>
<time title="The Wonder Years" type="series" strict-time="false" time-shift="5" overlap-max="">5:00 PM</time>
<time title="The Wonder Years" type="series" strict-time="false" time-shift="5" overlap-max="">4:30 PM</time>
<time title="The Wonder Years" type="series" strict-time="false" time-shift="5" overlap-max="">5:00 PM</time>
<time title="The Simpsons" type="series" strict-time="true" time-shift="5" overlap-max="">5:30 PM</time>
<time title="The Simpsons" type="series" strict-time="false" time-shift="5" overlap-max="">6:00 PM</time>
<time title="The Simpsons" type="series" strict-time="true" time-shift="5" overlap-max="">5:30 PM</time>
<time title="The Simpsons" type="series" strict-time="false" time-shift="5" overlap-max="">6:00 PM</time>
<time title="Sherlock" type="series" strict-time="false" time-shift="5" overlap-max="">6:30 PM</time>
<time title="Sherlock" type="series" strict-time="false" time-shift="5" overlap-max="">6:30 PM</time>
<time title="Arrested Development" type="series" strict-time="false" time-shift="5" overlap-max="">7:00 PM</time>
<time title="Arrested Development" type="series" strict-time="false" time-shift="5" overlap-max="">7:30 PM</time>
<time title="Arrested Development" type="series" strict-time="false" time-shift="5" overlap-max="">7:00 PM</time>
<time title="Arrested Development" type="series" strict-time="false" time-shift="5" overlap-max="">7:30 PM</time>
<time title="random" type="movie" strict-time="false" time-shift="5" overlap-max="">8:00 PM</time>
<time title="random" type="movie" strict-time="false" time-shift="5" overlap-max="">8:00 PM</time>
<time title="Band of Brothers" type="show" strict-time="false" time-shift="5" overlap-max="">10:00 PM</time>
<time title="Beverly Hills, 90210" type="show" strict-time="false" time-shift="5" overlap-max="">10:30 PM</time>
<time title="Band of Brothers" type="show" strict-time="false" time-shift="5" overlap-max="">10:00 PM</time>
<time title="Beverly Hills, 90210" type="show" strict-time="false" time-shift="5" overlap-max="">10:30 PM</time>
<time title="The Flintstones" type="show" strict-time="false" time-shift="5" overlap-max="">11:00 PM</time>
<time title="The Flintstones" type="show" strict-time="false" time-shift="5" overlap-max="">11:30 PM</time>
</weekends>
<weekdays>
<default title="Seinfeld" type="series" ></default>
<time title="The Flintstones" type="show" strict-time="false" time-shift="5" overlap-max="">11:00 PM</time>
<time title="The Flintstones" type="show" strict-time="false" time-shift="5" overlap-max="">11:30 PM</time>
</weekends>
<weekdays>
<default title="Seinfeld" type="series" ></default>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:30 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 AM</time>
<time title="Garfield &#38; Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:30 AM</time>
<time title="talespin" type="series" strict-time="false" time-shift="5" overlap-max="">10:00 AM</time>
<time title="talespin" type="series" strict-time="false" time-shift="5" overlap-max="">10:30 AM</time>
@@ -92,7 +92,7 @@
<time title="new girl" type="series" strict-time="false" time-shift="5" overlap-max="">7:30 PM</time>
<time title="the trip" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 PM</time>
<time title="the trip" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 PM</time>
<time title="the trip" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 PM</time>
</weekdays>
</weekdays>
</schedule>

View File

@@ -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
)

View File

@@ -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

View File

@@ -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

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -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

View File

@@ -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('<!DOCTYPE html>')
doc.asis('<!DOCTYPE html>')
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('<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">')
doc.asis('<script>setTimeout(function() {location.reload();}, 30000);</script>')
doc.asis('<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">')
doc.asis('<script>setTimeout(function() {location.reload();}, 30000);</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>')
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('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)
self.check_for_end_time(datalist)

View File

@@ -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
)