From 632f2ab470362312ec5134ffdb44c46991784cff Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 3 Aug 2012 15:13:51 -0400 Subject: [PATCH] cc-4105: fixed the gross hack to identify moved files --- .../media-monitor2/media/monitor/events.py | 21 +++++++++++++------ .../media-monitor2/media/monitor/listeners.py | 18 +++++++++------- .../media-monitor2/media/monitor/pure.py | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/python_apps/media-monitor2/media/monitor/events.py b/python_apps/media-monitor2/media/monitor/events.py index ebf5b9026..2781dfde4 100644 --- a/python_apps/media-monitor2/media/monitor/events.py +++ b/python_apps/media-monitor2/media/monitor/events.py @@ -3,6 +3,7 @@ import os import abc from media.monitor.pure import LazyProperty from media.monitor.metadata import Metadata +from media.monitor.log import Loggable class PathChannel(object): """a dumb struct; python has no record types""" @@ -23,7 +24,10 @@ class EventRegistry(object): return evt.cookie in EventRegistry.registry @staticmethod def matching(evt): - return EventRegistry.registry[evt.cookie] + event = EventRegistry.registry[evt.cookie] + # Want to disallow accessing the same event twice + EventRegistry.unregister(event) + return event # It would be good if we could parameterize this class by the attribute @@ -35,23 +39,28 @@ class HasMetaData(object): def metadata(self): return Metadata(self.path) -class BaseEvent(object): +class BaseEvent(Loggable): __metaclass__ = abc.ABCMeta def __init__(self, raw_event): # TODO : clean up this idiotic hack # we should use keyword constructors instead of this behaviour checking # bs to initialize BaseEvent if hasattr(raw_event,"pathname"): - self.__raw_event = raw_event + self._raw_event = raw_event self.path = os.path.normpath(raw_event.pathname) else: self.path = raw_event - self.cookie = getattr( raw_event, 'cookie', None ) def exists(self): return os.path.exists(self.path) + @LazyProperty + def cookie(self): + return getattr( self._raw_event, 'cookie', None ) def __str__(self): return "Event. Path: %s" % self.__raw_event.pathname - def morph_move(self, evt): - self.__raw_event = evt + # nothing to see here, please move along + def morph_into(self, evt): + self.logger.info("Morphing '%s' into '%s'" % (self.__class__.__name__, + evt.__class__.__name__)) + self._raw_event = evt self.path = evt.path self.__class__ = evt.__class__ diff --git a/python_apps/media-monitor2/media/monitor/listeners.py b/python_apps/media-monitor2/media/monitor/listeners.py index b82957258..b0dd39aee 100644 --- a/python_apps/media-monitor2/media/monitor/listeners.py +++ b/python_apps/media-monitor2/media/monitor/listeners.py @@ -73,7 +73,7 @@ def mediate_ignored(fn): if FileMediator.is_ignored(event.pathname): FileMediator.logger.info("Ignoring: '%s' (once)" % event.pathname) FileMediator.unignore(event.pathname) - else: fn(self, event, *args, **kwargs) + else: return fn(self, event, *args, **kwargs) return wrapped class BaseListener(object): @@ -107,14 +107,12 @@ class StoreWatchListener(BaseListener, Loggable, pyinotify.ProcessEvent): def process_IN_CLOSE_WRITE(self, event): self.process_create(event) def process_IN_MOVED_TO(self, event): if EventRegistry.registered(event): - EventRegistry.matching(event).morph_move(MoveFile(event)) - EventRegistry.unregister(event) + EventRegistry.matching(event).morph_into(MoveFile(event)) else: self.process_create(event) def process_IN_MOVED_FROM(self, event): # Is either delete dir or delete file - if event.dir: self.process_delete_dir(event) - else: self.process_delete(event) - if hasattr(event.cookie): EventRegistry.register(event) + evt = self.process_delete_dir(event) if event.dir else self.process_delete(event) + if hasattr(event,'cookie'): EventRegistry.register(evt) def process_IN_DELETE(self,event): self.process_delete(event) # Capturing modify events is too brittle and error prone # def process_IN_MODIFY(self,event): self.process_modify(event) @@ -133,11 +131,15 @@ class StoreWatchListener(BaseListener, Loggable, pyinotify.ProcessEvent): @mediate_ignored @IncludeOnly(mmp.supported_extensions) def process_delete(self, event): - dispatcher.send(signal=self.signal, sender=self, event=DeleteFile(event)) + evt = DeleteFile(event) + dispatcher.send(signal=self.signal, sender=self, event=evt) + return evt @mediate_ignored def process_delete_dir(self, event): - dispatcher.send(signal=self.signal, sender=self, event=DeleteDir(event)) + evt = DeleteDir(event) + dispatcher.send(signal=self.signal, sender=self, event=evt) + return evt def flush_events(self, path): """ diff --git a/python_apps/media-monitor2/media/monitor/pure.py b/python_apps/media-monitor2/media/monitor/pure.py index b5bd89fbd..e987022eb 100644 --- a/python_apps/media-monitor2/media/monitor/pure.py +++ b/python_apps/media-monitor2/media/monitor/pure.py @@ -42,7 +42,7 @@ class IncludeOnly(object): def __call__(self, func): def _wrap(moi, event, *args, **kwargs): ext = extension(event.pathname) - if ext in self.exts: func(moi, event, *args, **kwargs) + if ext in self.exts: return func(moi, event, *args, **kwargs) return _wrap