From 938c503e85c06a5fe273fea6af45838b123145ee Mon Sep 17 00:00:00 2001 From: James Date: Thu, 4 Aug 2011 18:36:40 -0400 Subject: [PATCH] CC-2633: media monitor crashes on non-ascii files and metadata - fixed bug for the case where mutagen return None for metadata - fixed bug for non-ascii files and metadata --- python_apps/api_clients/api_client.py | 2 +- python_apps/media-monitor/MediaMonitor.py | 3 +- .../airtimefilemonitor/airtimemetadata.py | 24 +++++++++----- .../airtimefilemonitor/airtimenotifier.py | 32 ++++++++++--------- python_apps/media-monitor/logging.cfg | 16 ++++++++-- 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 081e08846..becba51db 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -402,7 +402,7 @@ class AirTimeApiClient(ApiClientInterface): req = urllib2.Request(url, data) response = urllib2.urlopen(req).read() - logger.info("update media %s", response) + logger.info("update media %s, filepath: %s, mode: %s", response, md['MDATA_KEY_FILEPATH'], mode) response = json.loads(response) elapsed = (time.time() - start) diff --git a/python_apps/media-monitor/MediaMonitor.py b/python_apps/media-monitor/MediaMonitor.py index f7f67516b..b96f186e5 100644 --- a/python_apps/media-monitor/MediaMonitor.py +++ b/python_apps/media-monitor/MediaMonitor.py @@ -70,7 +70,8 @@ try: #create 5 worker threads wp = MediaMonitorWorkerProcess() for i in range(5): - t = Thread(target=wp.process_file_events, args=(multi_queue, notifier)) + threadName = "Thread #%d" % i + t = Thread(target=wp.process_file_events, name=threadName, args=(multi_queue, notifier)) t.start() wdd = notifier.watch_directory(storage_directory) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimemetadata.py b/python_apps/media-monitor/airtimefilemonitor/airtimemetadata.py index 01fede71c..9376cd110 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimemetadata.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimemetadata.py @@ -5,11 +5,16 @@ import logging import math import re +def to_unicode(obj, encoding='utf-8'): + if isinstance(obj, basestring): + if not isinstance(obj, unicode): + obj = unicode(obj, encoding) + return obj + """ list of supported easy tags in mutagen version 1.20 ['albumartistsort', 'musicbrainz_albumstatus', 'lyricist', 'releasecountry', 'date', 'performer', 'musicbrainz_albumartistid', 'composer', 'encodedby', 'tracknumber', 'musicbrainz_albumid', 'album', 'asin', 'musicbrainz_artistid', 'mood', 'copyright', 'author', 'media', 'length', 'version', 'artistsort', 'titlesort', 'discsubtitle', 'website', 'musicip_fingerprint', 'conductor', 'compilation', 'barcode', 'performer:*', 'composersort', 'musicbrainz_discid', 'musicbrainz_albumtype', 'genre', 'isrc', 'discnumber', 'musicbrainz_trmid', 'replaygain_*_gain', 'musicip_puid', 'artist', 'title', 'bpm', 'musicbrainz_trackid', 'arranger', 'albumsort', 'replaygain_*_peak', 'organization'] """ - class AirtimeMetadata: def __init__(self): @@ -108,7 +113,6 @@ class AirtimeMetadata: def get_md_from_file(self, filepath): - self.logger.debug("testing upgrade") self.logger.info("getting info from filepath %s", filepath) try: @@ -125,7 +129,8 @@ class AirtimeMetadata: self.logger.info(file_info) - + if file_info is None: + return None #check if file has any metadata if file_info is not None: for key in file_info.keys() : @@ -134,11 +139,13 @@ class AirtimeMetadata: if 'MDATA_KEY_TITLE' not in md: #get rid of file extention from original name, name might have more than 1 '.' in it. + filepath = to_unicode(filepath) + filepath = filepath.encode('utf-8') original_name = os.path.basename(filepath) original_name = original_name.split(".")[0:-1] original_name = ''.join(original_name) md['MDATA_KEY_TITLE'] = original_name - + #incase track number is in format u'4/11' #need to also check that the tracknumber is even a tracknumber (cc-2582) if 'MDATA_KEY_TRACKNUMBER' in md: @@ -175,10 +182,11 @@ class AirtimeMetadata: #do this so object can be urlencoded properly. for key in md.keys(): - if(isinstance(md[key], basestring)): + + if (isinstance(md[key], basestring)): + #self.logger.info("Converting md[%s] = '%s' ", key, md[key]) + md[key] = to_unicode(md[key]) md[key] = md[key].encode('utf-8') - - self.logger.info("MD after parsing.") - self.logger.debug(md) + #self.logger.info("Converting complete: md[%s] = '%s' ", key, md[key]) return md diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py b/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py index 7c4e706f8..3fef2ca2b 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py @@ -119,25 +119,27 @@ class AirtimeNotifier(Notifier): os.unlink(filepath) - #update airtime with information about files discovered in our - #watched directories. Pass in a dict() object with the following - #attributes: - # -filepath - # -mode - # -data - # -is_recorded_show - def update_airtime(self, d): + """ + Update airtime with information about files discovered in our + watched directories. + event: a dict() object with the following attributes: + -filepath + -mode + -data + -is_recorded_show + """ + def update_airtime(self, event): try: - self.logger.info("updating filepath: %s ", d['filepath']) - filepath = d['filepath'] - mode = d['mode'] + self.logger.info("updating filepath: %s ", event['filepath']) + filepath = event['filepath'] + mode = event['mode'] md = {} md['MDATA_KEY_FILEPATH'] = filepath - if 'data' in d: - file_md = d['data'] + if 'data' in event: + file_md = event['data'] md.update(file_md) else: file_md = None @@ -151,7 +153,7 @@ class AirtimeNotifier(Notifier): return md.update(mutagen) - if d['is_recorded_show']: + if event['is_recorded_show']: self.api_client.update_media_metadata(md, mode, True) else: self.api_client.update_media_metadata(md, mode) @@ -171,7 +173,7 @@ class AirtimeNotifier(Notifier): self.api_client.update_media_metadata(md, mode) except Exception, e: - self.logger.error("failed updating filepath: %s ", d['filepath']) + self.logger.error("failed updating filepath: %s ", event['filepath']) self.logger.error('Exception: %s', e) #define which directories the pyinotify WatchManager should watch. diff --git a/python_apps/media-monitor/logging.cfg b/python_apps/media-monitor/logging.cfg index c0a43564c..ea24f69e0 100644 --- a/python_apps/media-monitor/logging.cfg +++ b/python_apps/media-monitor/logging.cfg @@ -1,5 +1,5 @@ [loggers] -keys=root +keys= root,notifier,metadata [handlers] keys=fileOutHandler @@ -11,12 +11,22 @@ keys=simpleFormatter level=DEBUG handlers=fileOutHandler +[logger_notifier] +level=DEBUG +handlers=fileOutHandler +qualname=notifier + +[logger_metadata] +level=DEBUG +handlers=fileOutHandler +qualname=metadata + [handler_fileOutHandler] class=logging.handlers.RotatingFileHandler level=DEBUG formatter=simpleFormatter -args=("/var/log/airtime/media-monitor/media-monitor.log", 'a', 1000000, 5,) +args=("/var/log/airtime/media-monitor/media-monitor.log", 'a', 10000000, 5,) [formatter_simpleFormatter] -format=%(asctime)s %(levelname)s - [%(filename)s : %(funcName)s() : line %(lineno)d] - %(message)s +format=%(asctime)s %(levelname)s - [%(threadName)s] [%(filename)s : %(funcName)s()] : LINE %(lineno)d - %(message)s datefmt=