示例#1
0
    def restore_file_from_copy(self,
                               file_name,
                               copy_hash,
                               events_file_id,
                               search_by_id=False):
        try:
            old_hash = self._quiet_processor.create_file_from_copy(
                file_name,
                copy_hash,
                silent=True,
                events_file_id=events_file_id,
                search_by_id=search_by_id,
                wrong_file_id=self.Exceptions.WrongFileId,
                copy_does_not_exists=self.Exceptions.CopyDoesNotExists)
        except AssertionError:
            self._on_event_arrived(
                FsEvent(DELETE,
                        op.dirname(
                            self._path_converter.create_abspath(file_name)),
                        True,
                        is_offline=True,
                        quiet=True))
            raise

        return old_hash
示例#2
0
    def move_file(self, src, dst, is_offline=True):
        src_full_path = self._path_converter.create_abspath(src)
        dst_full_path = self._path_converter.create_abspath(dst)
        is_offline = True if op.isdir(src_full_path) else is_offline
        src_hard_path = self._quiet_processor.get_hard_path(
            src_full_path, is_offline)
        dst_hard_path = self._quiet_processor.get_hard_path(
            dst_full_path, is_offline)

        if not op.exists(src_hard_path):
            raise self.Exceptions.FileNotFound(src_full_path)
        elif op.exists(dst_hard_path):
            raise self.Exceptions.FileAlreadyExists(dst_full_path)

        dst_parent_folder_path = op.dirname(dst_full_path)
        if not op.exists(dst_parent_folder_path):
            self._on_event_arrived(
                FsEvent(DELETE,
                        dst_parent_folder_path,
                        True,
                        is_offline=True,
                        quiet=True))

        try:
            os.rename(src_hard_path, dst_hard_path)
        except OSError as e:
            logger.warning("Can't move file (dir) %s. Reason: %s",
                           src_full_path, e)
            if e.errno == errno.EACCES:
                self._quiet_processor.access_denied()
                raise self.Exceptions.AccessDenied(src_full_path)
            else:
                raise e
    def _on_new_event(self, fs_event):
        dirname = FilePath(op.dirname(fs_event.src))

        if dirname != self._root and not op.exists(dirname):
            self.event_spawned(
                FsEvent(DELETE,
                        dirname,
                        True,
                        is_offline=fs_event.is_offline,
                        quiet=fs_event.quiet,
                        event_time=fs_event.time))
            self.event_suppressed(fs_event)
        else:
            self.event_passed(fs_event)
示例#4
0
 def create_directory(self, path, events_file_id):
     full_path = self._path_converter.create_abspath(path)
     try:
         self._quiet_processor.create_directory(
             full_path,
             events_file_id=events_file_id,
             wrong_file_id=self.Exceptions.WrongFileId)
     except AssertionError:
         self._on_event_arrived(
             FsEvent(DELETE,
                     op.dirname(full_path),
                     True,
                     is_offline=True,
                     quiet=True))
         raise
    def _process(self, fs_event):
        src_path = fs_event.src[: -len(FILE_LINK_SUFFIX)] if fs_event.is_link \
            else fs_event.src
        dst_path = fs_event.dst[: -len(FILE_LINK_SUFFIX)] if fs_event.is_link \
            else fs_event.dst
        if not self._check_file_exists_on_fs(fs_event.src) \
                and self._check_file_exists_in_storage(src_path) \
                and self._check_file_exists_on_fs(fs_event.dst) \
                and not self._check_file_exists_in_storage(dst_path):
            self.event_passed(fs_event)
            if not fs_event.is_dir:
                self.event_spawned(
                    FsEvent(event_type=MODIFY,
                            src=fs_event.dst,
                            is_dir=fs_event.is_dir))
            return

        fs_event.event_type = CREATE if fs_event.is_dir else MODIFY
        self.event_spawned(
            FsEvent(event_type=fs_event.event_type,
                    src=fs_event.dst,
                    is_dir=fs_event.is_dir))
        fs_event.dst = None
        self.event_returned(fs_event)
示例#6
0
    def accept_move(self,
                    src,
                    dst,
                    is_directory=False,
                    events_file_id=None,
                    is_offline=True):
        src_full_path = self._path_converter.create_abspath(src)
        dst_full_path = self._path_converter.create_abspath(dst)

        try:
            object_type = 'directory' if is_directory else 'file'
            logger.debug("Moving '%s' %s to '%s'...", src, object_type, dst)
            if is_directory:
                self._quiet_processor.move_directory(
                    src_full_path,
                    dst_full_path,
                    events_file_id,
                    self.Exceptions.FileAlreadyExists,
                    self.Exceptions.FileNotFound,
                    wrong_file_id=self.Exceptions.WrongFileId)
            else:
                self._quiet_processor.move_file(
                    src_full_path,
                    dst_full_path,
                    events_file_id,
                    self.Exceptions.FileAlreadyExists,
                    self.Exceptions.FileNotFound,
                    wrong_file_id=self.Exceptions.WrongFileId,
                    is_offline=is_offline)
            logger.info("'%s' %s is moved to '%s'", src, object_type, dst)
            self.file_removed_from_indexing.emit(FilePath(src_full_path), True)
        except AssertionError:
            self._on_event_arrived(
                FsEvent(DELETE,
                        op.dirname(dst_full_path),
                        True,
                        is_offline=True,
                        quiet=True))
            raise
示例#7
0
 def create_empty_file(self,
                       file_name,
                       file_hash,
                       events_file_id,
                       search_by_id=False,
                       is_offline=True):
     try:
         self._quiet_processor.create_empty_file(
             file_name,
             file_hash,
             silent=True,
             events_file_id=events_file_id,
             search_by_id=search_by_id,
             wrong_file_id=self.Exceptions.WrongFileId,
             is_offline=is_offline)
     except AssertionError:
         self._on_event_arrived(
             FsEvent(DELETE,
                     op.dirname(
                         self._path_converter.create_abspath(file_name)),
                     True,
                     is_offline=True,
                     quiet=True))
         raise
示例#8
0
    def apply_patch(self, filename, patch, new_hash, old_hash, events_file_id):
        '''
        Applies given patch for the file specified

        @param filename Name of file relative to sync directory [unicode]
        @param patch Patch data [dict]
        '''

        full_fn = self._path_converter.create_abspath(filename)

        try:
            self._apply_patch(full_fn,
                              patch,
                              new_hash,
                              old_hash,
                              events_file_id=events_file_id)
        except AssertionError:
            self._on_event_arrived(
                FsEvent(DELETE,
                        op.dirname(full_fn),
                        True,
                        is_offline=True,
                        quiet=True))
            raise
示例#9
0
    def _check_root(self, root, process_modifies):
        """
        Check given root path for offline events

        @param root Path (absolute) to be checked [unicode]
        """
        if FilePath(root) in self._special_dirs:
            return

        logger.info("Checking root '%s' folder for offline changes...", root)

        self._start_time = time.time()

        logger.debug("Obtaining known files from storage...")
        known_files = set(self._storage.get_known_files())
        if not self._active or not self._started:
            return
        logger.debug("Known files: %s", len(known_files))

        logger.debug("Obtaining actual files and folders from filesystem...")
        actual_folders, actual_files = get_files_dir_list(
            root,
            exclude_dirs=self._root_handlers[root][0].hidden_dirs,
            exclude_files=self._root_handlers[root][0].hidden_files)
        if not self._active or not self._started:
            return
        logger.debug("Actual folders: %s", len(actual_folders))
        logger.debug("Actual files: %s", len(actual_files))

        actual_files = set(map(FilePath, actual_files)) - self._special_files
        actual_folders = set(map(FilePath, actual_folders))

        if not self._active or not self._started:
            return

        self._offline_stats['file_COUNT'] = len(actual_files)

        logger.debug("Finding files that were created...")
        files_created = actual_files.difference(known_files)
        if not self._active or not self._started:
            return

        logger.debug("Finding files that were deleted...")
        files_deleted = known_files.difference(actual_files)
        if not self._active or not self._started:
            return

        for path in files_deleted.copy():
            if not self._active or not self._started:
                return

            path_plus_suffix = path + FILE_LINK_SUFFIX
            if path_plus_suffix in files_created:
                files_deleted.discard(path)
                files_created.discard(path_plus_suffix)

        logger.debug("Obtaining known folders from storage...")
        known_folders = set(self._storage.get_known_folders())

        if not self._active or not self._started:
            return
        logger.debug("Known folders: %s", len(known_folders))

        logger.debug("Finding folders that were created...")
        folders_created = sorted(actual_folders.difference(known_folders),
                                 key=len,
                                 reverse=True)
        if not self._active or not self._started:
            return

        logger.debug("Finding folders that were deleted...")
        folders_deleted = sorted(known_folders.difference(actual_folders),
                                 key=len,
                                 reverse=True)

        if not self._active or not self._started:
            return

        logger.info("Folders found: %s (created: %s, deleted: %s)",
                    len(actual_folders), len(folders_created),
                    len(folders_deleted))

        self._offline_stats['dir_COUNT'] = len(actual_folders)

        logger.debug("Appending deleted files to processing...")
        for filename in files_deleted:
            if not self._active or not self._started:
                return
            self._emit_offline_event(
                FsEvent(event_type=DELETE,
                        src=filename,
                        is_dir=False,
                        is_offline=True))

        logger.debug("Appending deleted folders to processing...")
        for foldername in folders_deleted:
            if not self._active or not self._started:
                return
            self._emit_offline_event(
                FsEvent(event_type=DELETE,
                        src=foldername,
                        is_dir=True,
                        is_offline=True))

        logger.debug("Appending created files to processing...")
        for filename in files_created:
            if not self._active or not self._started:
                return
            self._emit_offline_event(
                FsEvent(event_type=CREATE,
                        src=filename,
                        is_dir=False,
                        is_offline=True))

        logger.debug("Appending created folders to processing...")
        for foldername in folders_created:
            if not self._active or not self._started:
                return
            self._emit_offline_event(
                FsEvent(event_type=CREATE,
                        src=foldername,
                        is_dir=True,
                        is_offline=True))

        self._processed_offline_changes = True
        self.is_processing_offline = False
        logger.debug("Emitting ofline events processed signal")
        self.processed_offline_changes.emit()

        if not process_modifies:
            return

        logger.debug("Finding files with possible modifications...")
        same_files = actual_files.intersection(known_files)

        if not self._active or not self._started:
            return

        logger.info(
            "Files found: %s (created: %s, deleted: %s, remaining: %s)",
            len(actual_files), len(files_created), len(files_deleted),
            len(same_files))

        logger.debug("Appending possible modified files to processing...")
        for filename in same_files:
            if not self._active or not self._started:
                return
            # Actual file modification will be checked by event filters
            # applied in WatchdogHandler instance
            self._emit_offline_event(
                FsEvent(
                    event_type=MODIFY,
                    src=filename,
                    is_dir=False,
                    is_offline=True,
                    quiet=True,
                ))
        logger.debug("work complete")