Merge branch 'devel' into mediamonitor2
Conflicts: python_apps/api_clients/api_client.py
This commit is contained in:
commit
20e32b98ba
31 changed files with 253 additions and 143 deletions
|
@ -40,8 +40,7 @@ class AirtimeMediaMonitorBootstrap():
|
|||
went offline.
|
||||
"""
|
||||
def scan(self):
|
||||
directories = self.get_list_of_watched_dirs();
|
||||
|
||||
directories = self.get_list_of_watched_dirs()
|
||||
self.logger.info("watched directories found: %s", directories)
|
||||
|
||||
for id, dir in directories.iteritems():
|
||||
|
@ -57,12 +56,21 @@ class AirtimeMediaMonitorBootstrap():
|
|||
return self.api_client.list_all_db_files(dir_id)
|
||||
|
||||
"""
|
||||
returns the path and the database row id for this path for all watched directories. Also
|
||||
returns the path and its corresponding database row idfor all watched directories. Also
|
||||
returns the Stor directory, which can be identified by its row id (always has value of "1")
|
||||
|
||||
Return type is a dictionary similar to:
|
||||
{"1":"/srv/airtime/stor/"}
|
||||
"""
|
||||
def get_list_of_watched_dirs(self):
|
||||
json = self.api_client.list_all_watched_dirs()
|
||||
return json["dirs"]
|
||||
|
||||
try:
|
||||
return json["dirs"]
|
||||
except KeyError as e:
|
||||
self.logger.error("Could not find index 'dirs' in dictionary: %s", str(json))
|
||||
self.logger.error(e)
|
||||
return {}
|
||||
|
||||
"""
|
||||
This function takes in a path name provided by the database (and its corresponding row id)
|
||||
|
@ -86,8 +94,9 @@ class AirtimeMediaMonitorBootstrap():
|
|||
|
||||
db_known_files_set = set()
|
||||
files = self.list_db_files(dir_id)
|
||||
for file in files['files']:
|
||||
db_known_files_set.add(file)
|
||||
|
||||
for f in files:
|
||||
db_known_files_set.add(f)
|
||||
|
||||
all_files = self.mmc.clean_dirty_file_paths( self.mmc.scan_dir_for_new_files(dir) )
|
||||
|
||||
|
@ -111,10 +120,9 @@ class AirtimeMediaMonitorBootstrap():
|
|||
stdout = self.mmc.exec_command(command)
|
||||
|
||||
if stdout is None:
|
||||
self.logger.error("Unrecoverable error when syncing db to filesystem.")
|
||||
return
|
||||
|
||||
new_files = self.mmc.clean_dirty_file_paths(stdout.splitlines())
|
||||
new_files = []
|
||||
else:
|
||||
new_files = stdout.splitlines()
|
||||
|
||||
new_and_modified_files = set()
|
||||
for file_path in new_files:
|
||||
|
|
|
@ -12,8 +12,17 @@ import traceback
|
|||
|
||||
"""
|
||||
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']
|
||||
['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):
|
||||
|
@ -57,10 +66,17 @@ class AirtimeMetadata:
|
|||
self.logger = logging.getLogger()
|
||||
|
||||
def get_md5(self, filepath):
|
||||
f = open(filepath, 'rb')
|
||||
m = hashlib.md5()
|
||||
m.update(f.read())
|
||||
md5 = m.hexdigest()
|
||||
"""
|
||||
Returns an md5 of the file located at filepath. Returns an empty string
|
||||
if there was an error reading the file.
|
||||
"""
|
||||
try:
|
||||
f = open(filepath, 'rb')
|
||||
m = hashlib.md5()
|
||||
m.update(f.read())
|
||||
md5 = m.hexdigest()
|
||||
except Exception, e:
|
||||
return ""
|
||||
|
||||
return md5
|
||||
|
||||
|
@ -121,6 +137,10 @@ class AirtimeMetadata:
|
|||
return item
|
||||
|
||||
def get_md_from_file(self, filepath):
|
||||
"""
|
||||
Returns None if error retrieving metadata. Otherwise returns a dictionary
|
||||
representing the file's metadata
|
||||
"""
|
||||
|
||||
self.logger.info("getting info from filepath %s", filepath)
|
||||
|
||||
|
@ -136,7 +156,6 @@ class AirtimeMetadata:
|
|||
md['MDATA_KEY_MD5'] = md5
|
||||
|
||||
file_info = mutagen.File(filepath, easy=True)
|
||||
|
||||
except Exception, e:
|
||||
self.logger.error("failed getting metadata from %s", filepath)
|
||||
self.logger.error("Exception %s", e)
|
||||
|
@ -146,18 +165,16 @@ class AirtimeMetadata:
|
|||
#check if file has any metadata
|
||||
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() :
|
||||
if key in self.mutagen2airtime:
|
||||
val = file_info[key]
|
||||
try:
|
||||
if val is not None and len(val) > 0 and val[0] is not None and len(val[0]) > 0:
|
||||
md[self.mutagen2airtime[key]] = val[0]
|
||||
except Exception, e:
|
||||
self.logger.error('Exception: %s', e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
|
||||
for key in file_info.keys() :
|
||||
if key in self.mutagen2airtime:
|
||||
val = file_info[key]
|
||||
try:
|
||||
if val is not None and len(val) > 0 and val[0] is not None and len(val[0]) > 0:
|
||||
md[self.mutagen2airtime[key]] = val[0]
|
||||
except Exception, e:
|
||||
self.logger.error('Exception: %s', e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
if 'MDATA_KEY_TITLE' not in md:
|
||||
#get rid of file extension from original name, name might have more than 1 '.' in it.
|
||||
original_name = os.path.basename(filepath)
|
||||
|
@ -228,18 +245,24 @@ class AirtimeMetadata:
|
|||
md['MDATA_KEY_COPYRIGHT'] = self.truncate_to_length(md['MDATA_KEY_COPYRIGHT'], 512)
|
||||
#end of db truncation checks.
|
||||
|
||||
md['MDATA_KEY_BITRATE'] = getattr(file_info.info, "bitrate", None)
|
||||
md['MDATA_KEY_SAMPLERATE'] = getattr(file_info.info, "sample_rate", None)
|
||||
self.logger.info("Bitrate: %s , Samplerate: %s", md['MDATA_KEY_BITRATE'], md['MDATA_KEY_SAMPLERATE'])
|
||||
try: md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length)
|
||||
except Exception as e: self.logger.warn("File: '%s' raises: %s", filepath, str(e))
|
||||
|
||||
try: md['MDATA_KEY_MIME'] = file_info.mime[0]
|
||||
except Exception as e: self.logger.warn("File: '%s' has no mime type", filepath, str(e))
|
||||
try:
|
||||
md['MDATA_KEY_BITRATE'] = getattr(file_info.info, "bitrate", 0)
|
||||
md['MDATA_KEY_SAMPLERATE'] = getattr(file_info.info, "sample_rate", 0)
|
||||
|
||||
md['MDATA_KEY_DURATION'] = self.format_length(getattr(file_info.info, "length", 0.0))
|
||||
|
||||
md['MDATA_KEY_MIME'] = ""
|
||||
if len(file_info.mime) > 0:
|
||||
md['MDATA_KEY_MIME'] = file_info.mime[0]
|
||||
except Exception as e:
|
||||
self.logger.warn(e)
|
||||
|
||||
if "mp3" in md['MDATA_KEY_MIME']:
|
||||
md['MDATA_KEY_FTYPE'] = "audioclip"
|
||||
elif "vorbis" in md['MDATA_KEY_MIME']:
|
||||
md['MDATA_KEY_FTYPE'] = "audioclip"
|
||||
else:
|
||||
self.logger.error("File %s of mime type %s does not appear to be a valid vorbis or mp3 file." % (filepath, md['MDATA_KEY_MIME']))
|
||||
return None
|
||||
|
||||
return md
|
||||
|
|
|
@ -36,6 +36,11 @@ class AirtimeNotifier(Notifier):
|
|||
time.sleep(5)
|
||||
|
||||
def init_rabbit_mq(self):
|
||||
"""
|
||||
This function will attempt to connect to RabbitMQ Server and if successful
|
||||
return 'True'. Returns 'False' otherwise.
|
||||
"""
|
||||
|
||||
self.logger.info("Initializing RabbitMQ stuff")
|
||||
try:
|
||||
schedule_exchange = Exchange("airtime-media-monitor", "direct", durable=True, auto_delete=True)
|
||||
|
|
|
@ -291,7 +291,10 @@ class MediaMonitorCommon:
|
|||
self.logger.debug(command)
|
||||
stdout = self.exec_command(command)
|
||||
|
||||
return stdout.splitlines()
|
||||
if stdout is None:
|
||||
return []
|
||||
else:
|
||||
return stdout.splitlines()
|
||||
|
||||
def touch_index_file(self):
|
||||
dirname = os.path.dirname(self.timestamp_file)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue