Skip to content

Commit 8e56040

Browse files
authored
Merge pull request #76 from jakewaldron/dev
Dev
2 parents a13252e + db8b809 commit 8e56040

File tree

2 files changed

+69
-25
lines changed

2 files changed

+69
-25
lines changed

scripts/config.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ date_format = '%m/%d/%y'
1313
date_days_back_to_search = 7
1414
date_hours_back_to_search = 0
1515
date_minutes_back_to_search = 0
16-
#If DLNA is enabled, this can be left blank; otherwise set this if using plex web links. Example (the portion of all X's is the value): https://app.plex.tv/web/app#!/server/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/details/%2Flibrary%2Fmetadata%2F43268
16+
#If DLNA is enabled, this can be left blank; otherwise set this if using plex web links. Example (the portion of all X's is the value): https://app.plex.tv/web/app#!/server/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/details?key=%2Flibrary%2Fmetadata%2F43268
1717
plex_web_server_guid = ''
1818

1919
##Logging
20+
logging_enabled = True
2021
logging_debug_level = 'INFO'
2122
#Leave blank to use default location - logs folder where the script file resides
2223
logging_file_location = ''
@@ -65,6 +66,7 @@ email_skip_if_no_additions = False
6566

6667
##Filtering
6768
filter_include_plex_web_link = True
69+
filter_include_original_title = True
6870
filter_show_movies = True
6971
filter_movies_include = []
7072
filter_movies_exclude = []

scripts/plexEmail.py

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@
2525
from email.utils import formataddr
2626
from xml.etree.ElementTree import XML
2727

28-
SCRIPT_VERSION = 'v0.9.0'
28+
SCRIPT_VERSION = 'v0.9.3'
2929

3030
def replaceConfigTokens():
3131
## The below code is for backwards compatibility
32+
if ('filter_include_original_title' not in config):
33+
config['filter_include_original_title'] = True
34+
35+
if ('logging_enabled' not in config):
36+
config['logging_enabled'] = True
37+
3238
if ('plex_web_server_guid' not in config):
3339
config['plex_web_server_guid'] = ''
3440

@@ -288,6 +294,9 @@ def replaceConfigTokens():
288294

289295
if (config['web_domain'] != '' and config['web_domain'].rfind('/') < len(config['web_domain']) - len('/')):
290296
config['web_domain'] = config['web_domain'] + '/'
297+
298+
if (config['logging_file_location'].rfind(os.path.sep) < len(config['logging_file_location']) - len(os.path.sep)):
299+
config['logging_file_location'] = config['logging_file_location'] + os.path.sep
291300

292301

293302
def convertToHumanReadable(valuesToConvert):
@@ -863,21 +872,25 @@ def exceptionHandler(type, value, tb):
863872
config = {}
864873
execfile(configFile, config)
865874
replaceConfigTokens()
866-
867-
numeric_level = getattr(logging, config['logging_debug_level'], None)
868-
file_mode = 'a' if (config['logging_retain_previous_logs']) else 'w'
869-
if not isinstance(numeric_level, int):
870-
numeric_level = getattr(logging, 'INFO')
871-
if not os.path.exists(os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'logs'):
872-
os.makedirs(os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'logs')
873-
logging.basicConfig(level=numeric_level, format='%(asctime)s - %(levelname)s:%(message)s', filename=os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'logs' + os.path.sep + 'plexEmail.log', filemode=file_mode)
874875

875-
sys.excepthook = exceptionHandler
876+
if (config['logging_enabled']):
877+
numeric_level = getattr(logging, config['logging_debug_level'], None)
878+
file_mode = 'a' if (config['logging_retain_previous_logs']) else 'w'
879+
if not isinstance(numeric_level, int):
880+
numeric_level = getattr(logging, 'INFO')
881+
if (config['logging_file_location'] != ''):
882+
logging.basicConfig(level=numeric_level, format='%(asctime)s - %(levelname)s:%(message)s', filename=config['logging_file_location'] + 'plexEmail.log', filemode=file_mode)
883+
else:
884+
if not os.path.exists(os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'logs'):
885+
os.makedirs(os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'logs')
886+
logging.basicConfig(level=numeric_level, format='%(asctime)s - %(levelname)s:%(message)s', filename=os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep + 'logs' + os.path.sep + 'plexEmail.log', filemode=file_mode)
887+
888+
sys.excepthook = exceptionHandler
876889

877890
testMode = False
878891

879892
if ('test' in args):
880-
logging.info('Test flag found - setting script instance to test mode.')
893+
logging.info('Test flag is set to ' + str(args['test']))
881894
testMode = args['test']
882895
else:
883896
logging.info('Test flag not found.')
@@ -899,21 +912,26 @@ def exceptionHandler(type, value, tb):
899912
plexWebLink = ''
900913

901914
if (config['filter_include_plex_web_link']):
902-
if (config['plex_web_server_guid'] == ''):
903-
plexWebLink = 'http://plex.tv/web/app#!/server/' + config['plex_web_server_guid'] + '/details/%2Flibrary%2Fmetadata%2F'
915+
if (config['plex_web_server_guid'] != ''):
916+
plexWebLink = 'http://plex.tv/web/app#!/server/' + config['plex_web_server_guid'] + '/details?key=%2Flibrary%2Fmetadata%2F'
904917
else:
905918
logging.info('Including Plex Web Link - Getting machine identifier from the DLNA DB')
906919
DLNA_DB_FILE = config['plex_data_folder'] + 'Plex Media Server' + os.path.sep + 'Plug-in Support' + os.path.sep + 'Databases' + os.path.sep + 'com.plexapp.dlna.db'
907920
logging.info('DLNA_DB_FILE = ' + DLNA_DB_FILE)
908921

909922
if (os.path.isfile(DLNA_DB_FILE)):
910923
try:
911-
con = sqlite3.connect(DLNA_DB_FILE)
924+
shutil.copyfile(DLNA_DB_FILE, DLNA_DB_FILE + '_plexemail')
925+
con = sqlite3.connect(DLNA_DB_FILE + '_plexemail')
912926
cur = con.cursor()
913927
cur.execute('SELECT machine_identifier FROM remote_servers WHERE url LIKE "http://127.0.0.1%";')
914928
for row in cur:
915-
plexWebLink = 'http://plex.tv/web/app#!/server/' + row[0] + '/details/%2Flibrary%2Fmetadata%2F'
929+
plexWebLink = 'http://plex.tv/web/app#!/server/' + row[0] + '/details?key=%2Flibrary%2Fmetadata%2F'
916930
logging.info('plexWebLink = ' + plexWebLink)
931+
cur.close()
932+
del cur
933+
con.close()
934+
os.remove(DLNA_DB_FILE + '_plexemail')
917935
except sqlite3.OperationalError:
918936
logging.warning(DLNA_DB_FILE + ' is locked or does not have the correct permissions')
919937
else:
@@ -926,7 +944,8 @@ def exceptionHandler(type, value, tb):
926944
print DATABASE_FILE + ' does not exist. Please make sure the plex_data_folder value is correct.'
927945
sys.exit()
928946

929-
con = sqlite3.connect(DATABASE_FILE)
947+
shutil.copyfile(DATABASE_FILE, DATABASE_FILE + '_plexemail')
948+
con = sqlite3.connect(DATABASE_FILE + '_plexemail')
930949
con.text_factory = str
931950

932951
with con:
@@ -946,6 +965,9 @@ def exceptionHandler(type, value, tb):
946965
libraryFilter += ') '
947966
logging.debug('libraryFilter = ' + libraryFilter)
948967

968+
cur.close()
969+
del cur
970+
949971
dateSearch = 'datetime(\'now\', \'localtime\', \'-' + str(config['date_days_back_to_search']) + ' days\', \'-' + str(config['date_hours_back_to_search']) + ' hours\', \'-' + str(config['date_minutes_back_to_search']) + ' minutes\')'
950972
logging.debug('dateSearch for DB query = ' + dateSearch)
951973

@@ -960,6 +982,9 @@ def exceptionHandler(type, value, tb):
960982
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], 'real_duration': row[19], 'air_date': row[20]}
961983
logging.debug(response[row[0]])
962984

985+
cur.close()
986+
del cur
987+
963988
emailNotice = ''
964989
htmlNotice = ''
965990
if (config['msg_notice']):
@@ -1067,7 +1092,7 @@ def exceptionHandler(type, value, tb):
10671092
for movie in movies:
10681093
movies[movie] = convertToHumanReadable(movies[movie])
10691094
title = ''
1070-
if ('original_title' in movies[movie] and movies[movie]['original_title'] != ''):
1095+
if (config['filter_include_original_title'] and 'original_title' in movies[movie] and movies[movie]['original_title'] != ''):
10711096
title += movies[movie]['original_title'] + ' AKA '
10721097
title += movies[movie]['title']
10731098
hash = str(movies[movie]['hash'])
@@ -1127,7 +1152,7 @@ def exceptionHandler(type, value, tb):
11271152
for show in tvShows:
11281153
tvShows[show] = convertToHumanReadable(tvShows[show])
11291154
title = ''
1130-
if (tvShows[show]['original_title'] != ''):
1155+
if (config['filter_include_original_title'] and 'original_title' in tvShows[show] and tvShows[show]['original_title'] != ''):
11311156
title += tvShows[show]['original_title'] + ' AKA '
11321157
title += tvShows[show]['title']
11331158
hash = str(tvShows[show]['hash'])
@@ -1195,6 +1220,9 @@ def exceptionHandler(type, value, tb):
11951220
tvSeasons[season]['parent_hash'] = row[12]
11961221
tvSeasons[season]['parent_thumb_url'] = row[13]
11971222
tvSeasons[season]['studio'] = row[14]
1223+
1224+
cur2.close()
1225+
del cur2
11981226

11991227
if ('season_sort_3' in config and config['season_sort_3'] != ''):
12001228
tvSeasons = OrderedDict(sorted(tvSeasons.iteritems(), key=lambda t: t[1][config['season_sort_3']], reverse=config['season_sort_3_reverse']))
@@ -1206,7 +1234,7 @@ def exceptionHandler(type, value, tb):
12061234
for season in tvSeasons:
12071235
tvSeasons[season] = convertToHumanReadable(tvSeasons[season])
12081236
title = ''
1209-
if (tvSeasons[season]['original_title'] != ''):
1237+
if (config['filter_include_original_title'] and 'original_title' in tvSeasons[season] and tvSeasons[season]['original_title'] != ''):
12101238
title += tvSeasons[season]['original_title'] + ' AKA '
12111239
title += tvSeasons[season]['title']
12121240
imageInfo = {}
@@ -1294,10 +1322,16 @@ def exceptionHandler(type, value, tb):
12941322
tvEpisodes[episode]['show_thumb_url'] = row2[8]
12951323
logging.debug('main: show_thumb_url = ' + row2[8])
12961324
tvEpisodes[episode]['studio'] = row2[9]
1325+
1326+
cur3.close()
1327+
del cur3
12971328
else:
12981329
logging.info('main: tvEpisodes[episode][\'parent_id\'] = None')
12991330
del modifiedTVEpisodes[episode]
13001331

1332+
cur2.close()
1333+
del cur2
1334+
13011335
tvEpisodes = dict(modifiedTVEpisodes)
13021336

13031337
if ('episode_sort_3' in config and config['episode_sort_3'] != ''):
@@ -1311,11 +1345,11 @@ def exceptionHandler(type, value, tb):
13111345
if (tvEpisodes[episode]['parent_id'] not in tvSeasons):
13121346
tvEpisodes[episode] = convertToHumanReadable(tvEpisodes[episode])
13131347
showTitle = ''
1314-
if (tvEpisodes[episode]['show_original_title'] != ''):
1348+
if (config['filter_include_original_title'] and 'original_title' in tvEpisodes[episode] and tvEpisodes[episode]['show_original_title'] != ''):
13151349
showTitle += tvEpisodes[episode]['show_original_title'] + ' AKA '
13161350
showTitle += tvEpisodes[episode]['show_title']
13171351
title = ''
1318-
if (tvEpisodes[episode]['original_title'] != ''):
1352+
if (config['filter_include_original_title'] and 'original_title' in tvEpisodes[episode] and tvEpisodes[episode]['original_title'] != ''):
13191353
title += tvEpisodes[episode]['original_title'] + ' AKA '
13201354
title += tvEpisodes[episode]['title']
13211355
imageInfo = {}
@@ -1387,7 +1421,7 @@ def exceptionHandler(type, value, tb):
13871421
for artist in artists:
13881422
artists[artist] = convertToHumanReadable(artists[artist])
13891423
title = ''
1390-
if (artists[artist]['original_title'] != ''):
1424+
if (config['filter_include_original_title'] and 'original_title' in artists[artist] and artists[artist]['original_title'] != ''):
13911425
title += artists[artist]['original_title'] + ' AKA '
13921426
title += artists[artist]['title']
13931427
hash = str(artists[artist]['hash'])
@@ -1457,6 +1491,9 @@ def exceptionHandler(type, value, tb):
14571491
albums[album]['parent_thumb_url'] = row[13]
14581492
albums[album]['studio'] = row[14]
14591493

1494+
cur2.close()
1495+
del cur2
1496+
14601497
cur2 = con.cursor()
14611498
cur2.execute("SELECT MD.id, MD.title, MD.title_sort, MD.original_title, MD.[index], ME.duration, ME.audio_codec FROM metadata_items MD LEFT OUTER JOIN media_items ME ON MD.id = ME.metadata_item_id WHERE parent_id = " + str(albums[album]['id']) + ";")
14621499

@@ -1475,7 +1512,9 @@ def exceptionHandler(type, value, tb):
14751512
except TypeError:
14761513
duration = 'N/A'
14771514
albums[album]['tracks'][row[4]] = {'id': row[0], 'title': row[1], 'title_sort': row[2], 'original_title': row[3], 'index': row[4], 'duration': duration, 'codec': row[6]}
1478-
1515+
1516+
cur2.close()
1517+
del cur2
14791518
if ('album_sort_3' in config and config['album_sort_3'] != ''):
14801519
albums = OrderedDict(sorted(albums.iteritems(), key=lambda t: t[1][config['album_sort_3']], reverse=config['album_sort_3_reverse']))
14811520
if ('album_sort_2' in config and config['album_sort_2'] != ''):
@@ -1486,7 +1525,7 @@ def exceptionHandler(type, value, tb):
14861525
for album in albums:
14871526
albums[album] = convertToHumanReadable(albums[album])
14881527
title = ''
1489-
if (albums[album]['original_title'] != ''):
1528+
if (config['filter_include_original_title'] and 'original_title' in albums[album] and albums[album]['original_title'] != ''):
14901529
title += albums[album]['original_title'] + ' AKA '
14911530
title += albums[album]['title']
14921531
imageInfo = {}
@@ -1701,3 +1740,6 @@ def exceptionHandler(type, value, tb):
17011740
print 'Emails were not sent because the option is disabled in the config file.'
17021741
else:
17031742
print 'Emails were not sent because there were no new additions in the timeframe specified.'
1743+
1744+
con.close()
1745+
os.remove(DATABASE_FILE + '_plexemail')

0 commit comments

Comments
 (0)