コード例 #1
0
def test_performance(sync):

    # 10,000 nested deleted events (5,000 folders, 5,000 files)
    file_events = [DirDeletedEvent(n * ipath(1)) for n in range(1, 5001)]
    file_events += [FileDeletedEvent(n * ipath(1) + ".txt") for n in range(1, 5001)]

    # 10,000 nested moved events (5,000 folders, 5,000 files)
    file_events += [DirMovedEvent(n * ipath(2), n * ipath(3)) for n in range(1, 5001)]
    file_events += [
        FileMovedEvent(n * ipath(2) + ".txt", n * ipath(3) + ".txt")
        for n in range(1, 5001)
    ]

    # 4,995 unrelated created events
    file_events += [FileCreatedEvent(ipath(n)) for n in range(5, 5001)]

    res = [
        DirDeletedEvent(ipath(1)),
        DirMovedEvent(ipath(2), ipath(3)),
        FileDeletedEvent(ipath(1) + ".txt"),
        FileMovedEvent(ipath(2) + ".txt", ipath(3) + ".txt"),
    ]
    res += [FileCreatedEvent(ipath(n)) for n in range(5, 5001)]

    cleaned_events = sync._clean_local_events(file_events)
    assert set(cleaned_events) == set(res)

    n_loops = 4
    duration = timeit.timeit(
        lambda: sync._clean_local_events(file_events), number=n_loops
    )

    assert duration < 10 * n_loops
コード例 #2
0
def test_nested_events(sync):

    file_events = [
        # convert to a single DirDeleted
        DirDeletedEvent(ipath(1)),
        FileDeletedEvent(ipath(1) + "/file1.txt"),
        FileDeletedEvent(ipath(1) + "/file2.txt"),
        DirDeletedEvent(ipath(1) + "/sub"),
        FileDeletedEvent(ipath(1) + "/sub/file3.txt"),
        # convert to a single DirMoved
        DirMovedEvent(ipath(2), ipath(3)),
        FileMovedEvent(ipath(2) + "/file1.txt",
                       ipath(3) + "/file1.txt"),
        FileMovedEvent(ipath(2) + "/file2.txt",
                       ipath(3) + "/file2.txt"),
        DirMovedEvent(ipath(2) + "/sub",
                      ipath(3) + "/sub"),
        FileMovedEvent(
            ipath(2) + "/sub/file3.txt",
            ipath(3) + "/sub/file3.txt"),
    ]

    res = [
        DirDeletedEvent(ipath(1)),
        DirMovedEvent(ipath(2), ipath(3)),
    ]

    cleaned_events = sync._clean_local_events(file_events)
    assert set(cleaned_events) == set(res)
コード例 #3
0
    def test_generate_sub_moved_events_for(self):
        mock_walker_path = [
            ('/path', ['ad', 'bd'], ['af', 'bf', 'cf']),
            ('/path/ad', [], ['af', 'bf', 'cf']),
            ('/path/bd', [], ['af', 'bf', 'cf']),
        ]
        dest_path = '/path'
        src_path = '/foobar'
        expected_events = set([
            DirMovedEvent('/foobar/ad', '/path/ad'),
            DirMovedEvent('/foobar/bd', '/path/bd'),
            FileMovedEvent('/foobar/af', '/path/af'),
            FileMovedEvent('/foobar/bf', '/path/bf'),
            FileMovedEvent('/foobar/cf', '/path/cf'),
            FileMovedEvent('/foobar/ad/af', '/path/ad/af'),
            FileMovedEvent('/foobar/ad/bf', '/path/ad/bf'),
            FileMovedEvent('/foobar/ad/cf', '/path/ad/cf'),
            FileMovedEvent('/foobar/bd/af', '/path/bd/af'),
            FileMovedEvent('/foobar/bd/bf', '/path/bd/bf'),
            FileMovedEvent('/foobar/bd/cf', '/path/bd/cf'),
        ])

        def _mock_os_walker(path):
            for root, directories, filenames in mock_walker_path:
                yield (root, directories, filenames)

        calculated_events = set(
            _generate_sub_moved_events_for(src_path,
                                           dest_path,
                                           _walker=_mock_os_walker))
        assert_equal(expected_events, calculated_events)
コード例 #4
0
ファイル: polling.py プロジェクト: d-ash/BigBenBox
    def queue_events(self, timeout):
        with self._lock:
            # We don't want to hit the disk continuously.
            # timeout behaves like an interval for polling emitters.
            time.sleep(timeout)

            # Get event diff between fresh snapshot and previous snapshot.
            # Update snapshot.
            new_snapshot = DirectorySnapshot(self.watch.path, self.watch.is_recursive)
            events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
            self._snapshot = new_snapshot

            # Files.
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))
            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))
            for src_path in events.files_created:
                self.queue_event(FileCreatedEvent(src_path))
            for src_path, dest_path in events.files_moved:
                self.queue_event(FileMovedEvent(src_path, dest_path))

            # Directories.
            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))
            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))
            for src_path in events.dirs_created:
                self.queue_event(DirCreatedEvent(src_path))
            for src_path, dest_path in events.dirs_moved:
                self.queue_event(DirMovedEvent(src_path, dest_path))
コード例 #5
0
def pop_collapse_deque(event_deque):
    # collapse multiple consecutive renaming
    # if nothing to collapse, pop the left most
    pop_i = 0 # pop until (exclusive)
    while pop_i + 1 < len(event_deque):
        older = event_deque[pop_i]
        newer = event_deque[pop_i + 1]
        if (older.event_type == EVENT_TYPE_MOVED
            and newer.event_type == EVENT_TYPE_MOVED
            and older.dest_path == newer.src_path):
            pop_i += 1
        else:
            break

    if pop_i > 0:
        start = event_deque[0]
        end = event_deque[pop_i]
        collapsed = FileMovedEvent(start.src_path, end.dest_path)
        for i in range(pop_i + 1):
            event_deque.popleft()
        logging.info('Collapsing {} renaming events into {}'
                     .format(pop_i + 1, collapsed))
        return collapsed
    else:
        return event_deque.popleft()
コード例 #6
0
ファイル: polling.py プロジェクト: connoryang/1v1dec
    def queue_events(self, timeout):
        if self.stopped_event.wait(timeout):
            return
        with self._lock:
            if not self.should_keep_running():
                return
            new_snapshot = self._take_snapshot()
            events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
            self._snapshot = new_snapshot
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))

            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))

            for src_path in events.files_created:
                self.queue_event(FileCreatedEvent(src_path))

            for src_path, dest_path in events.files_moved:
                self.queue_event(FileMovedEvent(src_path, dest_path))

            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))

            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))

            for src_path in events.dirs_created:
                self.queue_event(DirCreatedEvent(src_path))

            for src_path, dest_path in events.dirs_moved:
                self.queue_event(DirMovedEvent(src_path, dest_path))
コード例 #7
0
ファイル: polling.py プロジェクト: vjs3/Fast-file-transfer
    def queue_events(self, timeout):

        if self.stopped_event.wait(timeout):
            return

        with self._lock:
            if not self.should_keep_running():
                return

            # Get event diff between fresh snapshot and previous snapshot.
            # Update snapshot.
            new_snapshot = self._take_snapshot()
            events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
            self._snapshot = new_snapshot

            # Files.
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))
            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))
            for src_path in events.files_created:
                self.queue_event(FileCreatedEvent(src_path))
            for src_path, dest_path in events.files_moved:
                self.queue_event(FileMovedEvent(src_path, dest_path))

            # Directories.
            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))
            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))
            for src_path in events.dirs_created:
                self.queue_event(DirCreatedEvent(src_path))
            for src_path, dest_path in events.dirs_moved:
                self.queue_event(DirMovedEvent(src_path, dest_path))
コード例 #8
0
    def queue_events(self, timeout):
        time.sleep(timeout)
        with self._lock:
            if not self._snapshot:
                return
            new_snapshot = DirectorySnapshot(self.watch.path,
                                             self.watch.is_recursive)
            events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
            self._snapshot = new_snapshot
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))

            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))

            for src_path in events.files_created:
                self.queue_event(FileCreatedEvent(src_path))

            for src_path, dest_path in events.files_moved:
                self.queue_event(FileMovedEvent(src_path, dest_path))

            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))

            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))

            for src_path in events.dirs_created:
                self.queue_event(DirCreatedEvent(src_path))

            for src_path, dest_path in events.dirs_moved:
                self.queue_event(DirMovedEvent(src_path, dest_path))
コード例 #9
0
ファイル: polling.py プロジェクト: skcript/watchdog
    def queue_events(self, timeout):
        # We don't want to hit the disk continuously.
        # timeout behaves like an interval for polling emitters.
        if self.stopped_event.wait(timeout):
            return

        with self._lock:
            if not self.should_keep_running():
                return

            # Get event diff between fresh snapshot and previous snapshot.
            # Update snapshot.
            new_snapshot = self._take_snapshot()
            events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
            self._snapshot = new_snapshot
            
            # Directories.
            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))
            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))
            for src_path in events.dirs_created.sort(key=lambda item: (item.count("/"), item)):
                self.queue_event(DirCreatedEvent(src_path))
            for src_path, dest_path in events.dirs_moved.sort(key=lambda item: (item.count("/"), item)):
                self.queue_event(DirMovedEvent(src_path, dest_path))

            # Files.
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))
            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))
            for src_path in events.files_created.sort(key=lambda item: (item.count("/"), item)):
                self.queue_event(FileCreatedEvent(src_path))
            for src_path, dest_path in events.files_moved.sort(key=lambda item: (item.count("/"), item)):
                self.queue_event(FileMovedEvent(src_path, dest_path))
コード例 #10
0
    def test___init__(self):
        SLEEP_TIME = 0.4
        self.emitter.start()
        sleep(SLEEP_TIME)
        mkdir(p('project'))
        sleep(SLEEP_TIME)
        mkdir(p('project', 'blah'))
        sleep(SLEEP_TIME)
        touch(p('afile'))
        sleep(SLEEP_TIME)
        touch(p('fromfile'))
        sleep(SLEEP_TIME)
        mv(p('fromfile'), p('project', 'tofile'))
        sleep(SLEEP_TIME)
        touch(p('afile'))
        sleep(SLEEP_TIME)
        mv(p('project', 'blah'), p('project', 'boo'))
        sleep(SLEEP_TIME)
        rm(p('project'), recursive=True)
        sleep(SLEEP_TIME)
        rm(p('afile'))
        sleep(SLEEP_TIME)
        self.emitter.stop()

        # What we need here for the tests to pass is a collection type
        # that is:
        #   * unordered
        #   * non-unique
        # A multiset! Python's collections.Counter class seems appropriate.
        expected = set([
            DirModifiedEvent(p()),
            DirCreatedEvent(p('project')),
            DirModifiedEvent(p('project')),
            DirCreatedEvent(p('project', 'blah')),
            FileCreatedEvent(p('afile')),
            DirModifiedEvent(p()),
            FileCreatedEvent(p('fromfile')),
            DirModifiedEvent(p()),
            DirModifiedEvent(p()),
            FileMovedEvent(p('fromfile'), p('project', 'tofile')),
            FileModifiedEvent(p('afile')),
            DirModifiedEvent(p('project')),
            DirMovedEvent(p('project', 'blah'), p('project', 'boo')),
            DirModifiedEvent(p()),
            FileDeletedEvent(p('project', 'boo')),
            DirDeletedEvent(p('project', 'boo')),
            DirDeletedEvent(p('project')),
            DirModifiedEvent(p()),
            FileDeletedEvent(p('afile')),
        ])
        got = set()

        while True:
            try:
                event, _ = self.event_queue.get_nowait()
                got.add(event)
            except queue.Empty:
                break

        assert_equal(expected, got)
コード例 #11
0
def test_gedit_save(sync):

    file_events = [
        FileCreatedEvent(".gedit-save-UR4EC0"),  # save new version to tmp file
        FileModifiedEvent(".gedit-save-UR4EC0"),  # modify tmp file
        FileMovedEvent(ipath(1), ipath(1) + "~"),  # move old version to backup
        FileMovedEvent(".gedit-save-UR4EC0", ipath(1)),  # replace old version with tmp
    ]

    res = [
        FileModifiedEvent(ipath(1)),  # modified file
        FileCreatedEvent(ipath(1) + "~"),  # backup
    ]

    cleaned_events = sync._clean_local_events(file_events)
    assert set(cleaned_events) == set(res)
コード例 #12
0
    def _queue_renamed(self, src_path, is_directory, ref_snapshot,
                       new_snapshot):
        try:
            ref_stat_info = ref_snapshot.stat_info(src_path)
        except KeyError:
            if is_directory:
                self.queue_event(DirCreatedEvent(src_path))
                self.queue_event(DirDeletedEvent(src_path))
            else:
                self.queue_event(FileCreatedEvent(src_path))
                self.queue_event(FileDeletedEvent(src_path))
            return

        try:
            dest_path = absolute_path(
                new_snapshot.path_for_inode(ref_stat_info.st_ino))
            if is_directory:
                event = DirMovedEvent(src_path, dest_path)
                if self.watch.is_recursive:
                    for sub_event in event.sub_moved_events():
                        self.queue_event(sub_event)

                self.queue_event(event)
            else:
                self.queue_event(FileMovedEvent(src_path, dest_path))
        except KeyError:
            if is_directory:
                self.queue_event(DirDeletedEvent(src_path))
            else:
                self.queue_event(FileDeletedEvent(src_path))
コード例 #13
0
ファイル: snippet.py プロジェクト: someburner/GistsHub
    def start(self, *args, **kwargs):
        previous_snapshots = dict()
        if os.path.exists(self._filename):
            with open(self._filename) as f:
                previous_snapshots = pickle.load(f)

        for watcher, handlers in self._handlers.iteritems():
            path = watcher.path
            curr_snap = DirectorySnapshot(path)
            pre_snap = previous_snapshots.get(path, _EmptySnapshot())
            diff = DirectorySnapshotDiff(pre_snap, curr_snap)
            for handler in handlers:
                # Dispatch files modifications
                for new_path in diff.files_created:
                    handler.dispatch(FileCreatedEvent(new_path))
                for del_path in diff.files_deleted:
                    handler.dispatch(FileDeletedEvent(del_path))
                for mod_path in diff.files_modified:
                    handler.dispatch(FileModifiedEvent(mod_path))
                for mov_path in diff.files_moved:
                    handler.dispatch(FileMovedEvent(mov_path))

                # Dispatch directories modifications
                for new_dir in diff.dirs_created:
                    handler.dispatch(DirCreatedEvent(new_dir))
                for del_dir in diff.dirs_deleted:
                    handler.dispatch(DirDeletedEvent(del_dir))
                for mod_dir in diff.dirs_modified:
                    handler.dispatch(DirModifiedEvent(mod_dir))
                for mov_dir in diff.dirs_moved:
                    handler.dispatch(DirMovedEvent(mov_dir))

        Observer.start(self, *args, **kwargs)
コード例 #14
0
def test_recursive_off():
    mkdir(p('dir1'))
    start_watching(recursive=False)
    touch(p('dir1', 'a'))

    with pytest.raises(Empty):
        event_queue.get(timeout=5)

    mkfile(p('b'))
    expect_event(FileCreatedEvent(p('b')))
    if not platform.is_windows():
        expect_event(DirModifiedEvent(p()))

        if platform.is_linux():
            expect_event(FileClosedEvent(p('b')))

    # currently limiting these additional events to macOS only, see https://github.com/gorakhargosh/watchdog/pull/779
    if platform.is_darwin():
        mkdir(p('dir1', 'dir2'))
        with pytest.raises(Empty):
            event_queue.get(timeout=5)
        mkfile(p('dir1', 'dir2', 'somefile'))
        with pytest.raises(Empty):
            event_queue.get(timeout=5)

        mkdir(p('dir3'))
        expect_event(DirModifiedEvent(p()))  # the contents of the parent directory changed

        mv(p('dir1', 'dir2', 'somefile'), p('somefile'))
        expect_event(FileMovedEvent(p('dir1', 'dir2', 'somefile'), p('somefile')))
        expect_event(DirModifiedEvent(p()))

        mv(p('dir1', 'dir2'), p('dir2'))
        expect_event(DirMovedEvent(p('dir1', 'dir2'), p('dir2')))
        expect_event(DirModifiedEvent(p()))
コード例 #15
0
    def queue_events(self, timeout):
        with self._lock:
            dir_changes, nbytes = read_directory_changes(self._directory_handle, self._buffer, self.watch.is_recursive)
            last_renamed_src_path = ''
            for action, src_path in get_FILE_NOTIFY_INFORMATION(dir_changes, nbytes):
                src_path = absolute_path(os.path.join(self.watch.path, src_path))
                if action == FILE_ACTION_RENAMED_OLD_NAME:
                    last_renamed_src_path = src_path
                elif action == FILE_ACTION_RENAMED_NEW_NAME:
                    dest_path = src_path
                    src_path = last_renamed_src_path
                    if os.path.isdir(dest_path):
                        event = DirMovedEvent(src_path, dest_path)
                        if self.watch.is_recursive:
                            time.sleep(WATCHDOG_TRAVERSE_MOVED_DIR_DELAY)
                            for sub_moved_event in event.sub_moved_events():
                                self.queue_event(sub_moved_event)

                        self.queue_event(event)
                    else:
                        self.queue_event(FileMovedEvent(src_path, dest_path))
                elif os.path.isdir(src_path):
                    event = DIR_ACTION_EVENT_MAP[action](src_path)
                    if isinstance(event, DirCreatedEvent):
                        time.sleep(WATCHDOG_TRAVERSE_MOVED_DIR_DELAY)
                        sub_events = _generate_sub_created_events_for(src_path)
                        for sub_created_event in sub_events:
                            self.queue_event(sub_created_event)

                    self.queue_event(event)
                else:
                    self.queue_event(FILE_ACTION_EVENT_MAP[action](src_path))
コード例 #16
0
ファイル: fsevents.py プロジェクト: zjw0358/watchdog
    def queue_events(self, timeout):
        with self._lock:
            if not self.watch.is_recursive\
                and self.watch.path not in self.pathnames:
                return
            new_snapshot = DirectorySnapshot(self.watch.path,
                                             self.watch.is_recursive)
            events = new_snapshot - self.snapshot
            self.snapshot = new_snapshot

            # Files.
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))
            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))
            for src_path in events.files_created:
                self.queue_event(FileCreatedEvent(src_path))
            for src_path, dest_path in events.files_moved:
                self.queue_event(FileMovedEvent(src_path, dest_path))

            # Directories.
            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))
            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))
            for src_path in events.dirs_created:
                self.queue_event(DirCreatedEvent(src_path))
            for src_path, dest_path in events.dirs_moved:
                self.queue_event(DirMovedEvent(src_path, dest_path))
コード例 #17
0
def test_file_lifecyle():
    start_watching()

    mkfile(p('a'))
    touch(p('a'))
    mv(p('a'), p('b'))
    rm(p('b'))

    expect_event(FileCreatedEvent(p('a')))

    if not platform.is_windows():
        expect_event(DirModifiedEvent(p()))

    if platform.is_linux():
        expect_event(FileClosedEvent(p('a')))
        expect_event(DirModifiedEvent(p()))

    expect_event(FileModifiedEvent(p('a')))

    if platform.is_linux():
        expect_event(FileClosedEvent(p('a')))
        expect_event(DirModifiedEvent(p()))

    expect_event(FileMovedEvent(p('a'), p('b')))

    if not platform.is_windows():
        expect_event(DirModifiedEvent(p()))
        expect_event(DirModifiedEvent(p()))

    expect_event(FileDeletedEvent(p('b')))

    if not platform.is_windows():
        expect_event(DirModifiedEvent(p()))
コード例 #18
0
def test_file_moved_event():
    event = FileMovedEvent(path_1, path_2)
    assert path_1 == event.src_path
    assert path_2 == event.dest_path
    assert EVENT_TYPE_MOVED == event.event_type
    assert not event.is_directory
    assert not event.is_synthetic
コード例 #19
0
def test_case_change():
    mkdir(p('dir1'))
    mkdir(p('dir2'))
    mkfile(p('dir1', 'file'))
    start_watching()

    mv(p('dir1', 'file'), p('dir2', 'FILE'))

    if not platform.is_windows():
        expect_event(FileMovedEvent(p('dir1', 'file'), p('dir2', 'FILE')))
    else:
        event = event_queue.get(timeout=5)[0]
        assert event.src_path == p('dir1', 'file')
        assert isinstance(event, FileDeletedEvent)
        event = event_queue.get(timeout=5)[0]
        assert event.src_path == p('dir2', 'FILE')
        assert isinstance(event, FileCreatedEvent)

    event = event_queue.get(timeout=5)[0]
    assert event.src_path in [p('dir1'), p('dir2')]
    assert isinstance(event, DirModifiedEvent)

    if not platform.is_windows():
        event = event_queue.get(timeout=5)[0]
        assert event.src_path in [p('dir1'), p('dir2')]
        assert isinstance(event, DirModifiedEvent)
コード例 #20
0
def test_move_nested_subdirectories():
    mkdir(p('dir1/dir2/dir3'), parents=True)
    mkfile(p('dir1/dir2/dir3', 'a'))
    start_watching()
    mv(p('dir1/dir2'), p('dir2'))

    expect_event(DirMovedEvent(p('dir1', 'dir2'), p('dir2')))
    expect_event(DirModifiedEvent(p('dir1')))
    expect_event(DirModifiedEvent(p()))

    expect_event(DirMovedEvent(p('dir1', 'dir2', 'dir3'), p('dir2', 'dir3')))
    expect_event(FileMovedEvent(p('dir1', 'dir2', 'dir3', 'a'), p('dir2', 'dir3', 'a')))

    if platform.is_bsd():
        event = event_queue.get(timeout=5)[0]
        assert p(event.src_path) == p()
        assert isinstance(event, DirModifiedEvent)

        event = event_queue.get(timeout=5)[0]
        assert p(event.src_path) == p('dir1')
        assert isinstance(event, DirModifiedEvent)

    touch(p('dir2/dir3', 'a'))

    event = event_queue.get(timeout=5)[0]
    assert event.src_path == p('dir2/dir3', 'a')
    assert isinstance(event, FileModifiedEvent)
コード例 #21
0
ファイル: local_watcher.py プロジェクト: tinymins/pydio-sync
    def check_from_snapshot(self, sub_folder=None, state_callback=(lambda status: None), use_transaction=True):
        logging.info('Scanning for changes since last application launch')
        if (not sub_folder and os.path.exists(self.basepath)) or (sub_folder and os.path.exists(self.basepath + sub_folder)):
            previous_snapshot = SqlSnapshot(self.basepath, self.job_data_path, sub_folder)
            if sub_folder:
                local_path = self.basepath + os.path.normpath(sub_folder)
            else:
                local_path = self.basepath
            state_callback(status=_('Walking through your local folder, please wait...'))

            def listdir(dir_path):
                try:
                    return os.listdir(dir_path)
                except OSError as o:
                    logging.error(o)
                    return []

            snapshot = DirectorySnapshot(local_path, recursive=True, listdir=listdir)
            diff = SnapshotDiffStart(previous_snapshot, snapshot)
            state_callback(status=_('Detected %i local changes...') % (len(diff.dirs_created) + len(diff.files_created)
                                                                       + len(diff.dirs_moved) + len(diff.dirs_deleted)
                                                                       + len(diff.files_moved) +
                                                                       len(diff.files_modified) +
                                                                       len(diff.files_deleted)))

            if use_transaction:
                self.event_handler.begin_transaction()

            for path in diff.dirs_created:
                if self.interrupt:
                    return
                self.event_handler.on_created(DirCreatedEvent(path))
            for path in diff.files_created:
                if self.interrupt:
                    return
                self.event_handler.on_created(FileCreatedEvent(path))

            for path in diff.dirs_moved:
                if self.interrupt:
                    return
                self.event_handler.on_moved(DirMovedEvent(path[0], path[1]))
            for path in diff.files_moved:
                if self.interrupt:
                    return
                self.event_handler.on_moved(FileMovedEvent(path[0], path[1]))
            for path in diff.files_modified:
                if self.interrupt:
                    return
                self.event_handler.on_modified(FileModifiedEvent(path))
            for path in diff.files_deleted:
                if self.interrupt:
                    return
                self.event_handler.on_deleted(FileDeletedEvent(path))
            for path in diff.dirs_deleted:
                if self.interrupt:
                    return
                self.event_handler.on_deleted(DirDeletedEvent(path))

            if use_transaction:
                self.event_handler.end_transaction()
コード例 #22
0
    def test_dispatch(self):
        # Utilities.
        dir_del_event = DirDeletedEvent('/path/blah.py')
        file_del_event = FileDeletedEvent('/path/blah.txt')
        dir_cre_event = DirCreatedEvent('/path/blah.py')
        file_cre_event = FileCreatedEvent('/path/blah.txt')
        dir_mod_event = DirModifiedEvent('/path/blah.py')
        file_mod_event = FileModifiedEvent('/path/blah.txt')
        dir_mov_event = DirMovedEvent('/path/blah.py', '/path/blah')
        file_mov_event = FileMovedEvent('/path/blah.txt', '/path/blah')

        all_events = [
            dir_mod_event,
            dir_del_event,
            dir_cre_event,
            dir_mov_event,
            file_mod_event,
            file_del_event,
            file_cre_event,
            file_mov_event,
        ]

        handler = _TestableEventHandler()
        for event in all_events:
            handler.dispatch(event)
コード例 #23
0
ファイル: test_handlers.py プロジェクト: delijati/specchio
 def test_on_moved_dst_ignore(self, _rm, _os):
     _rm.return_value = True
     _os.path.abspath.side_effect = ["/a/1.py", "/a/test.py"]
     _os.path.join.side_effect = ["/b/a/1.py", "/b/a/test.py"]
     _event = FileMovedEvent(src_path="1.py", dest_path="/a/test.py")
     self.handler.on_moved(_event)
     _rm.assert_called_once_with(dst_ssh=self.handler.dst_ssh,
                                 dst_path="/b/a/1.py")
コード例 #24
0
ファイル: kqueue.py プロジェクト: ostapenkov10/sphinx-test
    def _gen_renamed_events(self,
                            src_path,
                            is_directory,
                            ref_snapshot,
                            new_snapshot):
        """
        Compares information from two directory snapshots (one taken before
        the rename operation and another taken right after) to determine the
        destination path of the file system object renamed, and yields
        the appropriate events to be queued.
        """
        try:
            f_inode = ref_snapshot.inode(src_path)
        except KeyError:
            # Probably caught a temporary file/directory that was renamed
            # and deleted. Fires a sequence of created and deleted events
            # for the path.
            if is_directory:
                yield DirCreatedEvent(src_path)
                yield DirDeletedEvent(src_path)
            else:
                yield FileCreatedEvent(src_path)
                yield FileDeletedEvent(src_path)
                # We don't process any further and bail out assuming
            # the event represents deletion/creation instead of movement.
            return

        dest_path = new_snapshot.path(f_inode)
        if dest_path is not None:
            dest_path = absolute_path(dest_path)
            if is_directory:
                event = DirMovedEvent(src_path, dest_path)
                yield event
            else:
                yield FileMovedEvent(src_path, dest_path)
            yield self._parent_dir_modified(src_path)
            yield self._parent_dir_modified(dest_path)
            if is_directory:
                # TODO: Do we need to fire moved events for the items
                # inside the directory tree? Does kqueue does this
                # all by itself? Check this and then enable this code
                # only if it doesn't already.
                # A: It doesn't. So I've enabled this block.
                if self.watch.is_recursive:
                    for sub_event in generate_sub_moved_events(src_path, dest_path):
                        yield sub_event
        else:
            # If the new snapshot does not have an inode for the
            # old path, we haven't found the new name. Therefore,
            # we mark it as deleted and remove unregister the path.
            if is_directory:
                yield DirDeletedEvent(src_path)
            else:
                yield FileDeletedEvent(src_path)
            yield self._parent_dir_modified(src_path)
コード例 #25
0
        def queue_events(self, timeout):
            with self._lock:
                dir_changes, nbytes = read_directory_changes(
                    self._directory_handle, self._buffer,
                    self.watch.is_recursive)
                last_renamed_src_path = ""
                for action, src_path in get_FILE_NOTIFY_INFORMATION(
                        dir_changes, nbytes):
                    src_path = absolute_path(
                        os.path.join(self.watch.path, src_path))

                    if action == FILE_ACTION_RENAMED_OLD_NAME:
                        last_renamed_src_path = src_path
                    elif action == FILE_ACTION_RENAMED_NEW_NAME:
                        dest_path = src_path
                        src_path = last_renamed_src_path

                        if os.path.isdir(dest_path):
                            event = DirMovedEvent(src_path, dest_path)
                            if self.watch.is_recursive:
                                # HACK: We introduce a forced delay before
                                # traversing the moved directory. This will read
                                # only file movement that finishes within this
                                # delay time.
                                time.sleep(WATCHDOG_TRAVERSE_MOVED_DIR_DELAY)
                                # The following block of code may not
                                # obtain moved events for the entire tree if
                                # the I/O is not completed within the above
                                # delay time. So, it's not guaranteed to work.
                                # TODO: Come up with a better solution, possibly
                                # a way to wait for I/O to complete before
                                # queuing events.
                                for sub_moved_event in event.sub_moved_events(
                                ):
                                    self.queue_event(sub_moved_event)
                            self.queue_event(event)
                        else:
                            self.queue_event(
                                FileMovedEvent(src_path, dest_path))
                    else:
                        if os.path.isdir(src_path):
                            event = DIR_ACTION_EVENT_MAP[action](src_path)
                            if isinstance(event, DirCreatedEvent):
                                # If a directory is moved from outside the watched folder to inside it
                                # we only get a created directory event out of it, not any events for its children
                                # so use the same hack as for file moves to get the child events
                                time.sleep(WATCHDOG_TRAVERSE_MOVED_DIR_DELAY)
                                sub_events = _generate_sub_created_events_for(
                                    src_path)
                                for sub_created_event in sub_events:
                                    self.queue_event(sub_created_event)
                            self.queue_event(event)
                        else:
                            self.queue_event(
                                FILE_ACTION_EVENT_MAP[action](src_path))
コード例 #26
0
ファイル: polling.py プロジェクト: QuantumEnergyE/watchdog
    def queue_events(self, timeout):
        # We don't want to hit the disk continuously.
        # timeout behaves like an interval for polling emitters.
        if self.stopped_event.wait(timeout):
            return

        with self._lock:
            if not self.should_keep_running():
                return

            # Get event diff between fresh snapshot and previous snapshot.
            # Update snapshot.
            try:
                new_snapshot = self._take_snapshot()
            except OSError as e:
                if e.errno in DEFAULT_RESUMABLE_ERRNO:
                    return
                elif e.errno == errno.ENOENT:  # The monitor directory has been removed.
                    if not SUPPORT_ENOENT_RECOVERY:
                        self.queue_event(DirDeletedEvent(self.watch.path))
                        self.stop()
                    return
                else:
                    raise
            if self._snapshot.mount != new_snapshot.mount:
                # The mount state of monitor directory has changed, such as a local directory is
                # mounted or a NAS directory is unmounted.
                if not SUPPORT_UNMOUNT_RECOVERY:
                    self.queue_event(DirDeletedEvent(self.watch.path))
                    self.stop()
                return

            events = DirectorySnapshotDiff(self._snapshot, new_snapshot)
            self._snapshot = new_snapshot

            # Files.
            for src_path in events.files_deleted:
                self.queue_event(FileDeletedEvent(src_path))
            for src_path in events.files_modified:
                self.queue_event(FileModifiedEvent(src_path))
            for src_path in events.files_created:
                self.queue_event(FileCreatedEvent(src_path))
            for src_path, dest_path in events.files_moved:
                self.queue_event(FileMovedEvent(src_path, dest_path))

            # Directories.
            for src_path in events.dirs_deleted:
                self.queue_event(DirDeletedEvent(src_path))
            for src_path in events.dirs_modified:
                self.queue_event(DirModifiedEvent(src_path))
            for src_path in events.dirs_created:
                self.queue_event(DirCreatedEvent(src_path))
            for src_path, dest_path in events.dirs_moved:
                self.queue_event(DirMovedEvent(src_path, dest_path))
コード例 #27
0
def test_single_file_events(sync):

    # only a single event for every path -> no consolidation

    file_events = [
        FileModifiedEvent(ipath(1)),
        FileCreatedEvent(ipath(2)),
        FileDeletedEvent(ipath(3)),
        FileMovedEvent(ipath(4), ipath(5)),
    ]

    res = [
        FileModifiedEvent(ipath(1)),
        FileCreatedEvent(ipath(2)),
        FileDeletedEvent(ipath(3)),
        FileMovedEvent(ipath(4), ipath(5)),
    ]

    cleaned_events = sync._clean_local_events(file_events)
    assert set(cleaned_events) == set(res)
コード例 #28
0
    def queue_events(self, timeout):
        winapi_events = self._read_events()
        with self._lock:
            last_renamed_src_path = ""
            for winapi_event in winapi_events:
                src_path = os.path.join(self.watch.path, winapi_event.src_path)

                if winapi_event.is_renamed_old:
                    last_renamed_src_path = src_path
                elif winapi_event.is_renamed_new:
                    dest_path = src_path
                    src_path = last_renamed_src_path
                    if os.path.isdir(dest_path):
                        event = DirMovedEvent(src_path, dest_path)
                        if self.watch.is_recursive:
                            # HACK: We introduce a forced delay before
                            # traversing the moved directory. This will read
                            # only file movement that finishes within this
                            # delay time.
                            time.sleep(WATCHDOG_TRAVERSE_MOVED_DIR_DELAY)
                            # The following block of code may not
                            # obtain moved events for the entire tree if
                            # the I/O is not completed within the above
                            # delay time. So, it's not guaranteed to work.
                            # TODO: Come up with a better solution, possibly
                            # a way to wait for I/O to complete before
                            # queuing events.
                            for sub_moved_event in generate_sub_moved_events(
                                    src_path, dest_path):
                                self.queue_event(sub_moved_event)
                        self.queue_event(event)
                    else:
                        self.queue_event(FileMovedEvent(src_path, dest_path))
                elif winapi_event.is_modified:
                    cls = DirModifiedEvent if os.path.isdir(
                        src_path) else FileModifiedEvent
                    self.queue_event(cls(src_path))
                elif winapi_event.is_added:
                    isdir = os.path.isdir(src_path)
                    cls = DirCreatedEvent if isdir else FileCreatedEvent
                    self.queue_event(cls(src_path))
                    if isdir and self.watch.is_recursive:
                        # If a directory is moved from outside the watched folder to inside it
                        # we only get a created directory event out of it, not any events for its children
                        # so use the same hack as for file moves to get the child events
                        time.sleep(WATCHDOG_TRAVERSE_MOVED_DIR_DELAY)
                        sub_events = generate_sub_created_events(src_path)
                        for sub_created_event in sub_events:
                            self.queue_event(sub_created_event)
                elif winapi_event.is_removed:
                    self.queue_event(FileDeletedEvent(src_path))
                elif winapi_event.is_removed_self:
                    self.queue_event(DirDeletedEvent(self.watch.path))
                    self.stop()
コード例 #29
0
ファイル: test_handlers.py プロジェクト: delijati/specchio
 def test_on_moved_src_ignore(self, _rsync, _create_folder, _os):
     _create_folder.return_value = True
     _rsync.return_value = True
     _os.path.abspath.side_effect = ["/a/test.py", "/a/1.py"]
     _os.path.join.side_effect = ["/b/a/test.py", "/b/a/1.py"]
     _event = FileMovedEvent(src_path="test.py", dest_path="/a/1.py")
     self.handler.on_moved(_event)
     _create_folder.assert_called_once_with(dst_ssh=self.handler.dst_ssh,
                                            dst_path="/b/a/")
     _rsync.assert_called_once_with(dst_ssh=self.handler.dst_ssh,
                                    src_path="/a/1.py",
                                    dst_path="/b/a/1.py")
コード例 #30
0
def test_move_events(sync):

    file_events = [
        # created + moved -> created
        FileCreatedEvent(ipath(1)),
        FileMovedEvent(ipath(1), ipath(2)),
        # moved + deleted -> deleted
        FileMovedEvent(ipath(1), ipath(4)),
        FileDeletedEvent(ipath(4)),
        # moved + moved back -> modified
        FileMovedEvent(ipath(5), ipath(6)),
        FileMovedEvent(ipath(6), ipath(5)),
        # moved + moved -> deleted + created
        # (this is currently not handled as a single moved)
        FileMovedEvent(ipath(7), ipath(8)),
        FileMovedEvent(ipath(8), ipath(9)),
    ]

    res = [
        # created + moved -> created
        FileCreatedEvent(ipath(2)),
        # moved + deleted -> deleted
        FileDeletedEvent(ipath(1)),
        # moved + moved back -> modified
        FileModifiedEvent(ipath(5)),
        # moved + moved -> deleted + created
        # (this is currently not handled as a single moved)
        FileDeletedEvent(ipath(7)),
        FileCreatedEvent(ipath(9)),
    ]

    cleaned_events = sync._clean_local_events(file_events)
    assert set(cleaned_events) == set(res)
コード例 #31
0
 def test___repr__(self):
   event = FileMovedEvent(path_1, path_2)
   self.assertEqual("<FileMovedEvent: src_path=%s, dest_path=%s>" %\
                    (path_1, path_2), event.__repr__())