From ebf67a16cf52ca6e6b95659e83df0a68b26a20d4 Mon Sep 17 00:00:00 2001 From: jakewaldron Date: Thu, 12 Mar 2015 11:50:13 -0700 Subject: [PATCH] New Feature and Cleaned Up Code Can now set hours instead of days for backwards search Put html creation into functions Don't display categories if empty --- README.md | 4 +- scripts/config.conf | 4 +- scripts/plexEmail.py | 375 ++++++++++++++++++++++++------------------- 3 files changed, 220 insertions(+), 163 deletions(-) diff --git a/README.md b/README.md index 4e903fa..ebfe4f9 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,9 @@ The config file is in the scripts folder. Before first run of the script, pleas #####General * date_format - Format to use for the date -* days_back_to_search - Number of days to search backwards +* date_days_back_to_search - Number of days to search backwards +* date_use_hours - Search back y hours instead of days (useful for 24 hours reports) +* date_hours_back_to_search - Number of hours to search backwards #####Web * web_enabled - Enable the creation of the web page diff --git a/scripts/config.conf b/scripts/config.conf index 59e06d2..700106c 100644 --- a/scripts/config.conf +++ b/scripts/config.conf @@ -8,7 +8,9 @@ web_folder = '' ##General date_format = '%m/%d/%y' -days_back_to_search = 7 +date_days_back_to_search = 7 +date_use_hours = False +date_hours_back_to_search = 24 ##Image Upload - If this option is enabled, image hosting will be used for web and email #Cloudinary - Sign up for a free account at: http://cloudinary.com/ diff --git a/scripts/plexEmail.py b/scripts/plexEmail.py index 4d316d5..4295c0a 100644 --- a/scripts/plexEmail.py +++ b/scripts/plexEmail.py @@ -19,19 +19,10 @@ from email.header import Header from email.utils import formataddr -def replaceConfigTokens(): - for value in config: - if (isinstance(config[value], str)): - config[value] = config[value].replace('{past_day}', str((date.today() - timedelta(days=config['days_back_to_search'])).strftime(config['date_format']))) - config[value] = config[value].replace('{current_day}', str(date.today().strftime(config['date_format']))) - config[value] = config[value].replace('{website}', config['web_domain'] + config['web_path']) - config[value] = config[value].replace('{path_sep}', os.path.sep) - - if (config['plex_data_folder'] and config['plex_data_folder'].rfind(os.path.sep) < len(config['plex_data_folder']) - len(os.path.sep)): - config['plex_data_folder'] = config['plex_data_folder'] + os.path.sep - - if (config['web_folder'] and config['web_folder'].rfind(os.path.sep) < len(config['web_folder']) - len(os.path.sep)): - config['web_folder'] = config['web_folder'] + os.path.sep +def replaceConfigTokens(): + ## The below code is for backwards compatibility + if ('date_days_back_to_search' not in config and 'days_back_to_search' in config): + config['date_days_back_to_search'] = config['days_back_to_search'] if ('movie_sort_1' not in config.keys() or config['movie_sort_1'] == ""): config['movie_sort_1'] = 'rating' @@ -80,6 +71,22 @@ def replaceConfigTokens(): config['episode_sort_2_reverse'] = False if ('episode_sort_3_reverse' not in config.keys() or config['episode_sort_3_reverse'] == ""): config['episode_sort_3_reverse'] = False + + for value in config: + if (isinstance(config[value], str)): + if ('date_use_hours' in config and config['date_use_hours']): + config[value] = config[value].replace('{past_day}', str((date.today() - timedelta(hours=config['date_hours_back_to_search'])).strftime(config['date_format']))) + else: + config[value] = config[value].replace('{past_day}', str((date.today() - timedelta(days=config['date_days_back_to_search'])).strftime(config['date_format']))) + config[value] = config[value].replace('{current_day}', str(date.today().strftime(config['date_format']))) + config[value] = config[value].replace('{website}', config['web_domain'] + config['web_path']) + config[value] = config[value].replace('{path_sep}', os.path.sep) + + if (config['plex_data_folder'] and config['plex_data_folder'].rfind(os.path.sep) < len(config['plex_data_folder']) - len(os.path.sep)): + config['plex_data_folder'] = config['plex_data_folder'] + os.path.sep + + if (config['web_folder'] and config['web_folder'].rfind(os.path.sep) < len(config['web_folder']) - len(os.path.sep)): + config['web_folder'] = config['web_folder'] + os.path.sep def deleteImages(): folder = config['web_folder'] + config['web_path'] + os.path.sep + 'images' + os.path.sep @@ -198,10 +205,10 @@ def sendMail(email): text = config['msg_email_teaser'] # Record the MIME types of both parts - text/plain and text/html. - if containsnonasciicharacters(emailText): - htmltext = MIMEText(emailText, 'html','utf-8') + if containsnonasciicharacters(emailHTML): + htmltext = MIMEText(emailHTML, 'html','utf-8') else: - htmltext = MIMEText(emailText, 'html') + htmltext = MIMEText(emailHTML, 'html') if(containsnonasciicharacters(text)): plaintext = MIMEText(text,'plain','utf-8') @@ -228,33 +235,9 @@ def sendMail(email): server.login(gmail_user, gmail_pwd) server.sendmail(FROM, TO, msg.as_string()) server.close() - -config = {} -execfile(os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'config.conf', config) -replaceConfigTokens() - -if ('upload_use_cloudinary' in config and config['upload_use_cloudinary']): - cloudinary.config( - cloud_name = config['upload_cloudinary_cloud_name'], - api_key = config['upload_cloudinary_api_key'], - api_secret = config['upload_cloudinary_api_secret'] - ) - -DATABASE_FILE = config['plex_data_folder'] + 'Plex Media Server' + os.path.sep + 'Plug-in Support' + os.path.sep + 'Databases' + os.path.sep + 'com.plexapp.plugins.library.db' -con = sqlite3.connect(DATABASE_FILE) -con.text_factory = str - -with con: - - cur = con.cursor() - cur.execute("SELECT id, parent_id, metadata_type, title, title_sort, original_title, rating, tagline, summary, content_rating, duration, user_thumb_url, tags_genre, tags_director, tags_star, year, hash, [index], studio FROM metadata_items WHERE added_at >= date('now', '-" + str(config['days_back_to_search']) + " days') AND metadata_type >= 1 AND metadata_type <= 4 ORDER BY title_sort;") - - response = {}; - for row in cur: - response[row[0]] = {'id': row[0], 'parent_id': row[1], 'metadata_type': row[2], 'title': row[3], 'title_sort': row[4], 'original_title': row[5], 'rating': row[6], 'tagline': row[7], 'summary': row[8], 'content_rating': row[9], 'duration': row[10], 'user_thumb_url': row[11], 'tags_genre': row[12], 'tags_director': row[13], 'tags_star': row[14], 'year': row[15], 'hash': row[16], 'index': row[17], 'studio': row[18]} - - emailText = """ +def createEmailHTML(): + emailText = """ @@ -300,90 +283,196 @@ def sendMail(email):
""" + + if (movieCount > 0): + emailText += emailMovies + '
 ' + if (showCount > 0): + emailText += emailTVShows + '
 ' + if (seasonCount > 0): + emailText += emailTVSeasons + '
 ' + if (episodeCount > 0): + emailText += emailTVEpisodes + emailText += """ + +
+
+
+

Copyright © Jake Waldron 2015

+
+
+
- html = """ - +
+ - + + - - - - - + + - """ + config['msg_web_title'] + """ + - - + """ + + return emailText + +def createWebHTML(): + htmlText = """ + - - - - - - - - + - - - + + + + + - + """ + config['msg_web_title'] + """ - + + - - + + + + + + + + + + + + + + + + + + + + + +
+
+
+

""" + config['msg_header1'] + """

+

""" + config['msg_header2'] + """

+
+
+
+ + +
""" + + if (movieCount > 0): + htmlText += htmlMovies + '
 ' + if (showCount > 0): + htmlText += htmlTVShows + '
 ' + if (seasonCount > 0): + htmlText += htmlTVSeasons + '
 ' + if (episodeCount > 0): + htmlText += htmlTVEpisodes + + htmlText += """
+ +
+
+
+

""" + config['msg_footer'] + """

+
+
+
- -
-
-
-

""" + config['msg_header1'] + """

-

""" + config['msg_header2'] + """

-
-
-
+
+ - -
""" + + + + + + + + + """ + + return htmlText + +config = {} +execfile(os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'config.conf', config) +replaceConfigTokens() + +if ('upload_use_cloudinary' in config and config['upload_use_cloudinary']): + cloudinary.config( + cloud_name = config['upload_cloudinary_cloud_name'], + api_key = config['upload_cloudinary_api_key'], + api_secret = config['upload_cloudinary_api_secret'] + ) + +DATABASE_FILE = config['plex_data_folder'] + 'Plex Media Server' + os.path.sep + 'Plug-in Support' + os.path.sep + 'Databases' + os.path.sep + 'com.plexapp.plugins.library.db' + +con = sqlite3.connect(DATABASE_FILE) +con.text_factory = str + +with con: + + if ('date_use_hours' in config and config['date_use_hours']): + dateSearch = 'date(\'now\', \'-' + str(config['date_hours_back_to_search']) + ' hours\')' + else: + dateSearch = 'date(\'now\', \'-' + str(config['date_days_back_to_search']) + ' days\')' + cur = con.cursor() + cur.execute("SELECT id, parent_id, metadata_type, title, title_sort, original_title, rating, tagline, summary, content_rating, duration, user_thumb_url, tags_genre, tags_director, tags_star, year, hash, [index], studio FROM metadata_items WHERE added_at >= " + dateSearch + " AND metadata_type >= 1 AND metadata_type <= 4 ORDER BY title_sort;") + + response = {}; + for row in cur: + response[row[0]] = {'id': row[0], 'parent_id': row[1], 'metadata_type': row[2], 'title': row[3], 'title_sort': row[4], 'original_title': row[5], 'rating': row[6], 'tagline': row[7], 'summary': row[8], 'content_rating': row[9], 'duration': row[10], 'user_thumb_url': row[11], 'tags_genre': row[12], 'tags_director': row[13], 'tags_star': row[14], 'year': row[15], 'hash': row[16], 'index': row[17], 'studio': row[18]} emailMovies = """

""" + config['msg_new_movies_header'] + """

@@ -418,6 +507,10 @@ def sendMail(email): tvSeasons = {} tvEpisodes = {} imgNames = {} + movieCount = 0 + showCount = 0 + seasonCount = 0 + episodeCount = 0 if (config['web_enabled'] and 'web_delete_previous_images' in config and config['web_delete_previous_images']): deleteImages() for item in response: @@ -442,6 +535,7 @@ def sendMail(email): movies = OrderedDict(sorted(movies.iteritems(), key=lambda t: t[1][config['movie_sort_1']], reverse=config['movie_sort_1_reverse'])) for movie in movies: + movieCount += 1 title = '' if (movies[movie]['original_title'] != ''): title += movies[movie]['original_title'] + ' AKA ' @@ -489,6 +583,7 @@ def sendMail(email): tvShows = OrderedDict(sorted(tvShows.iteritems(), key=lambda t: t[1][config['show_sort_1']], reverse=config['show_sort_1_reverse'])) for show in tvShows: + showCount += 1 title = '' if (tvShows[show]['original_title'] != ''): title += tvShows[show]['original_title'] + ' AKA ' @@ -547,6 +642,7 @@ def sendMail(email): tvSeasons = OrderedDict(sorted(tvSeasons.iteritems(), key=lambda t: t[1][config['season_sort_1']], reverse=config['season_sort_1_reverse'])) for season in tvSeasons: + seasonCount += 1 title = '' if (tvSeasons[season]['original_title'] != ''): title += tvSeasons[season]['original_title'] + ' AKA ' @@ -615,6 +711,7 @@ def sendMail(email): for episode in tvEpisodes: if (tvEpisodes[episode]['parent_id'] not in tvSeasons): + episodeCount += 1 showTitle = '' if (tvEpisodes[episode]['show_original_title'] != ''): showTitle += tvEpisodes[episode]['show_original_title'] + ' AKA ' @@ -657,56 +754,12 @@ def sendMail(email): htmlTVEpisodes += '

Network: ' + tvEpisodes[episode]['studio'].decode('utf-8') + '

' htmlTVEpisodes += '

 
 ' - emailText += emailMovies + '
 ' + emailTVShows + '
 ' + emailTVSeasons + '
 ' + emailTVEpisodes + """ - - - - - - - - - - - - - - -""" - - html += htmlMovies + '
 ' + htmlTVShows + '
 ' + htmlTVSeasons + '
 ' + htmlTVEpisodes + """
- - - - - - - - - - - - - - - -""" + emailHTML = createEmailHTML() + webHTML = createWebHTML() if (config['web_enabled']): with open(config['web_folder'] + config['web_path'] + os.path.sep + 'index.html', 'w') as text_file: - text_file.write(html.encode('utf-8')) + text_file.write(webHTML.encode('utf-8')) if (config['email_enabled']): try: