diff --git a/python_apps/media-monitor/MediaMonitor.py b/python_apps/media-monitor/MediaMonitor.py index c4429b0f6..773c99fe6 100644 --- a/python_apps/media-monitor/MediaMonitor.py +++ b/python_apps/media-monitor/MediaMonitor.py @@ -63,7 +63,7 @@ try: wm = WatchManager() pe = AirtimeProcessEvent(queue=multi_queue, airtime_config=config, wm=wm) - bootstrap = AirtimeMediaMonitorBootstrap(logger, multi_queue, pe, api_client) + bootstrap = AirtimeMediaMonitorBootstrap(logger, pe, api_client) bootstrap.scan() notifier = AirtimeNotifier(wm, pe, read_freq=1, timeout=0, airtime_config=config, api_client=api_client, bootstrap=bootstrap) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py b/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py index 2761f3a5d..35d69e6f7 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py @@ -5,15 +5,19 @@ from subprocess import Popen, PIPE class AirtimeMediaMonitorBootstrap(): - def __init__(self, logger, multi_queue, pe, api_client): + """AirtimeMediaMonitorBootstrap constructor + + Keyword Arguments: + logger -- reference to the media-monitor logging facility + pe -- reference to an instance of ProcessEvent + api_clients -- reference of api_clients to communicate with airtime-server + """ + def __init__(self, logger, pe, api_client): self.logger = logger - self.multi_queue = multi_queue self.pe = pe - self.airtime_tmp = '/var/tmp/airtime' self.api_client = api_client - """ - on bootup we want to scan all directories and look for files that + """On bootup we want to scan all directories and look for files that weren't there or files that changed before media-monitor process went offline. """ @@ -24,19 +28,39 @@ class AirtimeMediaMonitorBootstrap(): for id, dir in directories.iteritems(): self.logger.debug("%s, %s", id, dir) - self.check_for_diff(id, dir) + self.sync_database_to_filesystem(id, dir) + """Gets a list of files that the Airtime database knows for a specific directory. + You need to provide the directory's row ID, which is obtained when calling + get_list_of_watched_dirs function. + dir_id -- row id of the directory in the cc_watched_dirs database table + """ def list_db_files(self, dir_id): 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 Stor directory, which can be identified by its row id (always has value of "1") + """ def get_list_of_watched_dirs(self): json = self.api_client.list_all_watched_dirs() return json["dirs"] - def check_for_diff(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. + """ + This function takes in a path name provided by the database (and its corresponding row id) + and reads the list of files in the local file system. Its purpose is to discover which files + exist on the file system but not in the database and vice versa, as well as which files have + been modified since the database was last updated. In each case, this method will call an + appropiate method to ensure that the database actually represents the filesystem. + dir_id -- row id of the directory in the cc_watched_dirs database table + dir -- pathname of the directory + """ + 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() @@ -52,15 +76,14 @@ class AirtimeMediaMonitorBootstrap(): if len(file_path.strip(" \n")) > 0: all_files_set.add(file_path[len(dir)+1:]) - if os.path.exists("/var/tmp/airtime/.last_index"): - #find files that have been modified since the last time - #media-monitor process started. - time_diff_sec = time.time() - os.path.getmtime("/var/tmp/airtime/.last_index") + if os.path.exists(self.pe.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.pe.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.execCommandAndReturnStdOut(command) + stdout = self.pe.execCommandAndReturnStdOut(command) stdout = unicode(stdout, "utf_8") new_files = stdout.splitlines() @@ -69,12 +92,14 @@ class AirtimeMediaMonitorBootstrap(): if len(file_path.strip(" \n")) > 0: new_and_modified_files.add(file_path[len(dir)+1:]) - #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. + """ + 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 @@ -99,17 +124,4 @@ class AirtimeMediaMonitorBootstrap(): file_path = "%s/%s" % (dir, file_path) if os.path.exists(file_path): self.pe.handle_modified_file(False, os.path.basename(file_path), file_path) - - def execCommand(self, command): - p = Popen(command, shell=True) - sts = os.waitpid(p.pid, 0)[1] - if sts != 0: - self.logger.warn("command \n%s\n return with a non-zero return value", command) - - def execCommandAndReturnStdOut(self, command): - p = Popen(command, shell=True, stdout=PIPE) - stdout = p.communicate()[0] - if p.returncode != 0: - self.logger.warn("command \n%s\n return with a non-zero return value", command) - return stdout - \ No newline at end of file + \ No newline at end of file diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py b/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py index d05af0282..b799c55ce 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py @@ -92,7 +92,7 @@ class AirtimeNotifier(Notifier): mm.set_needed_file_permissions(new_storage_directory, True) - self.bootstrap.check_for_diff(new_storage_directory_id, new_storage_directory) + 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') diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py index 1ade79d67..0054be1f2 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py @@ -19,6 +19,8 @@ from airtimefilemonitor.mediaconfig import AirtimeMediaConfig class AirtimeProcessEvent(ProcessEvent): + timestamp_file = "/var/tmp/airtime/last_index" + def my_init(self, queue, airtime_config=None, wm=None): """ Method automatically called from ProcessEvent.__init__(). Additional @@ -394,7 +396,7 @@ class AirtimeProcessEvent(ProcessEvent): return stdout.splitlines() def touch_index_file(self): - open("/var/tmp/airtime/.last_index", "w") + open(self.timestamp_file, "w") def notifier_loop_callback(self, notifier): if len(self.file_events) > 0: