diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 62261db47..8a256185a 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -535,6 +535,15 @@ 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(); + } + return; + } $this->view->id = $file->getId(); } diff --git a/airtime_mvc/application/models/MusicDir.php b/airtime_mvc/application/models/MusicDir.php index cee6182cd..3b26c6da9 100644 --- a/airtime_mvc/application/models/MusicDir.php +++ b/airtime_mvc/application/models/MusicDir.php @@ -281,7 +281,10 @@ 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; + } $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 6c9bf6e16..db73f4278 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..c8670bb64 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,58 @@ 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) + path = event.path + if event.dir: + if "-unknown-path" in path: + unkown_path = 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[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: + # 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: + list = self.api_client.list_all_watched_dirs() + 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']) + #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 +148,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 +200,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):