cc-4105: fixed moving watched directory

This commit is contained in:
Rudi Grinberg 2012-08-07 12:06:14 -04:00
parent 166a724d9d
commit 7db4573d10
5 changed files with 37 additions and 11 deletions
python_apps/media-monitor2/media/monitor

View File

@ -121,8 +121,10 @@ class MoveFile(BaseEvent, HasMetaData):
return [req_dict] return [req_dict]
def map_events(directory, constructor): def map_events(directory, constructor):
for f in mmp.walk_supported(directory.replace("-unknown-path",""), # This hack is actually not necessary:
clean_empties=True): #for f in mmp.walk_supported(directory.replace("-unknown-path",""),
#clean_empties=False)
for f in mmp.walk_supported(directory, clean_empties=False):
try: try:
for e in constructor( FakePyinotify(f) ).pack(): yield e for e in constructor( FakePyinotify(f) ).pack(): yield e
except BadSongFile as e: yield e except BadSongFile as e: yield e
@ -142,7 +144,7 @@ class DeleteDirWatch(BaseEvent):
def pack(self): def pack(self):
req_dict = {} req_dict = {}
req_dict['mode'] = u'delete_dir' req_dict['mode'] = u'delete_dir'
req_dict['MDATA_KEY_FILEPATH'] = unicode( self.path ) req_dict['MDATA_KEY_FILEPATH'] = unicode( self.path + "/" )
return [req_dict] return [req_dict]
class ModifyFile(BaseEvent, HasMetaData): class ModifyFile(BaseEvent, HasMetaData):

View File

@ -38,6 +38,7 @@ class ProblemFileHandler(Handles, Loggable):
self.logger.info("Initialized problem file handler. Problem dir: '%s'" % self.problem_dir) self.logger.info("Initialized problem file handler. Problem dir: '%s'" % self.problem_dir)
def handle(self, sender, event, exception=None): def handle(self, sender, event, exception=None):
# TODO : use the exception parameter for something
self.logger.info("Received problem file: '%s'. Supposed to move it to problem dir", event.path) self.logger.info("Received problem file: '%s'. Supposed to move it to problem dir", event.path)
import ipdb; ipdb.set_trace() import ipdb; ipdb.set_trace()
try: mmp.move_to_dir(dir_path=self.problem_dir, file_path=event.path) try: mmp.move_to_dir(dir_path=self.problem_dir, file_path=event.path)

View File

@ -5,7 +5,7 @@ from pydispatch import dispatcher
import media.monitor.pure as mmp import media.monitor.pure as mmp
from media.monitor.pure import IncludeOnly from media.monitor.pure import IncludeOnly
from media.monitor.events import OrganizeFile, NewFile, MoveFile, DeleteFile, \ from media.monitor.events import OrganizeFile, NewFile, MoveFile, DeleteFile, \
ModifyFile, DeleteDir, EventRegistry, MoveDir,\ DeleteDir, EventRegistry, MoveDir,\
DeleteDirWatch DeleteDirWatch
from media.monitor.log import Loggable, get_logger from media.monitor.log import Loggable, get_logger
@ -118,19 +118,27 @@ class StoreWatchListener(BaseListener, Loggable, pyinotify.ProcessEvent):
evt = self.process_delete(event) evt = self.process_delete(event)
if hasattr(event,'cookie'): EventRegistry.register(evt) if hasattr(event,'cookie'): EventRegistry.register(evt)
def process_IN_DELETE(self,event): self.process_delete(event) def process_IN_DELETE(self,event): self.process_delete(event)
def process_IN_MOVE_SELF(self, event):
if '-unknown-path' in event.pathname:
event.pathname = event.pathname.replace('-unknown-path','')
self.delete_watch_dir(event)
# Capturing modify events is too brittle and error prone # Capturing modify events is too brittle and error prone
# def process_IN_MODIFY(self,event): self.process_modify(event) # def process_IN_MODIFY(self,event): self.process_modify(event)
def delete_watch_dir(self, event):
e = DeleteDirWatch(event)
dispatcher.send(signal='watch_move', sender=self, event=e)
dispatcher.send(signal=self.signal, sender=self, event=e)
# TODO : Remove this code. Later decided we will ignore modify events # TODO : Remove this code. Later decided we will ignore modify events
# since it's too difficult to tell which ones should be handled. Much # since it's too difficult to tell which ones should be handled. Much
# easier to just intercept IN_CLOSE_WRITE and decide what to do on the php # easier to just intercept IN_CLOSE_WRITE and decide what to do on the php
# side # side
@mediate_ignored #@mediate_ignored
@IncludeOnly(mmp.supported_extensions) #@IncludeOnly(mmp.supported_extensions)
def process_modify(self, event): #def process_modify(self, event):
FileMediator.skip_next('IN_MODIFY','IN_CLOSE_WRITE',key='maskname') #FileMediator.skip_next('IN_MODIFY','IN_CLOSE_WRITE',key='maskname')
evt = ModifyFile(event) #evt = ModifyFile(event)
dispatcher.send(signal=self.signal, sender=self, event=evt) #dispatcher.send(signal=self.signal, sender=self, event=evt)
@mediate_ignored @mediate_ignored
@IncludeOnly(mmp.supported_extensions) @IncludeOnly(mmp.supported_extensions)

View File

@ -1,5 +1,7 @@
import pyinotify import pyinotify
from pydispatch import dispatcher
from os.path import normpath
from media.monitor.events import PathChannel from media.monitor.events import PathChannel
from media.monitor.log import Loggable from media.monitor.log import Loggable
from media.monitor.listeners import StoreWatchListener, OrganizeListener from media.monitor.listeners import StoreWatchListener, OrganizeListener
@ -34,16 +36,27 @@ class Manager(Loggable):
'organizer' : None, 'organizer' : None,
'problem_handler' : None, 'problem_handler' : None,
} }
def dummy(sender, event): self.watch_move( event.path, sender=sender )
dispatcher.connect(dummy, signal='watch_move', sender=dispatcher.Any,
weak=False)
# A private mapping path => watch_descriptor # A private mapping path => watch_descriptor
# we use the same dictionary for organize, watch, store wd events. # we use the same dictionary for organize, watch, store wd events.
# this is a little hacky because we are unable to have multiple wd's # this is a little hacky because we are unable to have multiple wd's
# on the same path. # on the same path.
self.__wd_path = {} self.__wd_path = {}
# The following set isn't really necessary anymore. should be # The following set isn't really necessary anymore. Should be
# removed... # removed...
self.watched_directories = set([]) self.watched_directories = set([])
Manager.global_inst = self Manager.global_inst = self
# This is the only event that we are unable to process "normally". I.e.
# through dedicated handler objects. Because we must have access to a
# manager instance. Hence we must slightly break encapsulation.
def watch_move(self, watch_dir, sender=None):
self.logger.info("Watch dir '%s' has been renamed (hence removed)" %
watch_dir)
self.remove_watch_directory(normpath(watch_dir))
def watch_signal(self): def watch_signal(self):
return self.watch_listener.signal return self.watch_listener.signal

View File

@ -107,6 +107,8 @@ class WatchSyncer(ReportHandler,Loggable):
tc.start() tc.start()
super(WatchSyncer, self).__init__(signal=signal) super(WatchSyncer, self).__init__(signal=signal)
# TODO : get rid of this useless property. WatchSyncer is now uncoupled
# from any particular watch directory
@property @property
def target_path(self): return self.path def target_path(self): return self.path