def copy_or_move_files_to(paths, dest, flag): try: for path in paths: if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') dest = apc.encode_to(dest, 'utf-8') if(os.path.exists(path)): if(os.path.isdir(path)): path = format_dir_string(path) #construct full path sub_path = [] for temp in os.listdir(path): sub_path.append(path+temp) copy_or_move_files_to(sub_path, dest, flag) elif(os.path.isfile(path)): #copy file to dest ext = os.path.splitext(path)[1] if( 'mp3' in ext or 'ogg' in ext ): destfile = dest+os.path.basename(path) if(flag == 'copy'): print "Copying %(src)s to %(dest)s..." % {'src':path, 'dest':destfile} shutil.copyfile(path, destfile) elif(flag == 'move'): print "Moving %(src)s to %(dest)s..." % {'src':path, 'dest':destfile} shutil.move(path, destfile) else: print "Cannot find file or path: %s" % path except Exception as e: print "Error: ", e
def copy_or_move_files_to(paths, dest, flag): try: for path in paths: if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') dest = apc.encode_to(dest, 'utf-8') if(os.path.exists(path)): if(os.path.isdir(path)): path = format_dir_string(path) #construct full path sub_path = [] for temp in os.listdir(path): sub_path.append(path+temp) copy_or_move_files_to(sub_path, dest, flag) elif(os.path.isfile(path)): #copy file to dest ext = os.path.splitext(path)[1] if( 'mp3' in ext or 'ogg' in ext ): destfile = dest+os.path.basename(path) if(flag == 'copy'): print "Copying %(src)s to %(dest)s..." % {'src':path, 'dest':destfile} shutil.copyfile(path, destfile) elif(flag == 'move'): print "Moving %(src)s to %(dest)s..." % {'src':path, 'dest':destfile} shutil.move(path, destfile) else: print "Cannot find file or path: %s" % path except Exception as e: print "Error: ", e
def WatchRemoveAction(option, opt, value, parser): errorIfMultipleOption(parser.rargs) if (len(parser.rargs) > 1): raise OptionValueError( "Too many arguments. This option requires exactly one argument.") elif (len(parser.rargs) == 0): raise OptionValueError( "No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir + path path = apc.encode_to(path, 'utf-8') if (os.path.isdir(path)): res = api_client.remove_watched_dir(path) if (res is None): exit("Unable to connect to the Airtime server.") # sucess if (res['msg']['code'] == 0): print "%s removed from watch folder list successfully." % path else: print "Removing the watch folder failed: %s" % res['msg']['error'] else: print "The given path is not a directory: %s" % path
def write_liquidsoap_config(self, setting): fh = open('/etc/airtime/liquidsoap.cfg', 'w') self.logger.info("Rewriting liquidsoap.cfg...") fh.write("################################################\n") fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n") fh.write("################################################\n") for k, d in setting: buffer_str = d[u'keyname'] + " = " if d[u'type'] == 'string': temp = d[u'value'] buffer_str += '"%s"' % temp else: temp = d[u'value'] if temp == "": temp = "0" buffer_str += temp buffer_str += "\n" fh.write(api_client.encode_to(buffer_str)) fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n"); fh.close() # restarting pypo. # we could just restart liquidsoap but it take more time somehow. self.logger.info("Restarting pypo...") sys.exit(0)
def WatchAddAction(option, opt, value, parser): errorIfMultipleOption(parser.rargs) if(len(parser.rargs) > 1): raise OptionValueError("Too many arguments. This option requires exactly one argument.") elif(len(parser.rargs) == 0 ): raise OptionValueError("No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') if(os.path.isdir(path)): #os.chmod(path, 0765) try: res = api_client.add_watched_dir(path) except Exception, e: exit("Unable to connect to the server.") # sucess if(res['msg']['code'] == 0): print "%s added to watched folder list successfully" % path else: print "Adding a watched folder failed: %s" % res['msg']['error'] print "This error most likely caused by wrong permissions" print "Try fixing this error by chmodding the parent directory(ies)"
def write_liquidsoap_config(self, setting): fh = open('/etc/airtime/liquidsoap.cfg', 'w') self.logger.info("Rewriting liquidsoap.cfg...") fh.write("################################################\n") fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n") fh.write("################################################\n") for k, d in setting: buffer_str = d[u'keyname'] + " = " if d[u'type'] == 'string': temp = d[u'value'] buffer_str += '"%s"' % temp else: temp = d[u'value'] if temp == "": temp = "0" buffer_str += temp buffer_str += "\n" fh.write(api_client.encode_to(buffer_str)) fh.write( "log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n") fh.close() # restarting pypo. # we could just restart liquidsoap but it take more time somehow. self.logger.info("Restarting pypo...") sys.exit(0)
def WatchAddAction(option, opt, value, parser): errorIfMultipleOption(parser.rargs) if(len(parser.rargs) > 1): raise OptionValueError("Too many arguments. This option requires exactly one argument.") elif(len(parser.rargs) == 0 ): raise OptionValueError("No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') if(os.path.isdir(path)): #os.chmod(path, 0765) try: res = api_client.add_watched_dir(path) except Exception, e: exit("Unable to connect to the server.") # sucess if(res['msg']['code'] == 0): print "%s added to watched folder list successfully" % path else: print "Adding a watched folder failed: %s" % res['msg']['error'] print "This error most likely caused by wrong permissions" print "Try fixing this error by chmodding the parent directory(ies)"
def scan(self): directories = self.get_list_of_watched_dirs(); self.logger.info("watched directories found: %s", directories) for id, dir in directories.iteritems(): self.logger.debug("%s, %s", id, dir) self.sync_database_to_filesystem(id, api_client.encode_to(dir, "utf-8"))
def scan(self): directories = self.get_list_of_watched_dirs() self.logger.info("watched directories found: %s", directories) for id, dir in directories.iteritems(): self.logger.debug("%s, %s", id, dir) self.sync_database_to_filesystem( id, api_client.encode_to(dir, "utf-8"))
def StorageSetAction(option, opt, value, parser): bypass = False isF = '-f' in parser.rargs isForce = '--force' in parser.rargs if (isF or isForce): bypass = True if (isF): parser.rargs.remove('-f') if (isForce): parser.rargs.remove('--force') if (not bypass): errorIfMultipleOption( parser.rargs, "Only [-f] and [--force] option is allowed with this option.") possibleInput = ['y', 'Y', 'n', 'N'] confirm = raw_input( "Are you sure you want to change the storage direcory? (y/N)") confirm = confirm or 'N' while (confirm not in possibleInput): print "Not an acceptable input: %s\n" % confirm confirm = raw_input( "Are you sure you want to change the storage direcory? (y/N) ") confirm = confirm or 'N' if (confirm == 'n' or confirm == 'N'): sys.exit(1) if (len(parser.rargs) > 1): raise OptionValueError( "Too many arguments. This option requires exactly one argument.") elif (len(parser.rargs) == 0): raise OptionValueError( "No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir + path path = apc.encode_to(path, 'utf-8') if (os.path.isdir(path)): res = api_client.set_storage_dir(path) if (res is None): exit("Unable to connect to the Airtime server.") # sucess if (res['msg']['code'] == 0): print "Successfully set storage folder to %s" % path else: print "Setting storage folder failed: %s" % res['msg']['error'] else: print "The given path is not a directory: %s" % path
def StorageSetAction(option, opt, value, parser): bypass = False isF = '-f' in parser.rargs isForce = '--force' in parser.rargs if(isF or isForce ): bypass = True if(isF): parser.rargs.remove('-f') if(isForce): parser.rargs.remove('--force') if(not bypass): errorIfMultipleOption(parser.rargs, "Only [-f] and [--force] option is allowed with this option.") possibleInput = ['y','Y','n','N'] confirm = raw_input("Are you sure you want to change the storage direcory? (y/N)") confirm = confirm or 'N' while(confirm not in possibleInput): print "Not an acceptable input: %s\n" % confirm confirm = raw_input("Are you sure you want to change the storage direcory? (y/N) ") confirm = confirm or 'N' if(confirm == 'n' or confirm =='N'): sys.exit(1) if(len(parser.rargs) > 1): raise OptionValueError("Too many arguments. This option requires exactly one argument.") elif(len(parser.rargs) == 0 ): raise OptionValueError("No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') if(os.path.isdir(path)): res = api_client.set_storage_dir(path) if(res is None): exit("Unable to connect to the Airtime server.") # sucess if(res['msg']['code'] == 0): print "Successfully set storage folder to %s" % path else: print "Setting storage folder failed: %s" % res['msg']['error'] else: print "The given path is not a directory: %s" % path
def generate_liquidsoap_config(ss): data = ss['msg'] fh = open('/etc/airtime/liquidsoap.cfg', 'w') fh.write("################################################\n") fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n") fh.write("################################################\n") for d in data: buffer = d[u'keyname'] + " = " if(d[u'type'] == 'string'): temp = d[u'value'] buffer += '"%s"' % temp else: temp = d[u'value'] if(temp == ""): temp = "0" buffer += temp buffer += "\n" fh.write(api_client.encode_to(buffer)) fh.write('log_file = "/var/log/airtime/pypo-liquidsoap/<script>.log"\n') fh.close()
def generate_liquidsoap_config(ss): data = ss['msg'] fh = open('/etc/airtime/liquidsoap.cfg', 'w') fh.write("################################################\n") fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n") fh.write("################################################\n") for d in data: buffer = d[u'keyname'] + " = " if (d[u'type'] == 'string'): temp = d[u'value'] buffer += '"%s"' % temp else: temp = d[u'value'] if (temp == ""): temp = "0" buffer += temp buffer += "\n" fh.write(api_client.encode_to(buffer)) fh.write('log_file = "/var/log/airtime/pypo-liquidsoap/<script>.log"\n') fh.close()
def WatchRemoveAction(option, opt, value, parser): errorIfMultipleOption(parser.rargs) if(len(parser.rargs) > 1): raise OptionValueError("Too many arguments. This option requires exactly one argument.") elif(len(parser.rargs) == 0 ): raise OptionValueError("No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') if(os.path.isdir(path)): try: res = api_client.remove_watched_dir(path) except Exception, e: exit("Unable to connect to the Airtime server.") # sucess if(res['msg']['code'] == 0): print "%s removed from watch folder list successfully." % path else: print "Removing the watch folder failed: %s" % res['msg']['error']
def WatchAddAction(option, opt, value, parser): errorIfMultipleOption(parser.rargs) if(len(parser.rargs) > 1): raise OptionValueError("Too many arguments. This option requires exactly one argument.") elif(len(parser.rargs) == 0 ): raise OptionValueError("No argument found. This option requires exactly one argument.") path = parser.rargs[0] if (path[0] == "/" or path[0] == "~"): path = os.path.realpath(path) else: path = currentDir+path path = apc.encode_to(path, 'utf-8') if(os.path.isdir(path)): res = api_client.add_watched_dir(path) if(res is None): exit("Unable to connect to the server.") # sucess if(res['msg']['code'] == 0): print "%s added to watched folder list successfully" % path else: print "Adding a watched folder failed: %s" % res['msg']['error'] else: print "Given path is not a directory: %s" % path
def create_file_path(self, original_path, orig_md): storage_directory = self.config.storage_directory is_recorded_show = False try: #will be in the format .ext file_ext = os.path.splitext(original_path)[1] file_ext = api_client.encode_to(file_ext, 'utf-8') path_md = [ 'MDATA_KEY_TITLE', 'MDATA_KEY_CREATOR', 'MDATA_KEY_SOURCE', 'MDATA_KEY_TRACKNUMBER', 'MDATA_KEY_BITRATE' ] md = {} for m in path_md: if m not in orig_md: md[m] = api_client.encode_to(u'unknown', 'utf-8') else: #get rid of any "/" which will interfere with the filepath. if isinstance(orig_md[m], basestring): md[m] = orig_md[m].replace("/", "-") else: md[m] = orig_md[m] if 'MDATA_KEY_TRACKNUMBER' in orig_md: #make sure all track numbers are at least 2 digits long in the filepath. md['MDATA_KEY_TRACKNUMBER'] = "%02d" % (int( md['MDATA_KEY_TRACKNUMBER'])) #format bitrate as 128kbps md['MDATA_KEY_BITRATE'] = str( md['MDATA_KEY_BITRATE'] / 1000) + "kbps" filepath = None #file is recorded by Airtime #/srv/airtime/stor/recorded/year/month/year-month-day-time-showname-bitrate.ext if (md['MDATA_KEY_CREATOR'] == api_client.encode_to( "Airtime Show Recorder", 'utf-8')): #yyyy-mm-dd-hh-MM-ss y = orig_md['MDATA_KEY_YEAR'].split("-") filepath = '%s/%s/%s/%s/%s-%s-%s%s' % ( storage_directory, api_client.encode_to( "recorded", 'utf-8'), y[0], y[1], orig_md['MDATA_KEY_YEAR'], md['MDATA_KEY_TITLE'], md['MDATA_KEY_BITRATE'], file_ext) #"Show-Title-2011-03-28-17:15:00" title = md['MDATA_KEY_TITLE'].split("-") show_hour = title[0] show_min = title[1] show_sec = title[2] show_name = '-'.join(title[3:]) new_md = {} new_md["MDATA_KEY_FILEPATH"] = original_path new_md['MDATA_KEY_TITLE'] = '%s-%s-%s:%s:%s' % ( show_name, orig_md['MDATA_KEY_YEAR'], show_hour, show_min, show_sec) self.md_manager.save_md_to_file(new_md) elif (md['MDATA_KEY_TRACKNUMBER'] == api_client.encode_to( u'unknown', 'utf-8')): filepath = '%s/%s/%s/%s/%s-%s%s' % ( storage_directory, api_client.encode_to( "imported", 'utf-8'), md['MDATA_KEY_CREATOR'], md['MDATA_KEY_SOURCE'], md['MDATA_KEY_TITLE'], md['MDATA_KEY_BITRATE'], file_ext) else: filepath = '%s/%s/%s/%s/%s-%s-%s%s' % ( storage_directory, api_client.encode_to( "imported", 'utf-8'), md['MDATA_KEY_CREATOR'], md['MDATA_KEY_SOURCE'], md['MDATA_KEY_TRACKNUMBER'], md['MDATA_KEY_TITLE'], md['MDATA_KEY_BITRATE'], file_ext) filepath = self.create_unique_filename(filepath, original_path) self.logger.info('Unique filepath: %s', filepath) self.ensure_is_dir(os.path.dirname(filepath)) except Exception, e: self.logger.error('Exception: %s', e)
def sync_database_to_filesystem(self, dir_id, dir): """ set to hold new and/or modified files. We use a set to make it ok if files are added twice. This is because some of the tests for new files return result sets that are not mutually exclusive from each other. """ new_and_modified_files = set() removed_files = set() db_known_files_set = set() files = self.list_db_files(dir_id) for file in files['files']: db_known_files_set.add(api_client.encode_to(file, 'utf-8')) new_files = self.mmc.scan_dir_for_new_files(dir) all_files_set = set() for file_path in new_files: if len(file_path.strip(" \n")) > 0: all_files_set.add(file_path[len(dir):]) if os.path.exists(self.mmc.timestamp_file): """find files that have been modified since the last time media-monitor process started.""" time_diff_sec = time.time() - os.path.getmtime(self.mmc.timestamp_file) command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable -mmin -%d" % (dir, time_diff_sec/60+1) else: command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable" % dir stdout = self.mmc.exec_command(command) #self.logger.info(stdout) new_files = stdout.splitlines() for file_path in new_files: if len(file_path.strip(" \n")) > 0: new_and_modified_files.add(file_path[len(dir):]) """ new_and_modified_files gives us a set of files that were either copied or modified since the last time media-monitor was running. These files were collected based on their modified timestamp. But this is not all that has changed in the directory. Files could have been removed, or files could have been moved into this directory (moving does not affect last modified timestamp). Lets get a list of files that are on the file-system that the db has no record of, and vice-versa. """ deleted_files_set = db_known_files_set - all_files_set new_files_set = all_files_set - db_known_files_set modified_files_set = new_and_modified_files - new_files_set #NAOMI: Please comment out the "Known files" line, if you find the bug. #it is for debugging purposes only (Too much data will be written to log). -mk #self.logger.info("Known files: \n%s\n\n"%db_known_files_set) self.logger.info("Deleted files: \n%s\n\n"%deleted_files_set) self.logger.info("New files: \n%s\n\n"%new_files_set) self.logger.info("Modified files: \n%s\n\n"%modified_files_set) #"touch" file timestamp try: self.mmc.touch_index_file() except Exception, e: self.logger.warn(e)
logger = logging.getLogger() logger.info("\n\n*** Media Monitor bootup ***\n\n") try: config = AirtimeMediaConfig(logger) api_client = apc.api_client_factory(config.cfg) logger.info("Setting up monitor") response = None while response is None: response = api_client.setup_media_monitor() time.sleep(5) storage_directory = apc.encode_to(response["stor"], 'utf-8') logger.info("Storage Directory is: %s", storage_directory) config.storage_directory = os.path.normpath(storage_directory) config.imported_directory = os.path.normpath(storage_directory + '/imported') config.organize_directory = os.path.normpath(storage_directory + '/organize') config.recorded_directory = os.path.normpath(storage_directory + '/recorded') multi_queue = mpQueue() logger.info("Initializing event processor") except Exception, e: logger.error('Exception: %s', e) try: wm = WatchManager()
def sync_database_to_filesystem(self, dir_id, dir): """ set to hold new and/or modified files. We use a set to make it ok if files are added twice. This is because some of the tests for new files return result sets that are not mutually exclusive from each other. """ new_and_modified_files = set() removed_files = set() db_known_files_set = set() files = self.list_db_files(dir_id) for file in files['files']: db_known_files_set.add(api_client.encode_to(file, 'utf-8')) new_files = self.mmc.scan_dir_for_new_files(dir) all_files_set = set() for file_path in new_files: if len(file_path.strip(" \n")) > 0: all_files_set.add(file_path[len(dir):]) if os.path.exists(self.mmc.timestamp_file): """find files that have been modified since the last time media-monitor process started.""" time_diff_sec = time.time() - os.path.getmtime( self.mmc.timestamp_file) command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable -mmin -%d" % ( dir, time_diff_sec / 60 + 1) else: command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable" % dir stdout = self.mmc.exec_command(command) #self.logger.info(stdout) new_files = stdout.splitlines() for file_path in new_files: if len(file_path.strip(" \n")) > 0: new_and_modified_files.add(file_path[len(dir):]) """ new_and_modified_files gives us a set of files that were either copied or modified since the last time media-monitor was running. These files were collected based on their modified timestamp. But this is not all that has changed in the directory. Files could have been removed, or files could have been moved into this directory (moving does not affect last modified timestamp). Lets get a list of files that are on the file-system that the db has no record of, and vice-versa. """ deleted_files_set = db_known_files_set - all_files_set new_files_set = all_files_set - db_known_files_set modified_files_set = new_and_modified_files - new_files_set #NAOMI: Please comment out the "Known files" line, if you find the bug. #it is for debugging purposes only (Too much data will be written to log). -mk #self.logger.info("Known files: \n%s\n\n"%db_known_files_set) self.logger.info("Deleted files: \n%s\n\n" % deleted_files_set) self.logger.info("New files: \n%s\n\n" % new_files_set) self.logger.info("Modified files: \n%s\n\n" % modified_files_set) #"touch" file timestamp try: self.mmc.touch_index_file() except Exception, e: self.logger.warn(e)
def handle_message(self, body, message): # ACK the message to take it off the queue message.ack() self.logger.info("Received md from RabbitMQ: " + body) m = json.loads(message.body) if m['event_type'] == "md_update": self.logger.info("AIRTIME NOTIFIER md update event") self.md_manager.save_md_to_file(m) elif m['event_type'] == "new_watch": self.logger.info("AIRTIME NOTIFIER add watched folder event " + m['directory']) self.walk_newly_watched_directory(m['directory']) self.watch_directory(m['directory']) elif m['event_type'] == "remove_watch": watched_directory = api_client.encode_to(m['directory'], 'utf-8') mm = self.proc_fun() wd = mm.wm.get_wd(watched_directory) self.logger.info("Removing watch on: %s wd %s", watched_directory, wd) mm.wm.rm_watch(wd, rec=True) elif m['event_type'] == "change_stor": storage_directory = self.config.storage_directory new_storage_directory = api_client.encode_to( m['directory'], 'utf-8') new_storage_directory_id = api_client.encode_to( str(m['dir_id']), 'utf-8') mm = self.proc_fun() wd = mm.wm.get_wd(storage_directory) self.logger.info("Removing watch on: %s wd %s", storage_directory, wd) mm.wm.rm_watch(wd, rec=True) self.bootstrap.sync_database_to_filesystem( new_storage_directory_id, new_storage_directory) self.config.storage_directory = os.path.normpath( new_storage_directory) self.config.imported_directory = os.path.normpath( new_storage_directory + '/imported') self.config.organize_directory = os.path.normpath( new_storage_directory + '/organize') self.mmc.ensure_is_dir(self.config.storage_directory) self.mmc.ensure_is_dir(self.config.imported_directory) self.mmc.ensure_is_dir(self.config.organize_directory) self.mmc.set_needed_file_permissions(self.config.storage_directory, True) self.mmc.set_needed_file_permissions( self.config.imported_directory, True) self.mmc.set_needed_file_permissions( self.config.organize_directory, True) self.watch_directory(new_storage_directory) elif m['event_type'] == "file_delete": filepath = api_client.encode_to(m['filepath'], 'utf-8') mm = self.proc_fun() self.logger.info("Adding file to ignore: %s ", filepath) mm.add_filepath_to_ignore(filepath) if m['delete']: self.logger.info("Deleting file: %s ", filepath) os.unlink(filepath)
def create_file_path(self, original_path, orig_md): storage_directory = self.config.storage_directory is_recorded_show = False try: #will be in the format .ext file_ext = os.path.splitext(original_path)[1] file_ext = api_client.encode_to(file_ext, 'utf-8') path_md = ['MDATA_KEY_TITLE', 'MDATA_KEY_CREATOR', 'MDATA_KEY_SOURCE', 'MDATA_KEY_TRACKNUMBER', 'MDATA_KEY_BITRATE'] md = {} for m in path_md: if m not in orig_md: md[m] = api_client.encode_to(u'unknown', 'utf-8') else: #get rid of any "/" which will interfere with the filepath. if isinstance(orig_md[m], basestring): md[m] = orig_md[m].replace("/", "-") else: md[m] = orig_md[m] if 'MDATA_KEY_TRACKNUMBER' in orig_md: #make sure all track numbers are at least 2 digits long in the filepath. md['MDATA_KEY_TRACKNUMBER'] = "%02d" % (int(md['MDATA_KEY_TRACKNUMBER'])) #format bitrate as 128kbps md['MDATA_KEY_BITRATE'] = str(md['MDATA_KEY_BITRATE']/1000)+"kbps" filepath = None #file is recorded by Airtime #/srv/airtime/stor/recorded/year/month/year-month-day-time-showname-bitrate.ext if(md['MDATA_KEY_CREATOR'] == api_client.encode_to("Airtime Show Recorder", 'utf-8')): #yyyy-mm-dd-hh-MM-ss y = orig_md['MDATA_KEY_YEAR'].split("-") filepath = '%s/%s/%s/%s/%s-%s-%s%s' % (storage_directory, api_client.encode_to("recorded", 'utf-8'), y[0], y[1], orig_md['MDATA_KEY_YEAR'], md['MDATA_KEY_TITLE'], md['MDATA_KEY_BITRATE'], file_ext) #"Show-Title-2011-03-28-17:15:00" title = md['MDATA_KEY_TITLE'].split("-") show_hour = title[0] show_min = title[1] show_sec = title[2] show_name = '-'.join(title[3:]) new_md = {} new_md["MDATA_KEY_FILEPATH"] = original_path new_md['MDATA_KEY_TITLE'] = '%s-%s-%s:%s:%s' % (show_name, orig_md['MDATA_KEY_YEAR'], show_hour, show_min, show_sec) self.md_manager.save_md_to_file(new_md) elif(md['MDATA_KEY_TRACKNUMBER'] == api_client.encode_to(u'unknown', 'utf-8')): filepath = '%s/%s/%s/%s/%s-%s%s' % (storage_directory, api_client.encode_to("imported", 'utf-8'), md['MDATA_KEY_CREATOR'], md['MDATA_KEY_SOURCE'], md['MDATA_KEY_TITLE'], md['MDATA_KEY_BITRATE'], file_ext) else: filepath = '%s/%s/%s/%s/%s-%s-%s%s' % (storage_directory, api_client.encode_to("imported", 'utf-8'), md['MDATA_KEY_CREATOR'], md['MDATA_KEY_SOURCE'], md['MDATA_KEY_TRACKNUMBER'], md['MDATA_KEY_TITLE'], md['MDATA_KEY_BITRATE'], file_ext) filepath = self.create_unique_filename(filepath, original_path) self.logger.info('Unique filepath: %s', filepath) self.ensure_is_dir(os.path.dirname(filepath)) except Exception, e: self.logger.error('Exception: %s', e)
def handle_message(self, body, message): # ACK the message to take it off the queue message.ack() self.logger.info("Received md from RabbitMQ: " + body) m = json.loads(message.body) if m['event_type'] == "md_update": self.logger.info("AIRTIME NOTIFIER md update event") self.md_manager.save_md_to_file(m) elif m['event_type'] == "new_watch": self.logger.info("AIRTIME NOTIFIER add watched folder event " + m['directory']) self.walk_newly_watched_directory(m['directory']) self.watch_directory(m['directory']) elif m['event_type'] == "remove_watch": watched_directory = api_client.encode_to(m['directory'], 'utf-8') mm = self.proc_fun() wd = mm.wm.get_wd(watched_directory) self.logger.info("Removing watch on: %s wd %s", watched_directory, wd) mm.wm.rm_watch(wd, rec=True) elif m['event_type'] == "change_stor": storage_directory = self.config.storage_directory new_storage_directory = api_client.encode_to(m['directory'], 'utf-8') new_storage_directory_id = api_client.encode_to(str(m['dir_id']), 'utf-8') mm = self.proc_fun() wd = mm.wm.get_wd(storage_directory) self.logger.info("Removing watch on: %s wd %s", storage_directory, wd) mm.wm.rm_watch(wd, rec=True) self.bootstrap.sync_database_to_filesystem(new_storage_directory_id, new_storage_directory) self.config.storage_directory = os.path.normpath(new_storage_directory) self.config.imported_directory = os.path.normpath(new_storage_directory + '/imported') self.config.organize_directory = os.path.normpath(new_storage_directory + '/organize') self.mmc.ensure_is_dir(self.config.storage_directory) self.mmc.ensure_is_dir(self.config.imported_directory) self.mmc.ensure_is_dir(self.config.organize_directory) self.mmc.set_needed_file_permissions(self.config.storage_directory, True) self.mmc.set_needed_file_permissions(self.config.imported_directory, True) self.mmc.set_needed_file_permissions(self.config.organize_directory, True) self.watch_directory(new_storage_directory) elif m['event_type'] == "file_delete": filepath = api_client.encode_to(m['filepath'], 'utf-8') mm = self.proc_fun() self.logger.info("Adding file to ignore: %s ", filepath) mm.add_filepath_to_ignore(filepath) if m['delete']: self.logger.info("Deleting file: %s ", filepath) os.unlink(filepath)
if 'MDATA_KEY_URL' in md: md['MDATA_KEY_URL'] = self.truncate_to_length(md['MDATA_KEY_URL'], 512) if 'MDATA_KEY_ISRC' in md: md['MDATA_KEY_ISRC'] = self.truncate_to_length(md['MDATA_KEY_ISRC'], 512) if 'MDATA_KEY_COPYRIGHT' in md: md['MDATA_KEY_COPYRIGHT'] = self.truncate_to_length(md['MDATA_KEY_COPYRIGHT'], 512) #end of db truncation checks. md['MDATA_KEY_BITRATE'] = file_info.info.bitrate md['MDATA_KEY_SAMPLERATE'] = file_info.info.sample_rate md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length) md['MDATA_KEY_MIME'] = file_info.mime[0] if "mp3" in md['MDATA_KEY_MIME']: md['MDATA_KEY_FTYPE'] = "audioclip" elif "vorbis" in md['MDATA_KEY_MIME']: md['MDATA_KEY_FTYPE'] = "audioclip" #do this so object can be urlencoded properly. for key in md.keys(): if (isinstance(md[key], basestring)): #self.logger.info("Converting md[%s] = '%s' ", key, md[key]) md[key] = api_client.encode_to(md[key], 'utf-8') #self.logger.info("Converting complete: md[%s] = '%s' ", key, md[key]) return md