From b1fa8901cad4f6297b138145210db2e930531886 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 27 Sep 2011 14:49:03 -0400 Subject: [PATCH 1/2] cc-2882: Airtime cannot delete watched folder when is been renamed - initial commit --- .../application/controllers/ApiController.php | 8 +++ airtime_mvc/application/models/MusicDir.php | 9 ++- airtime_mvc/application/models/StoredFile.php | 21 +++++++ python_apps/media-monitor/MediaMonitor.py | 5 +- .../airtimefilemonitor/airtimenotifier.py | 3 + .../airtimefilemonitor/airtimeprocessevent.py | 63 +++++++++++++++++-- .../airtimefilemonitor/mediaconfig.py | 1 + 7 files changed, 104 insertions(+), 6 deletions(-) diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 7e6b5768f..6576a9051 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -535,6 +535,14 @@ class ApiController extends Zend_Controller_Action $file->delete(); } } + else if ($mode == "delete_dir") { + $filepath = $md['MDATA_KEY_FILEPATH']; + $filepath = str_replace("\\", "", $filepath); + $files = Application_Model_StoredFile::RecallByPartialFilepath($filepath); + foreach($files as $file){ + $file->delete(); + } + } $this->view->id = $file->getId(); } diff --git a/airtime_mvc/application/models/MusicDir.php b/airtime_mvc/application/models/MusicDir.php index 0ca8ab00d..e3d537ee9 100644 --- a/airtime_mvc/application/models/MusicDir.php +++ b/airtime_mvc/application/models/MusicDir.php @@ -281,7 +281,14 @@ class Application_Model_MusicDir { } public static function removeWatchedDir($p_dir){ - $p_dir = realpath($p_dir)."/"; + $real_path = realpath($p_dir)."/"; + if($real_path != "/"){ + $p_dir = $real_path; + }else{ + // this is the case where user removes watched directory on + // the file system directly. + $p_dir .= "/"; + } $dir = Application_Model_MusicDir::getDirByPath($p_dir); if($dir == NULL){ return array("code"=>1,"error"=>"'$p_dir' doesn't exist in the watched list."); diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index a9f0913d7..b791a5255 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -576,6 +576,27 @@ class Application_Model_StoredFile { { return Application_Model_StoredFile::Recall(null, null, null, $p_filepath); } + + public static function RecallByPartialFilepath($partial_path){ + $path_info = Application_Model_MusicDir::splitFilePath($partial_path); + + if (is_null($path_info)) { + return null; + } + $music_dir = Application_Model_MusicDir::getDirByPath($path_info[0]); + + $files = CcFilesQuery::create() + ->filterByDbDirectory($music_dir->getId()) + ->filterByDbFilepath("$path_info[1]%") + ->find(); + $res = array(); + foreach ($files as $file){ + $storedFile = new Application_Model_StoredFile(); + $storedFile->_file = $file; + $res[] = $storedFile; + } + return $res; + } public static function searchFilesForPlaylistBuilder($datatables) { global $CC_CONFIG; diff --git a/python_apps/media-monitor/MediaMonitor.py b/python_apps/media-monitor/MediaMonitor.py index 7e8fceca8..af9b9e3f3 100644 --- a/python_apps/media-monitor/MediaMonitor.py +++ b/python_apps/media-monitor/MediaMonitor.py @@ -60,7 +60,7 @@ try: wm = WatchManager() mmc = MediaMonitorCommon(config) - pe = AirtimeProcessEvent(queue=multi_queue, airtime_config=config, wm=wm, mmc=mmc) + pe = AirtimeProcessEvent(queue=multi_queue, airtime_config=config, wm=wm, mmc=mmc, api_client=api_client) bootstrap = AirtimeMediaMonitorBootstrap(logger, pe, api_client, mmc) bootstrap.scan() @@ -90,4 +90,7 @@ except KeyboardInterrupt: notifier.stop() logger.info("Keyboard Interrupt") except Exception, e: + import traceback + top = traceback.format_exc() logger.error('Exception: %s', e) + logger.error("traceback: %s", top) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py b/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py index f6952e82c..1f75f0bba 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimenotifier.py @@ -171,6 +171,9 @@ class AirtimeNotifier(Notifier): elif (mode == self.config.MODE_DELETE): self.api_client.update_media_metadata(md, mode) + + elif (mode == self.config.MODE_DELETE_DIR): + self.api_client.update_media_metadata(md, mode) except Exception, e: self.logger.error("failed updating filepath: %s ", event['filepath']) diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py index 8bf25d0f6..6d891ad80 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py @@ -8,10 +8,12 @@ from pyinotify import ProcessEvent from airtimemetadata import AirtimeMetadata from airtimefilemonitor.mediaconfig import AirtimeMediaConfig +from api_clients import api_client + class AirtimeProcessEvent(ProcessEvent): #TODO - def my_init(self, queue, airtime_config=None, wm=None, mmc=None): + def my_init(self, queue, airtime_config=None, wm=None, mmc=None, api_client=api_client): """ Method automatically called from ProcessEvent.__init__(). Additional keyworded arguments passed to ProcessEvent.__init__() are then @@ -33,10 +35,63 @@ class AirtimeProcessEvent(ProcessEvent): self.wm = wm self.md_manager = AirtimeMetadata() self.mmc = mmc + self.api_client = api_client def add_filepath_to_ignore(self, filepath): self.ignore_event.add(filepath) + def process_IN_MOVE_SELF(self, event): + self.logger.info("event: %s", event) + if event.dir: + path = event.path + wd = self.wm.get_wd(path) + self.logger.info("Removing watch on: %s wd %s", path, wd) + self.wm.rm_watch(wd, rec=True) + if "-unknown-path" in path: + pos = path.find("-unknown-path") + path = path[0:pos] + + list = self.api_client.list_all_watched_dirs() + # case where the dir that is being watched is moved to somewhere + if path in list: + self.logger.info("Requesting the airtime server to remove '%s'", path) + res = self.api_client.remove_watched_dir(path) + if(res is None): + self.logger.info("Unable to connect to the Airtime server.") + # sucess + if(res['msg']['code'] == 0): + self.logger.info("%s removed from watch folder list successfully.", path) + else: + self.logger.info("Removing the watch folder failed: %s", res['msg']['error']) + else: + self.file_events.append({'mode': self.config.MODE_DELETE_DIR, 'filepath': path}) + + + def process_IN_DELETE_SELF(self, event): + self.logger.info("event: %s", event) + if event.dir: + path = event.path + wd = self.wm.get_wd(path) + self.logger.info("Removing watch on: %s wd %s", path, wd) + self.wm.rm_watch(wd, rec=True) + if "-unknown-path" in path: + pos = path.find("-unknown-path") + path = path[0:pos] + + list = self.api_client.list_all_watched_dirs() + if path in list: + self.logger.info("Requesting the airtime server to remove '%s'", path) + res = self.api_client.remove_watched_dir(path) + if(res is None): + self.logger.info("Unable to connect to the Airtime server.") + # sucess + if(res['msg']['code'] == 0): + self.logger.info("%s removed from watch folder list successfully.", path) + else: + self.logger.info("Removing the watch folder failed: %s", res['msg']['error']) + else: + self.file_events.append({'mode': self.config.MODE_DELETE_DIR, 'filepath': path}) + #event.dir: True if the event was raised against a directory. #event.name: filename #event.pathname: pathname (str): Concatenation of 'path' and 'name'. @@ -98,7 +153,7 @@ class AirtimeProcessEvent(ProcessEvent): if self.mmc.is_audio_file(event.name): self.cookies_IN_MOVED_FROM[event.cookie] = (event, time.time()) else: - self.cookies_IN_MOVED_FROM[event.cookie] = event.pathname + self.cookies_IN_MOVED_FROM[event.cookie] = (event, time.time()) #Some weird thing to note about this event: it seems that if a file is moved to a newly @@ -150,10 +205,10 @@ class AirtimeProcessEvent(ProcessEvent): for file in files: filepath = self.mmc.organize_new_file(file) if (filepath is not None): - self.file_events.append({'mode': mode, 'filepath': filepath}) + self.file_events.append({'mode': mode, 'filepath': filepath, 'is_recorded_show': False}) else: for file in files: - self.file_events.append({'mode': mode, 'filepath': file}) + self.file_events.append({'mode': mode, 'filepath': file, 'is_recorded_show': False}) def process_IN_DELETE(self, event): diff --git a/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py b/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py index 2b1197e24..2ddd71680 100644 --- a/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py +++ b/python_apps/media-monitor/airtimefilemonitor/mediaconfig.py @@ -8,6 +8,7 @@ class AirtimeMediaConfig: MODE_MODIFY = "modify" MODE_MOVED = "moved" MODE_DELETE = "delete" + MODE_DELETE_DIR = "delete_dir" def __init__(self, logger): From d1542b0d896ad1235d0cea103658097a1cebdd1e Mon Sep 17 00:00:00 2001 From: James Date: Wed, 28 Sep 2011 13:45:21 -0400 Subject: [PATCH 2/2] CC-2882: Airtime cannot delete watched folder when is been renamed - done --- .../application/controllers/ApiController.php | 1 + airtime_mvc/application/models/MusicDir.php | 4 -- .../airtimefilemonitor/airtimeprocessevent.py | 53 +++++++++---------- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 6576a9051..878b1f909 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -542,6 +542,7 @@ class ApiController extends Zend_Controller_Action foreach($files as $file){ $file->delete(); } + return; } $this->view->id = $file->getId(); } diff --git a/airtime_mvc/application/models/MusicDir.php b/airtime_mvc/application/models/MusicDir.php index e3d537ee9..028923a3e 100644 --- a/airtime_mvc/application/models/MusicDir.php +++ b/airtime_mvc/application/models/MusicDir.php @@ -284,10 +284,6 @@ class Application_Model_MusicDir { $real_path = realpath($p_dir)."/"; if($real_path != "/"){ $p_dir = $real_path; - }else{ - // this is the case where user removes watched directory on - // the file system directly. - $p_dir .= "/"; } $dir = Application_Model_MusicDir::getDirByPath($p_dir); if($dir == NULL){ diff --git a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py index 6d891ad80..c8670bb64 100644 --- a/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py +++ b/python_apps/media-monitor/airtimefilemonitor/airtimeprocessevent.py @@ -42,44 +42,41 @@ class AirtimeProcessEvent(ProcessEvent): def process_IN_MOVE_SELF(self, event): self.logger.info("event: %s", event) + path = event.path if event.dir: - path = event.path - wd = self.wm.get_wd(path) - self.logger.info("Removing watch on: %s wd %s", path, wd) - self.wm.rm_watch(wd, rec=True) if "-unknown-path" in path: + unkown_path = path pos = path.find("-unknown-path") - path = path[0:pos] + path = path[0:pos]+"/" - list = self.api_client.list_all_watched_dirs() - # case where the dir that is being watched is moved to somewhere - if path in list: - self.logger.info("Requesting the airtime server to remove '%s'", path) - res = self.api_client.remove_watched_dir(path) - if(res is None): - self.logger.info("Unable to connect to the Airtime server.") - # sucess - if(res['msg']['code'] == 0): - self.logger.info("%s removed from watch folder list successfully.", path) + list = self.api_client.list_all_watched_dirs() + # case where the dir that is being watched is moved to somewhere + if path in list[u'dirs'].values(): + self.logger.info("Requesting the airtime server to remove '%s'", path) + res = self.api_client.remove_watched_dir(path) + if(res is None): + self.logger.info("Unable to connect to the Airtime server.") + # sucess + if(res['msg']['code'] == 0): + self.logger.info("%s removed from watch folder list successfully.", path) + else: + self.logger.info("Removing the watch folder failed: %s", res['msg']['error']) else: - self.logger.info("Removing the watch folder failed: %s", res['msg']['error']) - else: - self.file_events.append({'mode': self.config.MODE_DELETE_DIR, 'filepath': path}) + # subdir being moved + # in this case, it has to remove watch manualy and also have to manually delete all records + # on cc_files table + wd = self.wm.get_wd(unkown_path) + self.logger.info("Removing watch on: %s wd %s", unkown_path, wd) + self.wm.rm_watch(wd, rec=True) + self.file_events.append({'mode': self.config.MODE_DELETE_DIR, 'filepath': path}) def process_IN_DELETE_SELF(self, event): self.logger.info("event: %s", event) + path = event.path + '/' if event.dir: - path = event.path - wd = self.wm.get_wd(path) - self.logger.info("Removing watch on: %s wd %s", path, wd) - self.wm.rm_watch(wd, rec=True) - if "-unknown-path" in path: - pos = path.find("-unknown-path") - path = path[0:pos] - list = self.api_client.list_all_watched_dirs() - if path in list: + if path in list[u'dirs'].values(): self.logger.info("Requesting the airtime server to remove '%s'", path) res = self.api_client.remove_watched_dir(path) if(res is None): @@ -89,8 +86,6 @@ class AirtimeProcessEvent(ProcessEvent): self.logger.info("%s removed from watch folder list successfully.", path) else: self.logger.info("Removing the watch folder failed: %s", res['msg']['error']) - else: - self.file_events.append({'mode': self.config.MODE_DELETE_DIR, 'filepath': path}) #event.dir: True if the event was raised against a directory. #event.name: filename