Exemple #1
0
 def prepare_copy(self, src_url, dst_url):
     src_scheme, src_path = splitscheme(src_url)
     dst_scheme, dst_path = splitscheme(dst_url)
     if src_scheme == self.scheme and dst_scheme == 'file://':
         zip_path, path_in_zip = self._split(src_path)
         dst_ospath = as_human_readable(dst_url)
         return [Extract(self._fs, zip_path, path_in_zip, dst_ospath)]
     elif src_scheme == 'file://' and dst_scheme == self.scheme:
         zip_path, path_in_zip = self._split(dst_path)
         src_ospath = as_human_readable(src_url)
         return [
             AddToArchive(self, self._fs, src_ospath, zip_path, path_in_zip)
         ]
     elif src_scheme == dst_scheme:
         # Guaranteed by fman's file system implementation:
         assert src_scheme == self.scheme
         src_zip_path, path_in_src_zip = self._split(src_path)
         dst_zip_path, path_in_dst_zip = self._split(dst_path)
         return [
             CopyBetweenArchives(self, self._fs, src_zip_path,
                                 path_in_src_zip, dst_zip_path,
                                 path_in_dst_zip)
         ]
     else:
         raise UnsupportedOperation()
Exemple #2
0
 def __call__(self):
     pane_path = self.pane.get_path()
     clipboard.clear()
     clipboard.set_text(pane_path)
     clipboard.set_text(splitscheme(pane_path)[1])
     show_status_message('Copied ' + splitscheme(pane_path)[1] +
                         ' to the clipboard',
                         timeout_secs=3)
Exemple #3
0
 def _rename(self, src_url, dst_url):
     src_path = splitscheme(src_url)[1]
     os_src_path = self._url_to_os_path(src_path)
     dst_path = splitscheme(dst_url)[1]
     os_dst_path = self._url_to_os_path(dst_path)
     Path(os_src_path).replace(os_dst_path)
     self.notify_file_removed(src_path)
     self.notify_file_added(dst_path)
Exemple #4
0
 def _check_transfer_precnds(self, src_url, dst_url):
     src_scheme, src_path = splitscheme(src_url)
     dst_scheme, dst_path = splitscheme(dst_url)
     if src_scheme != self.scheme or dst_scheme != self.scheme:
         raise UnsupportedOperation()
     if not self._isabs(self._url_to_os_path(dst_path)):
         raise ValueError('Destination path must be absolute')
     return src_path, dst_path
Exemple #5
0
 def _get_dest_dir_url(self):
     try:
         splitscheme(self._dest_dir)
     except ValueError as not_a_url:
         is_url = False
     else:
         is_url = True
     return self._dest_dir if is_url else join(self._src_dir,
                                               self._dest_dir)
Exemple #6
0
 def _check_transfer_precnds(self, src_url, dst_url):
     src_scheme, src_path = splitscheme(src_url)
     dst_scheme, dst_path = splitscheme(dst_url)
     if src_scheme != self.scheme or dst_scheme != self.scheme:
         raise UnsupportedOperation(
             "%s only supports transferring to and from %s." %
             (self.__class__.__name__, self.scheme))
     if not self._isabs(self._url_to_os_path(dst_path)):
         raise ValueError('Destination path must be absolute')
     return src_path, dst_path
Exemple #7
0
 def _prepare_move(self,
                   src_url,
                   dst_url,
                   measure_size=False,
                   use_rename=True,
                   expected_st_dev=None):
     if expected_st_dev is None:
         expected_st_dev = {}
     src_path, dst_path = self._check_transfer_precnds(src_url, dst_url)
     if use_rename:
         src_stat = self.stat(src_path)
         dst_par_path = splitscheme(dirname(dst_url))[1]
         try:
             dst_par_dev = expected_st_dev[dst_par_path]
         except KeyError:
             dst_par_dev = self.stat(dst_par_path).st_dev
         if src_stat.st_dev == dst_par_dev:
             yield Task('Moving ' + basename(src_url),
                        size=1,
                        fn=self._rename,
                        args=(src_url, dst_url))
             return
     src_is_dir = self.is_dir(src_path)
     if src_is_dir:
         yield Task('Creating ' + basename(dst_url),
                    fn=self.mkdir,
                    args=(dst_path, ))
         dst_par_path = splitscheme(dirname(dst_url))[1]
         # Expect `dst_path` to inherit .st_dev from its parent:
         try:
             expected_st_dev[dst_path] = expected_st_dev[dst_par_path]
         except KeyError:
             expected_st_dev[dst_path] = self.stat(dst_par_path).st_dev
         for name in self.iterdir(src_path):
             try:
                 yield from self._prepare_move(join(src_url, name),
                                               join(dst_url,
                                                    name), measure_size,
                                               use_rename, expected_st_dev)
             except FileNotFoundError:
                 pass
         yield DeleteIfEmpty(self, src_url)
     else:
         size = self.size_bytes(src_path) if measure_size else 0
         # It's tempting to "yield copy" then "yield delete" here. But this
         # can lead to data loss: fman / the user may choose to ignore errors
         # in a particular subtask. (Eg. moving file1.txt failed but the user
         # wants to go on to move file2.txt.) If we ignored a failure in
         # "yield copy" but then execute the "yield delete", we would delete
         # a file that has not been copied!
         # To avoid this, we "copy and delete" as a single, atomic task:
         yield MoveByCopying(self, src_url, dst_url, size)
Exemple #8
0
    def move(self, src_url, dst_url):
        # Rename on same server
        src_scheme, src_path = splitscheme(src_url)
        dst_scheme, dst_path = splitscheme(dst_url)
        if src_scheme == dst_scheme and commonprefix([src_path, dst_path]):
            # TODO avoid second connection
            with FtpWrapper(src_url) as src_ftp, \
                    FtpWrapper(dst_url) as dst_ftp:
                src_ftp.conn.rename(src_ftp.path, dst_ftp.path)
                return

        fs.copy(src_url, dst_url)
        if fs.exists(src_url):
            fs.delete(src_url)
Exemple #9
0
 def __call__(self):
     show_status_message('Regular Expressions Selection')
     result = show_quicksearch(self._suggest_projects)
     if result:
         query, regexp = result
         try:
             pattern = re.compile(regexp)
         except Exception as e:
             show_alert('Your Regular Expression statement is not valid.' +
                        str(e))
             self.__call__()
             return
         used = False
         lines = [""]
         if os.path.isfile(REGULAREXPRESSIONHIST):
             with open(REGULAREXPRESSIONHIST, "r") as f:
                 lines = f.readlines()
         for line in lines:
             if line.strip() == regexp:
                 used = True
         if not used:
             with open(REGULAREXPRESSIONHIST, "a") as f:
                 f.write(regexp + "\n")
         scheme, currentDir = splitscheme(self.pane.get_path())
         for filep in iterdir(self.pane.get_path()):
             if pattern.search(filep):
                 self.pane.toggle_selection(
                     as_url(currentDir + os.sep + filep, scheme))
     clear_status_message()
Exemple #10
0
 def test_delete_readonly_file(self):
     with TemporaryDirectory() as tmp_dir:
         path = Path(tmp_dir, 'file')
         path.touch()
         path.chmod(path.stat().st_mode ^ S_IWRITE)
         urlpath = splitscheme(as_url(path))[1]
         self._fs.delete(urlpath)
Exemple #11
0
    def on_command(self, command_name, args):
        if command_name != 'open_file':
            return

        url = args['url']
        scheme, path = splitscheme(url)
        if not is_ftp(scheme):
            return

        tmp = NamedTemporaryFile(prefix=basename(path), delete=False)
        tmp_path = tmp.name
        tmp_url = 'file://' + tmp_path

        fs.copy(url, tmp_url)
        _open_local_file(tmp_path)
        choice = show_alert(
            'Upload modified file?',
            buttons=YES | NO,
            default_button=YES
        )

        if choice == YES:
            fs.move(tmp_url, url)

        return 'reload', {}
Exemple #12
0
 def __call__(self, url=None):
     if url is None:
         url = self.pane.get_file_under_cursor() or self.pane.get_path()
     if not is_dir(url):
         url = dirname(url)
     new_url = Flat.scheme + splitscheme(url)[1]
     self.pane.set_path(new_url)
Exemple #13
0
 def _get_action(self):
     file_under_cursor = self.pane.get_file_under_cursor()
     selected_files = self.pane.get_selected_files()
     chosen_files = selected_files or \
                    ([file_under_cursor] if file_under_cursor else [])
     location = self.pane.get_path()
     scheme, path = splitscheme(location)
     if scheme == 'file://':
         if file_under_cursor is None:
             # Either we're in an empty folder, or the user
             # right-clicked inside a directory.
             if self._is_drive(path):
                 return lambda: _show_drive_properties(path)
             else:
                 dir_ = as_human_readable(dirname(location))
                 filenames = [basename(location)]
         else:
             dir_ = as_human_readable(location)
             filenames = [basename(f) for f in chosen_files]
         return lambda: _show_file_properties(dir_, filenames)
     elif scheme == 'drives://':
         if file_under_cursor is None:
             # This usually happens when the user right-clicked in the drive
             # overview (but not _on_ a drive).
             return None
         drive = splitscheme(file_under_cursor)[1]
         if self._is_drive(drive):
             return lambda: _show_drive_properties(drive)
     elif scheme == 'network://':
         # We check `path` because when it's empty, we're at the
         # overview of network locations. Servers don't have a Properties
         # dialog. So we can't do anything there.
         if path:
             for f in chosen_files:
                 try:
                     f_fileurl = resolve(f)
                 except OSError:
                     continue
                 if splitscheme(f_fileurl)[0] != 'file://':
                     # Sanity check. We don't actually expect this.
                     continue
                 dir_ = as_human_readable(dirname(f_fileurl))
                 break
             else:
                 return
             filenames = [basename(f) for f in chosen_files]
             return lambda: _show_file_properties(dir_, filenames)
Exemple #14
0
 def test_mkdir_raises_filenotfounderror(self):
     with TemporaryDirectory() as tmp_dir:
         zip_path = os.path.join(tmp_dir, 'test.zip')
         self._create_empty_zip(zip_path)
         zip_url_path = splitscheme(as_url(zip_path, 'zip://'))[1]
         with self.assertRaises(OSError) as cm:
             self._fs.mkdir(zip_url_path + '/nonexistent/dir')
         self.assertEqual(ENOENT, cm.exception.errno)
Exemple #15
0
 def test_mkdir_raises_fileexistserror(self):
     with TemporaryDirectory() as tmp_dir:
         zip_path = os.path.join(tmp_dir, 'test.zip')
         self._create_empty_zip(zip_path)
         dir_url_path = splitscheme(as_url(zip_path, 'zip://'))[1] + '/dir'
         self._fs.mkdir(dir_url_path)
         with self.assertRaises(FileExistsError):
             self._fs.mkdir(dir_url_path)
Exemple #16
0
 def prepare_move(self, src_url, dst_url):
     src_scheme, src_path = splitscheme(src_url)
     dst_scheme, dst_path = splitscheme(dst_url)
     if src_scheme == dst_scheme:
         # Guaranteed by fman's file system implementation:
         assert src_scheme == self.scheme
         src_zip, src_pth_in_zip = self._split(src_path)
         dst_zip, dst_pth_in_zip = self._split(dst_path)
         if src_zip == dst_zip:
             return [Rename(self, src_zip, src_pth_in_zip, dst_pth_in_zip)]
         else:
             return [MoveBetweenArchives(self, src_url, dst_url)]
     else:
         result = list(self.prepare_copy(src_url, dst_url))
         title = 'Cleaning up ' + basename(src_url)
         result.append(Task(title, fn=self._fs.delete, args=(src_url, )))
         return result
Exemple #17
0
 def test_delete_symlink_to_directory(self):
     with TemporaryDirectory() as tmp_dir:
         a = Path(tmp_dir, 'a')
         a.mkdir()
         b = Path(tmp_dir, 'b')
         b.symlink_to(a)
         self._fs.delete(splitscheme(as_url(b))[1])
         self.assertFalse(b.exists(), 'Failed to delete symlink to folder')
Exemple #18
0
    def copy(self, src_url, dst_url):
        src_scheme, src_path = splitscheme(src_url)

        file_scheme = 'file://'

        if src_scheme == self.scheme and dst_scheme == file_scheme:
            fman.fs.copy(as_url(src_path, file_scheme), dst_url)
        else:
            raise UnsupportedOperation()
Exemple #19
0
 def __call__(self):
     scheme = splitscheme(self.pane.get_path())[0]
     if scheme not in ('file://', 'drives://', 'network://'):
         show_alert('Sorry, showing the properties of %s files is not '
                    'yet supported.' % scheme)
     else:
         action = self._get_action()
         if action:
             action()
Exemple #20
0
 def __call__(self, *args, **kwargs):
     try:
         rmdir(as_human_readable(self._dir_url))
     except FileNotFoundError:
         pass
     except OSError as e:
         if e.errno != errno.ENOTEMPTY:
             raise
     self._fs.notify_file_removed(splitscheme(self._dir_url)[1])
Exemple #21
0
 def on_command(self, command_name, args):
     if command_name == 'open_file':
         if 'url' in args:
             url = args['url']
             scheme, path = splitscheme(url)
             if scheme == 'flat://':
                 self.path = path
                 self.pane.set_path('file://' + path.split(_SEPARATOR)[0],
                                    callback=self.callback)
                 return 'open_directory', {'url': to_file_url(self.path)}
Exemple #22
0
 def _get_dest_url(self, src_file):
     dest_name = self._dest_name or basename(src_file)
     if self._src_dir:
         try:
             rel_path = \
              relpath(join(dirname(src_file), dest_name), self._src_dir)
         except ValueError as e:
             raise ValueError('Could not construct path. '
                              'src_file: %r, dest_name: %r, src_dir: %r' %
                              (src_file, dest_name, self._src_dir)) from e
         is_in_src_dir = not rel_path.startswith(pardir)
         if is_in_src_dir:
             try:
                 splitscheme(self._dest_dir)
             except ValueError as no_scheme:
                 return join(self._src_dir, self._dest_dir, rel_path)
             else:
                 return join(self._dest_dir, rel_path)
     return join(self._dest_dir, dest_name)
Exemple #23
0
 def on_path_changed(self):
     url = self.pane.get_path()
     if not is_ftp(url):
         return
     scheme, path = splitscheme(url)
     if not path:
         # XXX avoid storing URLs with empty path
         return
     history = \
         load_json('FTP History.json', default={}, save_on_quit=True)
     history[url] = history.get(url, 0) + 1
    def __call__(self):
        url = self.pane.get_path()
        scheme, path = splitscheme(url)

        paths = []
        paths.append(as_url(path))
        if scheme != 'file://':
            show_alert('{} is not supported'.format(url))
            return

        openCommand(" /command:repobrowser /path:", paths, path)
Exemple #25
0
 def __call__(self, url=None):
     text, ok = show_prompt('Enter Filter e.g. *.txt',
                            default="*.txt",
                            selection_start=2)
     if url is None:
         url = self.pane.get_file_under_cursor() or self.pane.get_path()
     if not is_dir(url):
         url = dirname(url)
     Flat.filtertext = text
     new_url = Flat.scheme + splitscheme(url)[1]
     # Not working yet
     if ok and text:
         self.pane.set_path(new_url + '?' + text)
Exemple #26
0
 def __call__(self):
     url = self.pane.get_path()
     scheme, path = splitscheme(url)
     if scheme != 'file://':
         show_alert('Not supported.')
         return
     local_path = as_human_readable(url)
     if platform.system() == 'Windows' and os.path.isfile(self.GIT_BASH):
         subprocess.call('{bash_exe} --cd="{cd}"'.format(
             bash_exe=self.GIT_BASH,
             cd=local_path))
     else:
         self.pane.run_command('open_terminal')
Exemple #27
0
 def get_str(self, url):
     scheme, path = splitscheme(url)
     rootKey = ConnectRegistry(None, HKEY_CURRENT_USER)
     parent = dirname(path).replace("/", "\\")
     valueName = basename(path)
     try:
         key = OpenKey(rootKey, parent)
     except EnvironmentError:
         return None
     try:
         value = QueryValueEx(key, valueName)
     except EnvironmentError:
         return None
     return str(value[0])
Exemple #28
0
    def __call__(self):
        scheme, currentDir = splitscheme(self.pane.get_path())
        currentDir = os.path.normpath(currentDir)

        global current_dir
        global current_parent_dir

        current_dir = currentDir
        current_parent_dir = os.path.normpath(
            os.path.join(current_dir, os.pardir))

        self.searchDialog = SearchDialog(scheme, currentDir, self.pane,
                                         root_node)
        self.searchDialog.show()
Exemple #29
0
 def _prepare_move(self, src_url, dst_url, measure_size=False):
     src_path, dst_path = self._check_transfer_precnds(src_url, dst_url)
     src_stat = self.stat(src_path)
     dst_dir_dev = self.stat(splitscheme(dirname(dst_url))[1]).st_dev
     if src_stat.st_dev == dst_dir_dev:
         yield Task('Moving ' + basename(src_url),
                    size=1,
                    fn=self._rename,
                    args=(src_url, dst_url))
         return
     yield from self._prepare_copy(src_url, dst_url, measure_size)
     yield Task('Postprocessing ' + basename(src_url),
                fn=self.delete,
                args=(src_path, ))
Exemple #30
0
 def get_str(self, url):
     scheme, path = splitscheme(url)
     if scheme != 'drives://':
         raise ValueError('Unsupported URL: %r' % url)
     if path == DrivesFileSystem.NETWORK:
         return path
     result = path
     try:
         vol_name = self._get_volume_name(path + '\\')
     except WindowsError:
         pass
     else:
         if vol_name:
             result += ' ' + vol_name
     return result