def __call__(self): # check file under cursor current_file = self.pane.get_file_under_cursor() # simply checking the file extension if re.compile(r'\.lnk$').search(current_file): # ok, let's receive the real folder containing the target of that shortcut shellscript = os.path.dirname(__file__) + "\link_target.ps1 " command = "powershell -ExecutionPolicy Bypass -NoLogo -Noninteractive -noprofile" command += ' -file "' + shellscript + '"' command += ' -link "' + as_human_readable(current_file) + '"' #show_status_message("Command: " + command) # temporary target = as_url(os.popen(command).read().strip()) show_status_message("Target: " + target, 2) # what did we get? if False == exists(target): # target is not reachable... show_alert(target + " doesn't exist.") elif is_dir(target): # target is a folder, we go to it self.pane.set_path(target) else: # target is a file, we go to its directory self.pane.set_path(dirname(target)) else: # nope, wrong thing show_alert(current_file + " is not a shortcut.")
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)
def test_into_subfolder(self): dest_path = as_human_readable(join(self._dest, 'a.txt')) sel_start = dest_path.rindex(os.sep) + 1 self._expect_prompt( ('Move "a.txt" to', dest_path, sel_start, sel_start + 1), ('a', True) ) self._check([self._a_txt], (self._a, None))
def test_file_system_root(self): dest_path = as_human_readable(join(self._root, 'a.txt')) sel_start = dest_path.rindex(os.sep) + 1 self._expect_prompt( ('Move "a.txt" to', dest_path, sel_start, sel_start + 1), (dest_path, True) ) self._check([self._a_txt], (self._root, 'a.txt'), dest_dir=self._root)
def __call__(self): config = load_config() folder = as_human_readable(self.pane.get_path()).replace(path.sep, '/') launch_vscode(binPath=config["bin"], options=LaunchOptions.NewWindow | LaunchOptions.OpenFolder, userargs=config["additionalArgs"], args=[folder])
def __call__(self): filesSelection = self.pane.get_selected_files() if not filesSelection: fileUnderCursor = self.pane.get_file_under_cursor() if fileUnderCursor is not None: filepath = as_human_readable(fileUnderCursor) set_text(ntpath.basename(filepath)) else: fileList = "" first = True for files in filesSelection: if first: fileList += ntpath.basename(as_human_readable(files)) first = False else: fileList += ", " + ntpath.basename( as_human_readable(files)) set_text(fileList)
def __call__(self): selected_files = self.pane.get_selected_files() output = "" if len(selected_files) >= 1 or (len(selected_files) == 0 and self.get_chosen_files()): if len(selected_files) == 0 and self.get_chosen_files(): selected_files.append(self.get_chosen_files()[0]) dirPath = os.path.dirname(as_human_readable(selected_files[0])) unZipName = os.path.basename(as_human_readable(selected_files[0])) inFile = os.path.join(dirPath, unZipName) unZipDir = unZipName[:-4] unZipPath = os.path.join(dirPath, unZipDir) zipfile.ZipFile(inFile).extractall(path=unZipPath) output += "Files were unzipped to directory {0}".format(unZipDir) else: output += "No files or directories selected" show_alert(output)
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])
def test_different_scheme(self): dest_path = as_human_readable(join(self._dest, 'a.txt')) sel_start = dest_path.rindex(os.sep) + 1 self._expect_prompt( ('Move "a.txt" to', dest_path, sel_start, sel_start + 1), (dest_path, True)) src_url = 'zip:///dest.zip/a.txt' src_dir = dirname(src_url) self._check([src_url], (self._dest, 'a.txt'), src_dir=src_dir)
def test_overwrite_single_file(self): dest_url = join(self._dest, 'a.txt') self._fs._files[dest_url] = {'is_dir': False} dest_path = as_human_readable(dest_url) sel_start = dest_path.rindex(os.sep) + 1 self._expect_prompt( ('Move "a.txt" to', dest_path, sel_start, sel_start + 1), (dest_path, True)) self._check([self._a_txt], (self._dest, 'a.txt'))
def __call__(self): fileName = as_human_readable(self.get_chosen_files()[0]) gpg = GPG() myPass, ok = show_prompt('Passphrase') # https://stackoverflow.com/questions/4444923/get-filename-without-extension-in-python fileNameOut, ok = show_prompt('Target', default=os.path.splitext(fileName)[0]) with open(fileName, 'rb') as f: status = gpg.decrypt_file(f, passphrase=myPass, output=fileNameOut) show_alert('Status: ' + status.status)
def __call__(self): fileName = as_human_readable(self.get_chosen_files()[0]) gpg = GPG() default_recipient = self._get_default_recipient() recipient, ok = show_prompt('Recipient', default=default_recipient) with open(fileName, 'rb') as f: status = gpg.encrypt_file(f, recipients=[recipient], output=fileName + '.gpg') show_alert('Status: ' + status.status)
def _report_clipboard_action(verb, files, suffix='', ftype='file'): num = len(files) first_file = as_human_readable(files[0]) if num == 1: message = '%s %s%s' % (verb, first_file, suffix) else: plural = 's' if num > 2 else '' message = '%s %s and %d other %s%s%s' % \ (verb, first_file, num - 1, ftype, plural, suffix) show_status_message(message, timeout_secs=3)
def __call__(self): show_status_message('Launching a Script...') result = show_quicksearch(self._suggest_script) if result: # # Launch the script given. Show the output. # query, script = result # # Get the variables for this plugin # scriptVars = _GetScriptVars() # # Get a list of selected files. # selected_files = self.pane.get_selected_files() if len(selected_files) >= 1 or (len(selected_files) == 0 and self.get_chosen_files()): if len(selected_files) == 0 and self.get_chosen_files(): selected_files.append(self.get_chosen_files()[0]) fileList = '' first = True for file in selected_files: if first: fileList += as_human_readable(file) else: fileList += ',' + as_human_readable(file) # # Set the environment variables for the scripts to use. # os.putenv('CURRENT_DIRECTORY', as_human_readable(self.pane.get_path())) panes = self.pane.window.get_panes() os.putenv('LEFT_PANE', as_human_readable(panes[0].get_path())) path = panes[0].get_file_under_cursor() if path is not None: os.putenv('LEFT_PANE_SELECTED_FILE',as_human_readable(path)) else: os.putenv('LEFT_PANE_SELECTED_FILE',"") os.putenv('RIGHT_PANE', as_human_readable(panes[1].get_path())) path = panes[1].get_file_under_cursor() if path is not None: os.putenv('RIGHT_PANE_SELECTED_FILE',as_human_readable(path)) else: os.putenv('RIGHT_PANE_SELECTED_FILE',"") os.putenv('FILES_SELECTED',fileList) # # Run the script. # Output = run("source " + scriptVars['local_shell'] + "; '" + scriptVars['directory'] + "/" + script + "'",stdout=PIPE,shell=True) if Output.returncode == 0: if scriptVars['show_output']: show_alert(Output.stdout.decode("utf-8")) else: show_alert("Command line error.") clear_status_message()
def on_path_changed(self): # # See if the new directory is a project directory. # global LASTPOP, POPDIR, POPPING if not POPPING: LASTPOP = (LASTPOP + 1) % 10 POPDIR[LASTPOP] = as_human_readable(self.pane.get_path()) POPPING = False
def __call__(self): dst_urlpath = splitscheme(self._dst_url)[1] dst_existed = self._fs.exists(dst_urlpath) src = as_human_readable(self._src_url) dst = as_human_readable(self._dst_url) if islink(src): os.symlink(os.readlink(src), dst) else: with open(src, 'rb') as fsrc: with open(dst, 'wb') as fdst: num_written = 0 while True: self.check_canceled() buf = fsrc.read(16 * 1024) if not buf: break num_written += fdst.write(buf) self.set_progress(num_written) copystat(src, dst, follow_symlinks=False) if not dst_existed: self._fs.notify_file_added(dst_urlpath)
def __call__(self): # # Get the directory path. # selected_files = self.pane.get_selected_files() if len(selected_files) >= 1 or (len(selected_files) == 0 and self.get_chosen_files()): if len(selected_files) == 0 and self.get_chosen_files(): selected_files.append(self.get_chosen_files()[0]) dirName = as_human_readable(selected_files[0]) if os.path.isfile(dirName): # # It's a file, not a directory. Get the directory # name for this file's parent directory. # dirName = os.path.dirname(dirName) # # Set the directory obtained as a project directory. # with open(PROJECTDIR, "w") as f: f.write(dirName) # # Add to the list of projects. Get a name # from the user. # projName, checked = show_prompt("Name this Project:") projEntry = projName + "|" + dirName writeappend = 'w' if os.path.isfile(PROJECTSLIST): writeappend = 'a' with open(PROJECTSLIST, writeappend) as f: f.write(projEntry + "\n") # # Create the launch script file and open in the # editor. # scriptFile = dirName + "/.startproject" with open(scriptFile, 'w') as f: f.write("#!/bin/sh\n\n") os.chmod(scriptFile, stat.S_IEXEC | stat.S_IRUSR | stat.S_IWUSR) if (_THIRDPARTY_PLUGINS_DIR + "/OpenWithEditor") in _get_thirdparty_plugins(): self.pane.run_command("my_open_with_editor", args={'url': as_url(scriptFile)}) else: self.pane.run_command("open_with_editor", args={'url': as_url(scriptFile)}) else: # # Technically, this will never be reached. Just here # for completeness. # show_alert("No directory selected")
def __call__(self): to_copy = self.get_chosen_files() or [self.pane.get_path()] files = '\n'.join(to_copy) clipboard.clear() to_copy2 = map( lambda x: '"' + as_human_readable(x).replace("\\", "/") + '"', to_copy) clipboard.set_text(',\n'.join(to_copy2)) _report_clipboard_action('Copied', to_copy, ' to the clipboard', 'path')
def __call__(self): outlook = win32.Dispatch('outlook.application') mail = outlook.CreateItem(0) chosen_files = self.pane.get_selected_files() if not chosen_files: show_alert('No file selected.') return for chosen_file in chosen_files: file_to_send = as_human_readable(chosen_file) mail.Attachments.Add(Source=file_to_send) mail.Display(True)
def _suggest_my_files_and_folders(self, query): dir_path = as_human_readable(self.pane.get_path()) list_directory_content = listdir(dir_path) list_directory_content = sorted(list_directory_content, key=lambda s: s.lower()) for file_name in list_directory_content: file_path = join(dir_path, file_name) if isdir(file_path): file_name = '[' + file_name + ']' match = contains_chars(file_name.lower(), query.lower()) if match or not query: yield QuicksearchItem(file_path, file_name, highlight=match)
def _execute(self, command, path=None, close_on_end=2): arg_command = '/command:' + command if path is None: pane_path = self.pane.get_path() path = as_human_readable(pane_path) arg_path = '/path:"{}"'.format(path) arg_close_on_end = '/closeonend={}'.format(close_on_end) exec_command = [ "TortoiseGitProc.exe", arg_command, arg_path, arg_close_on_end ] show_status_message(' '.join(exec_command)) subprocess.run(' '.join(exec_command))
def test_add_file(self): with TemporaryDirectory() as tmp_dir: file_to_add = os.path.join(tmp_dir, 'tmp.txt') file_contents = 'added!' with open(file_to_add, 'w') as f: f.write(file_contents) dest_url_in_zip = self._url('ZipFileTest/Directory/added.txt') self._fs.copy(as_url(file_to_add), dest_url_in_zip) dest_url = join(as_url(tmp_dir), 'extracted.txt') self._fs.copy(dest_url_in_zip, dest_url) with open(as_human_readable(dest_url)) as f: actual_contents = f.read() self.assertEqual(file_contents, actual_contents)
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')
def __call__(self): result = show_quicksearch(self._get_items) if result: query, value = result if value == 'log_file': file = self.pane.get_file_under_cursor() if file is None: self._execute('log') else: self._execute('log', as_human_readable(file)) else: self._execute(value) else: pass
def __call__(self): show_status_message('Launching a Script...') if os.path.isfile(as_human_readable(self.pane.get_path()) + os.path.sep + 'package.json'): npmPackagePath = as_human_readable(self.pane.get_path()) + os.path.sep + 'package.json' npmPackagePtr = open(npmPackagePath,"r") npmPackage = json.loads(npmPackagePtr.read()) npmPackagePtr.close() if 'scripts' in npmPackage: result = show_quicksearch(self._suggest_script) if result: # # Launch the script given. Show the output. # query, script = result # # Get the variables for this plugin # scriptVars = _GetScriptVars() # # Run the script. # saveDir = os.getcwd() os.chdir(as_human_readable(self.pane.get_path()) + os.path.sep) Output = run("source " + scriptVars['local_shell'] + "; npm run " + script,stdout=PIPE,shell=True) os.chdir(saveDir) if Output.returncode == 0: if scriptVars['show_output']: show_alert(Output.stdout.decode("utf-8")) else: show_alert("Command line error.") else: show_alert("No scripts defined.") else: show_alert("Not a NPM project directory.") clear_status_message()
def __call__(self, url=None): sourceDirUrl = self.pane.get_path() archiveName = basename(sourceDirUrl) + '.7z' oppositePane = _get_opposite_pane(self.pane) oppositePaneUrl = oppositePane.get_path() archiveUrl = join(oppositePaneUrl, archiveName) sourceDir = as_human_readable(sourceDirUrl) archive = as_human_readable(archiveUrl) if exists(archiveUrl): if is_dir(archiveUrl): message = archiveName + " exists and is a directory, aborting!" show_alert(message) return choice = show_alert("Archive exists!\nReplace?", buttons=YES | CANCEL, default_button=CANCEL) if choice == YES: try: move_to_trash(archiveUrl) except NotImplementedError: show_alert("Failed to delete archive, aborting!") return elif choice == CANCEL: return submit_task(CreateArchive(archive, sourceDir)) oppositePane.reload() return
def _gather_files(self): dest_dir_url = self._get_dest_dir_url() self._enqueue([ Task('Preparing ' + basename(dest_dir_url), fn=self._fs.makedirs, args=(dest_dir_url, ), kwargs={'exist_ok': True}) ]) for i, src in enumerate(self._iter(self._files)): is_last = i == len(self._files) - 1 dest = self._get_dest_url(src) if is_parent(src, dest, self._fs): if src != dest: try: is_samefile = self._fs.samefile(src, dest) except OSError: is_samefile = False if is_samefile: if self._can_transfer_samefile(): self._enqueue(self._prepare_transfer(src, dest)) continue self.show_alert("You cannot %s a file to itself." % self._descr_verb) return False try: is_dir = self._fs.is_dir(src) except OSError as e: error_message = 'Could not %s %s' % \ (self._descr_verb, as_human_readable(src)) if self._handle_exception(error_message, is_last, e): continue return False if is_dir: if self._fs.exists(dest): if not self._merge_directory(src): return False else: self._enqueue(self._prepare_transfer(src, dest)) else: if self._fs.exists(dest): should_overwrite = self._should_overwrite(dest) if should_overwrite == NO: continue elif should_overwrite == ABORT: return False else: assert should_overwrite == YES, should_overwrite self._enqueue(self._prepare_transfer(src, dest)) return True
def iterdir(self, path): # path=remove_query_text(path) # path is in the form of C:/tmp/one or C:/tmp/one?.*txt for filtered # Recommended way for turning C:/tmp/one into C:\tmp\one: local_path = as_human_readable('file://' + path) for (dir_path, dirs, file_names) in walk(local_path): # Adding posibility to filter out directories # and files dirs[:] = [d for d in dirs if not re.match(self.excludes, d)] file_names = [f for f in file_names if re.match(self.includes, f)] for file_name in file_names: file_path = os.path.join(dir_path, file_name) # file_path is now eg. C:\tmp\one\sub1\file.txt. # If we're iterating C:\tmp\one, yield "sub1|file.txt": yield path_to_name(relpath(file_path, local_path))
def on_path_changed(self): try: cmd = 'git rev-parse --abbrev-ref HEAD' path = as_human_readable(self.pane.get_path()) result = subprocess.run(cmd, stdout=subprocess.PIPE, cwd=path, shell=True) branch = result.stdout.decode(locale.getpreferredencoding())[:-1] if branch != '': show_status_message('Git branch ' + branch) else: show_status_message('') except NotADirectoryError as e: pass
def __call__(self): chosen_files = self.get_chosen_files() if chosen_files: chosen_files_human_readable = [as_human_readable(resolve(chosen_file)) for chosen_file in chosen_files] foobar2000_exe = self._get_foobar2000_exe_path() if foobar2000_exe: args = [foobar2000_exe, '/immediate', '/add'] # add '/show' to bring foobar2000 to front args.extend(chosen_files_human_readable) show_status_message("Executed command: {}".format(" ".join(args)), timeout_secs=30) subprocess.call(args) else: show_alert("SendToFoobar2000: No foobar2000 executable configured. Unable to continue.")