mirror of
https://github.com/FakeTV/pseudo-channel.git
synced 2025-12-22 19:23:21 +00:00
Alpha
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ schedules/
|
|||||||
pseudo-tv.db-journal
|
pseudo-tv.db-journal
|
||||||
*.pyc
|
*.pyc
|
||||||
old/
|
old/
|
||||||
|
pseudo-channel.db
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from src import PseudoChannelDatabase
|
from src import PseudoChannelDatabase
|
||||||
from src import Movie
|
from src import Movie
|
||||||
from src import Commercial
|
from src import Commercial
|
||||||
@@ -8,6 +10,7 @@ from pseudo_config import *
|
|||||||
|
|
||||||
from plexapi.server import PlexServer
|
from plexapi.server import PlexServer
|
||||||
|
|
||||||
|
import sys
|
||||||
import datetime
|
import datetime
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
@@ -35,6 +38,29 @@ class PseudoChannel():
|
|||||||
generate_daily_schedule(): Generates daily schedule based on the "schedule" table.
|
generate_daily_schedule(): Generates daily schedule based on the "schedule" table.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Print iterations progress
|
||||||
|
def print_progress(self, iteration, total, prefix='', suffix='', decimals=1, bar_length=100):
|
||||||
|
"""
|
||||||
|
Call in a loop to create terminal progress bar
|
||||||
|
@params:
|
||||||
|
iteration - Required : current iteration (Int)
|
||||||
|
total - Required : total iterations (Int)
|
||||||
|
prefix - Optional : prefix string (Str)
|
||||||
|
suffix - Optional : suffix string (Str)
|
||||||
|
decimals - Optional : positive number of decimals in percent complete (Int)
|
||||||
|
bar_length - Optional : character length of bar (Int)
|
||||||
|
"""
|
||||||
|
str_format = "{0:." + str(decimals) + "f}"
|
||||||
|
percents = str_format.format(100 * (iteration / float(total)))
|
||||||
|
filled_length = int(round(bar_length * iteration / float(total)))
|
||||||
|
bar = '█' * filled_length + '-' * (bar_length - filled_length)
|
||||||
|
|
||||||
|
sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix)),
|
||||||
|
|
||||||
|
if iteration == total:
|
||||||
|
sys.stdout.write('\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def update_db(self):
|
def update_db(self):
|
||||||
|
|
||||||
print("Updating Local Database")
|
print("Updating Local Database")
|
||||||
@@ -49,15 +75,22 @@ class PseudoChannel():
|
|||||||
|
|
||||||
sectionMedia = self.PLEX.library.section(section.title).all()
|
sectionMedia = self.PLEX.library.section(section.title).all()
|
||||||
|
|
||||||
for media in sectionMedia:
|
self.print_progress(0, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50)
|
||||||
|
|
||||||
|
for i, media in enumerate(sectionMedia):
|
||||||
|
|
||||||
self.db.add_movies_to_db(1, media.title, media.duration)
|
self.db.add_movies_to_db(1, media.title, media.duration)
|
||||||
|
|
||||||
|
self.print_progress(i + 1, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50)
|
||||||
|
|
||||||
|
|
||||||
elif section.title == "TV Shows":
|
elif section.title == "TV Shows":
|
||||||
|
|
||||||
sectionMedia = self.PLEX.library.section(section.title).all()
|
sectionMedia = self.PLEX.library.section(section.title).all()
|
||||||
|
|
||||||
for media in sectionMedia:
|
self.print_progress(0, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50)
|
||||||
|
|
||||||
|
for i, media in enumerate(sectionMedia):
|
||||||
|
|
||||||
backgroundImagePath = self.PLEX.library.section(section.title).get(media.title)
|
backgroundImagePath = self.PLEX.library.section(section.title).get(media.title)
|
||||||
|
|
||||||
@@ -69,6 +102,8 @@ class PseudoChannel():
|
|||||||
|
|
||||||
self.db.add_shows_to_db(2, media.title, media.duration, '', backgroundImgURL)
|
self.db.add_shows_to_db(2, media.title, media.duration, '', backgroundImgURL)
|
||||||
|
|
||||||
|
self.print_progress(i + 1, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50)
|
||||||
|
|
||||||
#add all episodes of each tv show to episodes table
|
#add all episodes of each tv show to episodes table
|
||||||
episodes = self.PLEX.library.section(section.title).get(media.title).episodes()
|
episodes = self.PLEX.library.section(section.title).get(media.title).episodes()
|
||||||
|
|
||||||
@@ -88,12 +123,20 @@ class PseudoChannel():
|
|||||||
|
|
||||||
sectionMedia = self.PLEX.library.section(section.title).all()
|
sectionMedia = self.PLEX.library.section(section.title).all()
|
||||||
|
|
||||||
for media in sectionMedia:
|
self.print_progress(0, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50)
|
||||||
|
|
||||||
|
for i, media in enumerate(sectionMedia):
|
||||||
|
|
||||||
self.db.add_commercials_to_db(3, media.title, media.duration)
|
self.db.add_commercials_to_db(3, media.title, media.duration)
|
||||||
|
|
||||||
|
self.print_progress(i + 1, len(sectionMedia), prefix = 'Progress '+section.title+":", suffix = 'Complete', bar_length = 50)
|
||||||
|
|
||||||
def update_schedule(self):
|
def update_schedule(self):
|
||||||
|
|
||||||
|
self.db.create_tables()
|
||||||
|
|
||||||
|
self.db.remove_all_scheduled_items()
|
||||||
|
|
||||||
scheduled_days_list = [
|
scheduled_days_list = [
|
||||||
"mondays",
|
"mondays",
|
||||||
"tuesdays",
|
"tuesdays",
|
||||||
@@ -122,24 +165,46 @@ class PseudoChannel():
|
|||||||
|
|
||||||
if child.tag in scheduled_days_list:
|
if child.tag in scheduled_days_list:
|
||||||
|
|
||||||
print child.find( "time" )
|
|
||||||
|
|
||||||
for time in child.iter("time"):
|
for time in child.iter("time"):
|
||||||
|
|
||||||
for key, value in section_dict.items():
|
for key, value in section_dict.items():
|
||||||
|
|
||||||
if time.attrib['type'] == key or time.attrib['type'] in value:
|
if time.attrib['type'] == key or time.attrib['type'] in value:
|
||||||
|
|
||||||
print time.tag, time.text, time.attrib['title']
|
|
||||||
|
|
||||||
title = time.attrib['title']
|
title = time.attrib['title']
|
||||||
|
|
||||||
natural_start_time = time.text
|
natural_start_time = time.text
|
||||||
|
|
||||||
|
natural_end_time = 0
|
||||||
|
|
||||||
section = key
|
section = key
|
||||||
|
|
||||||
|
day_of_week = child.tag
|
||||||
|
|
||||||
strict_time = time.attrib['strict-time']
|
strict_time = time.attrib['strict-time']
|
||||||
|
|
||||||
|
time_shift = time.attrib['time-shift']
|
||||||
|
|
||||||
|
overlap_max = time.attrib['overlap-max']
|
||||||
|
|
||||||
|
start_time_unix = datetime.datetime.strptime(time.text, '%I:%M %p')
|
||||||
|
|
||||||
|
print "Adding: ", time.tag, section, time.text, time.attrib['title']
|
||||||
|
|
||||||
|
self.db.add_schedule_to_db(
|
||||||
|
0, # mediaID
|
||||||
|
title, # title
|
||||||
|
0, # duration
|
||||||
|
natural_start_time, # startTime
|
||||||
|
natural_end_time, # endTime
|
||||||
|
day_of_week, # dayOfWeek
|
||||||
|
start_time_unix, # startTimeUnix
|
||||||
|
section, # section
|
||||||
|
strict_time, # strictTime
|
||||||
|
time_shift, # timeShift
|
||||||
|
overlap_max, # overlapMax
|
||||||
|
)
|
||||||
|
|
||||||
def drop_db(self):
|
def drop_db(self):
|
||||||
|
|
||||||
self.db.drop_db()
|
self.db.drop_db()
|
||||||
@@ -189,6 +254,8 @@ class PseudoChannel():
|
|||||||
|
|
||||||
if section == "TV Shows":
|
if section == "TV Shows":
|
||||||
|
|
||||||
|
print "getting", entry[3]
|
||||||
|
|
||||||
next_episode = self.db.get_next_episode(entry[3])
|
next_episode = self.db.get_next_episode(entry[3])
|
||||||
|
|
||||||
if next_episode != None:
|
if next_episode != None:
|
||||||
@@ -294,9 +361,11 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
pseudo_channel = PseudoChannel()
|
pseudo_channel = PseudoChannel()
|
||||||
|
|
||||||
|
pseudo_channel.update_db()
|
||||||
|
|
||||||
pseudo_channel.update_schedule()
|
pseudo_channel.update_schedule()
|
||||||
|
|
||||||
#pseudo_channel.generate_daily_schedule()
|
pseudo_channel.generate_daily_schedule()
|
||||||
|
|
||||||
"""for item in pseudo_channel.MEDIA:
|
"""for item in pseudo_channel.MEDIA:
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -15,10 +15,10 @@
|
|||||||
<time title="Looney Tunes" type="series" strict-time="false" time-shift="5" overlap-max="">7:00 AM</time>
|
<time title="Looney Tunes" type="series" strict-time="false" time-shift="5" overlap-max="">7:00 AM</time>
|
||||||
<time title="Looney Tunes" type="series" strict-time="false" time-shift="5" overlap-max="">7:30 AM</time>
|
<time title="Looney Tunes" type="series" strict-time="false" time-shift="5" overlap-max="">7:30 AM</time>
|
||||||
|
|
||||||
<time title="Garfield and Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:00 AM</time>
|
<time title="Garfield & Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:00 AM</time>
|
||||||
<time title="Garfield and Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 AM</time>
|
<time title="Garfield & Friends" type="series" strict-time="false" time-shift="5" overlap-max="">8:30 AM</time>
|
||||||
<time title="Garfield and Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 AM</time>
|
<time title="Garfield & Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:00 AM</time>
|
||||||
<time title="Garfield and Friends" type="series" strict-time="false" time-shift="5" overlap-max="">9:30 AM</time>
|
<time title="Garfield & 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:00 AM</time>
|
||||||
<time title="talespin" type="series" strict-time="false" time-shift="5" overlap-max="">10:30 AM</time>
|
<time title="talespin" type="series" strict-time="false" time-shift="5" overlap-max="">10:30 AM</time>
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ class PseudoChannelDatabase():
|
|||||||
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
||||||
'schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
|
'schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
|
||||||
'mediaID INTEGER, title TEXT, duration INTEGER, startTime INTEGER, '
|
'mediaID INTEGER, title TEXT, duration INTEGER, startTime INTEGER, '
|
||||||
'endTime INTEGER, dayOfWeek TEXT, startTimeUnix INTEGER), section TEXT)')
|
'endTime INTEGER, dayOfWeek TEXT, startTimeUnix INTEGER, section TEXT, '
|
||||||
|
'strictTime TEXT, timeShift TEXT, overlapMax TEXT)')
|
||||||
|
|
||||||
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
||||||
'daily_schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
|
'daily_schedule(id INTEGER PRIMARY KEY AUTOINCREMENT, unix INTEGER, '
|
||||||
@@ -56,7 +57,7 @@ class PseudoChannelDatabase():
|
|||||||
'showTitle TEXT, duration INTEGER, startTime INTEGER, endTime INTEGER, dayOfWeek TEXT)')
|
'showTitle TEXT, duration INTEGER, startTime INTEGER, endTime INTEGER, dayOfWeek TEXT)')
|
||||||
|
|
||||||
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
self.cursor.execute('CREATE TABLE IF NOT EXISTS '
|
||||||
'app_settings(id INTEGER PRIMARY KEY AUTOINCREMENT, version TEXT')
|
'app_settings(id INTEGER PRIMARY KEY AUTOINCREMENT, version TEXT)')
|
||||||
|
|
||||||
#index
|
#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_episode_title ON episodes (title);')
|
||||||
@@ -69,13 +70,15 @@ class PseudoChannelDatabase():
|
|||||||
|
|
||||||
self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_commercial_title ON commercials (title);')
|
self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_commercial_title ON commercials (title);')
|
||||||
|
|
||||||
|
self.cursor.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_settings_version ON app_settings (version);')
|
||||||
|
|
||||||
"""Setting Basic Settings
|
"""Setting Basic Settings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.cursor.execute("INSERT OR REPLACE INTO app_settings "
|
self.cursor.execute("INSERT OR REPLACE INTO app_settings "
|
||||||
"(version) VALUES (?)",
|
"(version) VALUES (?)",
|
||||||
("0.1"))
|
("0.1",))
|
||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
# Catch the exception
|
# Catch the exception
|
||||||
@@ -92,7 +95,7 @@ class PseudoChannelDatabase():
|
|||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def remove_all_scheduled_items():
|
def remove_all_scheduled_items(self):
|
||||||
|
|
||||||
sql = "DELETE FROM schedule WHERE id > -1"
|
sql = "DELETE FROM schedule WHERE id > -1"
|
||||||
|
|
||||||
@@ -100,10 +103,6 @@ class PseudoChannelDatabase():
|
|||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
self.cursor.close()
|
|
||||||
|
|
||||||
self.conn.close()
|
|
||||||
|
|
||||||
"""Database functions.
|
"""Database functions.
|
||||||
|
|
||||||
Setters, etc.
|
Setters, etc.
|
||||||
@@ -176,12 +175,13 @@ class PseudoChannelDatabase():
|
|||||||
self.conn.rollback()
|
self.conn.rollback()
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def add_schedule_to_db(self, mediaID, title, duration, startTime, endTime, dayOfWeek, section):
|
def add_schedule_to_db(self, mediaID, title, duration, startTime, endTime, dayOfWeek, startTimeUnix, section, strictTime, timeShift, overlapMax):
|
||||||
unix = int(time.time())
|
unix = int(time.time())
|
||||||
try:
|
try:
|
||||||
self.cursor.execute("INSERT INTO schedule "
|
self.cursor.execute("INSERT OR REPLACE INTO schedule "
|
||||||
"(unix, mediaID, title, duration, startTime, endTime, dayOfWeek) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
"(unix, mediaID, title, duration, startTime, endTime, dayOfWeek, startTimeUnix, section, strictTime, timeShift, overlapMax) "
|
||||||
(unix, mediaID, title, duration, startTime, endTime, dayOfWeek, section))
|
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
(unix, mediaID, title, duration, startTime, endTime, dayOfWeek, startTimeUnix, section, strictTime, timeShift, overlapMax))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
# Catch the exception
|
# Catch the exception
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -268,7 +268,7 @@ class PseudoChannelDatabase():
|
|||||||
|
|
||||||
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 = ?"
|
sql1 = "UPDATE shows SET lastEpisodeTitle = ? WHERE title LIKE ? COLLATE NOCASE"
|
||||||
|
|
||||||
self.cursor.execute(sql1, (lastEpisodeTitle, showTitle, ))
|
self.cursor.execute(sql1, (lastEpisodeTitle, showTitle, ))
|
||||||
|
|
||||||
@@ -277,21 +277,13 @@ class PseudoChannelDatabase():
|
|||||||
def get_first_episode(self, tvshow):
|
def get_first_episode(self, tvshow):
|
||||||
|
|
||||||
sql = ("SELECT id, unix, mediaID, title, duration, MIN(episodeNumber), MIN(seasonNumber), "
|
sql = ("SELECT id, unix, mediaID, title, duration, MIN(episodeNumber), MIN(seasonNumber), "
|
||||||
"showTitle FROM episodes WHERE ( showTitle = ?) COLLATE NOCASE")
|
"showTitle FROM episodes WHERE ( showTitle LIKE ?) COLLATE NOCASE")
|
||||||
|
|
||||||
self.cursor.execute(sql, (tvshow, ))
|
self.cursor.execute(sql, (tvshow, ))
|
||||||
|
|
||||||
datalist = list(self.cursor.fetchone())
|
first_episode = self.cursor.fetchone()
|
||||||
|
|
||||||
if datalist > 0:
|
return first_episode
|
||||||
|
|
||||||
return datalist
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
print("No entry found in DB to add to schedule.")
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
*
|
*
|
||||||
@@ -300,21 +292,13 @@ class PseudoChannelDatabase():
|
|||||||
'''
|
'''
|
||||||
def get_episode_id(self, episodeTitle):
|
def get_episode_id(self, episodeTitle):
|
||||||
|
|
||||||
sql = "SELECT id FROM episodes WHERE ( title = ?) COLLATE NOCASE"
|
sql = "SELECT id FROM episodes WHERE ( title LIKE ?) COLLATE NOCASE"
|
||||||
|
|
||||||
self.cursor.execute(sql, (episodeTitle, ))
|
self.cursor.execute(sql, (episodeTitle, ))
|
||||||
|
|
||||||
datalist = list(self.cursor.fetchone())
|
episode_id = self.cursor.fetchone()
|
||||||
|
|
||||||
if datalist > 0:
|
return episode_id
|
||||||
|
|
||||||
return datalist[0]
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
print("No entry found in DB to add to schedule.")
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_next_episode(self, series):
|
def get_next_episode(self, series):
|
||||||
|
|
||||||
@@ -325,15 +309,15 @@ class PseudoChannelDatabase():
|
|||||||
* determine what has been previously scheduled for each show
|
* determine what has been previously scheduled for each show
|
||||||
*
|
*
|
||||||
'''
|
'''
|
||||||
self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title = ?", (series, ))
|
self.cursor.execute("SELECT lastEpisodeTitle FROM shows WHERE title LIKE ? COLLATE NOCASE", (series, ))
|
||||||
|
|
||||||
last_title_list = list(self.cursor.fetchone())
|
last_title_list = self.cursor.fetchone()
|
||||||
'''
|
'''
|
||||||
*
|
*
|
||||||
* If the last episode stored in the "shows" table is empty, then this is probably a first run...
|
* If the last episode stored in the "shows" table is empty, then this is probably a first run...
|
||||||
*
|
*
|
||||||
'''
|
'''
|
||||||
if last_title_list[0] == '':
|
if last_title_list and last_title_list[0] == '':
|
||||||
|
|
||||||
'''
|
'''
|
||||||
*
|
*
|
||||||
@@ -354,7 +338,7 @@ class PseudoChannelDatabase():
|
|||||||
|
|
||||||
return first_episode
|
return first_episode
|
||||||
|
|
||||||
else:
|
elif last_title_list:
|
||||||
'''
|
'''
|
||||||
*
|
*
|
||||||
* The last episode stored in the "shows" table was not empty... get the next episode in the series
|
* The last episode stored in the "shows" table was not empty... get the next episode in the series
|
||||||
@@ -369,8 +353,7 @@ class PseudoChannelDatabase():
|
|||||||
* If this isn't a first run, then grabbing the next episode by incrementing id
|
* If this isn't a first run, then grabbing the next episode by incrementing id
|
||||||
*
|
*
|
||||||
"""
|
"""
|
||||||
sql = ("SELECT * FROM episodes WHERE ( id > "
|
sql = ("SELECT * FROM episodes WHERE ( id > "+str(self.get_episode_id(last_title_list[0])[0])+
|
||||||
+str(self.get_episode_id(last_title_list[0]))+
|
|
||||||
" AND showTitle LIKE ? ) ORDER BY seasonNumber LIMIT 1 COLLATE NOCASE")
|
" AND showTitle LIKE ? ) ORDER BY seasonNumber LIMIT 1 COLLATE NOCASE")
|
||||||
|
|
||||||
self.cursor.execute(sql, (series, ))
|
self.cursor.execute(sql, (series, ))
|
||||||
|
|||||||
Reference in New Issue
Block a user