filewatcher.py :  » IDE » PIDA » pida-0.6beta3 » pida » services » filewatcher » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » PIDA 
PIDA » pida 0.6beta3 » pida » services » filewatcher » filewatcher.py
# -*- coding: utf-8 -*-
"""
    :copyright: 2005-2008 by The PIDA Project
    :license: GPL 2 or later (see README/COPYING/LICENSE)
"""

import gobject

from os.path import exists,isdir,isfile

# PIDA Imports
from pida.core.service import Service
from pida.core.features import FeaturesConfig
from pida.core.commands import CommandsConfig
from pida.core.events import EventsConfig
from pida.core.actions import ActionsConfig
from pida.core.options import OptionsConfig

# locale
from pida.core.locale import Locale
locale = Locale('filewatcher')
_ = locale.gettext

have_gio, have_gamin, have_pyinotify=False, False, False
try:
    import gio
    have_gio=True
except ImportError:
    try:
        import gamin
        have_gamin = True
    except ImportError:
        have_gamin = False
        try:
            import pyinotify
            from pyinotify import Notifier,WatchManager,ProcessEvent,IN_DELETE,IN_MODIFY,IN_CREATE,IN_MOVED_FROM,IN_MOVED_TO
            have_pyinotify=True
        except:
            have_pyinotify=False
        

class FileWatcherService(Service):
    
    def start(self): raise NotImplementedError
    def stop(self): raise NotImplementedError
    
    
class FilewatcherEvents(EventsConfig):

    def subscribe_all_foreign(self):
        self.subscribe_foreign('filemanager', 'browsed_path_changed',
                               self.svc.on_browsed_path_changed)

if have_gio:
    class GIOFileWatcherOptions(OptionsConfig):

        def create_options(self):
            self.create_option(
                'enable_giofilemon',
                _('Enable GIOFileMonitor'),
                bool,
                False,
                _('Whether GIOFileMonitor wil be enabled'),
                self.on_enabled_changed,
                safe=False
            )

        def on_enabled_changed(self, option):
            if option.value:
                self.svc.start_giofilemon()
            else:
                self.svc.stop_giofilemon()

    # Service class
    class GIOFileWatcher(Service):
        """the pyinotify File watcher service"""

        events_config = FilewatcherEvents
        options_config = GIOFileWatcherOptions
        
            
        def callcmd(self, cmd, name):
                self._callback(cmd, name)
                
        def _callback(self, command, name):
                    self.boss.cmd('filemanager', command, filename=name,
                        dirname=self.dir)
                        
        class GIOFileMonitor(object):
    
            def __init__(self, outer, path=None):
                    self.outer=outer
                    self.monitors = {}
                    self.add_path(path)
            
            def add_path(self, path):
                if path is None: return
                if exists(path):
                    monitor = None
                    f=gio.File(path)
                    if isdir(path):
                        monitor=f.monitor_directory( gio.FILE_MONITOR_NONE)
                    elif isfile(path):
                        monitor=f.monitor_file(gio.FILE_MONITOR_NONE)
                    
                    if monitor is not None:
                        monitor.connect("changed", self.on_changed)
                        self.monitors[path] = monitor

            def remove_path(self, path):
                del self.monitors[path]
                
            def on_changed(self, mon, file, otherfile, event): 
                #print file, otherfile, event

                #['FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED', 'FILE_MONITOR_EVENT_CHANGED', 'FILE_MONITOR_EVENT_CHANGES_DONE_HINT', 'FILE_MONITOR_EVENT_CREATED', 'FILE_MONITOR_EVENT_DELETED', 'FILE_MONITOR_EVENT_PRE_UNMOUNT', 'FILE_MONITOR_EVENT_UNMOUNTED', 'FILE_MONITOR_NONE', 'FILE_MONITOR_WATCH_MOUNTS']
                if event in [gio.FILE_MONITOR_EVENT_DELETED]:
                    self.outer.callcmd('update_removed_file', file.get_path())
                elif event in [gio.FILE_MONITOR_EVENT_CHANGED, gio.FILE_MONITOR_EVENT_CREATED]:
                    self.outer.callcmd('update_file', file.get_path())

            
        def pre_start(self):
            self.dir = None
            self.started = False
            self.giofilemon= None
            self.cache = []
            if have_gio:
                self.giofilemon=self.GIOFileMonitor(self)

        def start(self):
            if self.giofilemon and self.opt('enable_giofilemon'):
                self.start_giofilemon()

        def start_giofilemon(self):
            if have_gio:
                self.started = True
                #gtk.main() #start
                #gobject.timeout_add(1000, self._period_check)
        
        def stop_giofilemon(self):
            self.started=False
            
        def stop(self):
            self.stop_giofilemon()
            self.giofilemon = None

        def stop_pyinotify(self):
            self.started = False

        def on_browsed_path_changed(self, path):
            self.set_directory(path)
        
        def stop_watch(self, path):
            if self.giofilemon is not None:
                self.giofilemon.remove_path(path)
            
        def set_directory(self, dir):
            if self.giofilemon is not None:
                self.giofilemon.add_path(dir)

            # stop watching old directory
            if self.dir is not None and self.dir != dir:
                self.stop_watch(self.dir)

            # setting new directory
            self.dir = dir
            #self.gamin.watch_directory(self.dir, self._callback)
            #self.notifier=Notifier(self.watchmanager, self.PDir())
            


elif have_gamin:

    class GaminFileWatcherOptions(OptionsConfig):

        def create_options(self):
            self.create_option(
                'enable_gamin',
                _('Enable Gamin'),
                bool,
                False,
                _('Whether Gamin wil be enabled'),
                self.on_enabled_changed,
                safe=False
            )

        def on_enabled_changed(self, option):
            if option.value:
                self.svc.start_gamin()
            else:
                self.svc.stop_gamin()


    # Service class


    class GaminFilewatcher(Service):
        """the Gamin File watcher service"""

        events_config = FilewatcherEvents
        options_config = GaminFileWatcherOptions

        def pre_start(self):
            self.dir = None
            self.started = False
            self.gamin = None
            self.cache = []
            if have_gamin:
                self.gamin = gamin.WatchMonitor()
                self.gamin.no_exists()

        def start(self):
            if self.gamin and self.opt('enable_gamin'):
                self.start_gamin()

        def start_gamin(self):
            if have_gamin:
                self.started = True
                gobject.timeout_add(1000, self._period_check)

        def stop(self):
            self.stop_gamin()
            self.gamin = None

        def stop_gamin(self):
            self.started = False

        def on_browsed_path_changed(self, path):
            self.set_directory(path)

        def set_directory(self, dir):
            if not self.gamin:
                self.dir = dir
                return

            # stop watching old directory
            if self.dir is not None and self.dir != dir:
                self.gamin.stop_watch(self.dir)

            # setting new directory
            self.dir = dir
            self.gamin.watch_directory(self.dir, self._callback)

        def _callback(self, name, event):
            if event == gamin.GAMAcknowledge:
                return

            # don't send many time the same event
            if [name, event] in self.cache:
                return
            self.cache.append([name, event])


            if event == gamin.GAMChanged or event == gamin.GAMCreated:
                command = 'update_file'
            elif event == gamin.GAMDeleted or event == gamin.GAMMoved:
                command = 'update_removed_file'
            else:
                command = None
            if command:
                self.boss.cmd('filemanager', command, filename=name,
                    dirname=self.dir)

        def _period_check(self):
            if not self.started:
                return False
            self.cache = []
            self.gamin.handle_events()
            return True

elif have_pyinotify:
    
    class PyINotifyFileWatcherOptions(OptionsConfig):

        def create_options(self):
            self.create_option(
                'enable_pyinotify',
                _('Enable pyinotify'),
                bool,
                False,
                _('Whether pyinotify wil be enabled'),
                self.on_enabled_changed,
                safe=False
            )

        def on_enabled_changed(self, option):
            if option.value:
                self.svc.start_pyinotify()
            else:
                self.svc.stop_pyinotify()

    # Service class
    class PyINotifyFileWatcher(Service):
        """the pyinotify File watcher service"""

        events_config = FilewatcherEvents
        options_config = PyINotifyFileWatcherOptions
        
        
        def _callback(self, cmd, name):
                self.boss.cmd('filemanager', command, filename=name,
                    dirname=self.dir)
        callcmd=_callback
        
        class PDir(ProcessEvent):
            def my_init(self, outer, **kwargs):
                self.outer=outer
                self.mv_cookies={} #{cookie: src}
            
            def process_IN_DELETE(self, event):
                self._callback('update_removed_file', event.pathname)
                
            def process_IN_CREATE(self, event):
                self._callback('update_file', event.pathname)
                
            def process_IN_MODIFY(self, event):
                self._callback('update_file', event.pathname)
                   
            def process_IN_MOVED_FROM(self, event):
                self._callback('update_removed_file', event.pathname)
                
            def process_IN_MOVED_TO(self, event):
                self._callback('update_removed_file', event.pathname)
                

            
        def pre_start(self):
            self.dir = None
            self.started = False
            self.pyinotify = None
            self.cache = []
            if have_pyinotify:
                self.watchmanager=WatchManager()
                self.mask=IN_DELETE|IN_CREATE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY
                #self.gamin = gamin.WatchMonitor()
                #self.gamin.no_exists()

        def start(self):
            if self.pyinotify and self.opt('enable_pyinotify'):
                self.start_pyinotify()

        def start_pyinotify(self):
            if have_pyinotify:
                self.started = True
                self.notifier=Notifier(self.watchmanager, self.PDir())
                #gobject.timeout_add(1000, self._period_check)

        def stop(self):
            self.stop_pyinotify()
            self.pyinotify = None

        def stop_pyinotify(self):
            self.started = False

        def on_browsed_path_changed(self, path):
            self.set_directory(path)
        
        def stop_watch(self, path):
            self.watchmanager.rm_watch(path)
            
        def set_directory(self, dir):
            if not self.pyinotify:
                self.dir = dir
                self.watchmanager.add_watch(self.dir, self.mask) #, rec=True)
                return

            # stop watching old directory
            if self.dir is not None and self.dir != dir:
                self.stop_watch(self.dir)

            # setting new directory
            self.dir = dir
            #self.gamin.watch_directory(self.dir, self._callback)
            #self.notifier=Notifier(self.watchmanager, self.PDir())
            

        #def _period_check(self):
            #if not self.started:
                #return False
            #self.cache = []
            #self.gamin.handle_events()
            #return True


def watcher_factory():
    if have_gio:
        return GIOFileWatcher
    elif have_gamin:
        return GaminFilewatcher
    elif have_pyinotify:
        return PyINotifyFilewatcher
    else:
        raise Exception("[-]GIO/Gamin/pyinotify")
# Required Service attribute for service loading

Service = watcher_factory()


# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.