File Selection From Remote Machine In Python - python

I am writing a program in python on Ubuntu. In that program I am struggling to select a file using the command askopenfilename on a remote network connected RaspberryPi.
Can anybody guide me on how to select a file from the remote machine using askopenfilename command or something similar?
from Tkinter import *
from tkFileDialog import askopenfilename
import paramiko
if __name__ == '__main__':
root = Tk()
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.2.34', username='pi', password='raspberry')
name1= askopenfilename(title = "Select File For Removal", filetypes = [("Video Files","*.h264")])
stdin, stdout, stderr = client.exec_command('ls -l')
for line in stdout:
print '... ' + line.strip('\n')
client.close()

Haha, hello again!
It's not possible to use a tkinter's file dialogs to list (or select) files on remote machine. You would need to mount the remote machine's drive using, for example, SSHFS (as mentioned in the question's comment), or use a custom tkinter dialog which displays the remote files list (that is in the stdout variable) and lets you choose the one.
You can write a dialog window yourself, here's a quick demo:
from Tkinter import *
def double_clicked(event):
""" This function will be called when a user double-clicks on a list element.
It will print the filename of the selected file. """
file_id = event.widget.curselection() # get an index of the selected element
filename = event.widget.get(file_id[0]) # get the content of the first selected element
print filename
if __name__ == '__main__':
root = Tk()
files = ['file1.h264', 'file2.txt', 'file3.csv']
# create a listbox
listbox = Listbox(root)
listbox.pack()
# fill the listbox with the file list
for file in files:
listbox.insert(END, file)
# make it so when you double-click on the list's element, the double_clicked function runs (see above)
listbox.bind("<Double-Button-1>", double_clicked)
# run the tkinter window
root.mainloop()
The easiest solution without a tkinter is - you could make the user type the filename using the raw_input() function.
Kind of like that:
filename = raw_input('Enter filename to delete: ')
client.exec_command('rm {0}'.format(filename))
So the user would have to enter the filename that is to be deleted; then that filename gets passed directly to the rm command.
It's not really a safe approach - you should definitely escape the user's input. Imagine what if the user types '-rf /*' as a filename. Nothing good, even if you're not connected as a root.
But while you're learning and keeping the script to yourself I guess it's alright.

Related

How do I get the path selected by the user in Explorer?

I have a program that makes voice text using .txt ,but os.startfile doesn't let me select the file, hence get the path to it) I will be very grateful for your help!!
Как должно быть.
enter image description here
Как у меня)
enter image description here
import os
import pyttsx3 as pyt
from gtts import gTTS
class DICTOR:
def __init__(self, path):
self.engine = pyt.init()
#voices = self.engine.getProperty('voices')
self.engine.setProperty('voice', 0)
#rate = self.engine.getProperty('rate')
self.engine.setProperty('rate', 150)
with open(path, 'r') as file:
self.file = file.read()
# def speak(self):
# self.engine.say(self.file)
# self.engine.runAndWait()
def save(self, filename):
tss = gTTS(text = self.file, lang='en')
tss.save(filename)
#rate = self.engine.getProperty('rate')
path = os.startfile(filepath = 'D:\Python\Road_map\DICTOR')
DICTOR(path).save('.mp3')
I'm guessing your problem is with the formatting. You should add r to the start. It should be:
path = os.startfile(filepath = r"G:\EEGdatabase\6541455.docx")
the r is needed because \ is considered to be a special character by python. Another option is to escape \ with \\:
path = os.startfile(filepath = 'D:\\Python\\Road_map\\DICTOR')
More info in the docs.
Finally, since you haven't provided your error message, maybe this isn't your problem at all. If this doesn't fix it, add your error log so we know exactly what is going on.
Edit: It seems you have misunderstood the use of os.startfile. This function takes in something you need to "start", and starts it. So if you had said
os.startfile("something.pdf")
Then something.pdf will be opened in your default PDF software. If you instead passed in something like file.html, then this html file will be opened in your default web browser.
So you are now passing in D:\Python\Road_map\DICTOR, which is a folder, and the startfile function simply opens up that folder in Windows Explorer. A full reference for startfile can be found in the docs.
In any case, I don't think you need startfile at all. You need a file selector, which you can get using the Tkinter package. You can then say:
from Tkinter import Tk # from tkinter import Tk for Python 3.x
from tkinter.filedialog import askopenfilename
Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file
print(filename)
path = filename
(Taken from https://stackoverflow.com/a/3579625/3730626)

Canonical Method to get Long Filename from User

I am writing a Python module which will read and analyze an input file for a specialized software program. I want the user to be able to analyze whichever input file they choose. So far I've tried 2 methods to get the file name:
Method 1:
filename = input('File to be analyzed: ')
Pro: simplest method
Con: difficult for user to type long file path every time
Method 2:
Put a file called path.txt in the same directory as the Python module and the user can store the filename there.
import os
pathtxt_dir = os.path.dirname(os.path.realpath(__file__))
pathtxt_fullpath = os.path.join(pathtxt_dir, 'path.txt')
try:
fo = open(pathtxt_fullpath, 'r')
lines = fo.readlines()
fo.close()
except IOError:
raise Exception('path.txt cannot be opened')
filename = lines[0].rstrip().lstrip() # input file
Pro: Coworkers are familiar with this approach since it is similar to previous programs they have used.
Con: It seems like an unnecessarily complicated way to get user input
Question:
Is there a canonical Python method for getting long and repetitive user inputs, like this filename? Also, is there another useful method that I have not considered?
You can use tkinter to open a GUI for them to select the file. That way they don't have to type it out every time.
import tkinter as tk
from tkinter import filedialog as fd
import os
def getfile(title='Choose files', sformat='.*'):
root = tk.Tk()
root.lift()
# d and f are whatever default directory and filename
try:
f = fd.askopenfilename(parent=root, title=title, filetypes=[('', sformat)], initialdir=d, initialfile=f)
root.withdraw()
return f
except:
# print(title + ': error - no file exists')
return ''

Tkinter FileDialog.askopenfilename failing on already open files

I can not find a way using the the Tkinter tkFileDialog.askopenfilename / Open() method to get a file name of an already opened file. At least on Windows 7 anyway.
Simply need to return the filename selected, but when I select an 'opened' file I get the "This file is in use" popup. Any searches for getting filenames seems to always point back to using FileDialog.
There seems to be the same question but using c# here:
Open File Which is already open in window explorer
Are there any ways not listed that can be used to arrive at this? A file selection popup that doesn't fail on already opened files on Windows 7?
Python 2.7.11
Windows 7_64
Selection dialog:
opts = {}
opts['title'] = 'Select file.'
filename = tkFileDialog.Open(**opts).show()
or
filename = tkFileDialog.askopenfilename(**opts)
Which are the same as askopenfilename calls Open().show() which in turn is calling command = "tk_getOpenFile".
Searching tk_getOpenFile shows nothing to override this behavior.
Any pointers here would be much appreciated.
Update:
So as to not reiterate everything that's been gone over here's the break down of the Tkinter 8.5 FileDialog.
def askopenfile(mode = "r", **options):
"Ask for a filename to open, and returned the opened file"
filename = Open(**options).show()
if filename:
return open(filename, mode)
return None
def askopenfilename(**options):
"Ask for a filename to open"
return Open(**options).show()
Both call the Open class but askopenfile follows up with an open(file), here:
class Open(_Dialog):
"Ask for a filename to open"
command = "tk_getOpenFile"
def _fixresult(self, widget, result):
if isinstance(result, tuple):
# multiple results:
result = tuple([getattr(r, "string", r) for r in result])
if result:
import os
path, file = os.path.split(result[0])
self.options["initialdir"] = path
# don't set initialfile or filename, as we have multiple of these
return result
if not widget.tk.wantobjects() and "multiple" in self.options:
# Need to split result explicitly
return self._fixresult(widget, widget.tk.splitlist(result))
return _Dialog._fixresult(self, widget, result)
UPDATE2(answerish):
Seems the windows trc/tk tk_getOpenFile ultimately calls
OPENFILENAME ofn;
which apparently can not, at times, return a filename if the file is in use.
Yet to find the reason why but regardless.
In my case, needing to reference a running QuickBooks file, it will not work using askopenfilename().
Again the link above references someone having the same issue but using c# .

Using tkinter to create an ftp app that pulls file from dialog box

I use Filezilla to ftp files all the time at my job. I'm looking to give other people access to ftp files, but we don't want them to have the full access that filezilla gives. I was trying to create a basic python script that would do the following:
1. Let a user choose a file from a file dialog box
2. take that file and upload it to the FTP server
3. Throw the user back a message saying, hey your file was uploaded successfully.
I'm able to successfully connect to the FTP server, if I hardcode a file name that's in my python root directory. I'm struggling at passing a function with a parameter to the tkinter button. I want the file to be received by one function and then processed by another. Any help would be greatly appreciated, I'm a major python noob and I'm sure I'm missing something obvious...
import sys
from ftplib import FTP
from Tkinter import *
import tkFileDialog
#import Tkinter as ttk
def launch_file_dialog_box():
raw_filename = tkFileDialog.askopenfilename()
return raw_filename
def upload_file_to_FTP(raw_filename):
## first thing we do is connect to the ftp host
ftp = FTP('')
ftp.login( user = '', passwd='')
ftp.cwd("")
ftp.set_pasv(False)
file_name = raw_filename
file = open(file_name, 'rb')
ftp.storbinary('STOR ' + file_name, file)
file.quit()
App = Tk()
App.geometry("600x400+200+200")
App.title("Upload a Program Flyer to the Library Website")
Appbutton = Button(text='Choose a File to Upload', command = launch_file_dialog_box).pack()
Appbutton_FTP = Button(text='Upload File to FTP Server', command = upload_file_to_FTP(raw_filename)).pack()
App.mainloop()
use self keyword to use same variable across multiple function definition. create class and then create object later call mainloop()
import sys
from ftplib import FTP
import Tkinter as tk
import tkFileDialog
#import Tkinter as ttk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.geometry("600x400+200+200")
self.title("Upload a Program Flyer to the Library Website")
self.Appbutton = tk.Button(text='Choose a File to Upload', command = self.launch_file_dialog_box).pack()
self.Appbutton_FTP = tk.Button(text='Upload File to FTP Server', command = self.upload_file_to_FTP).pack()
def launch_file_dialog_box(self):
self.raw_filename = tkFileDialog.askopenfilename()
def upload_file_to_FTP(self):
## first thing we do is connect to the ftp host
ftp = FTP('')
ftp.login( user = '', passwd='')
ftp.cwd("")
ftp.set_pasv(False)
file_name = self.raw_filename
file = open(file_name, 'rb')
ftp.storbinary('STOR ' + file_name, file)
file.quit()
app = App()
app.mainloop()

Python Tkinter. Insert text in textbox from def?

I maked a script who need to pars 3D printer log files and export it to .xlsx.
I finished that but now I need to make GUI for that script, I finished almost everything except the one thing. I have function like this
def run(templatefilename):
#LIST OF PRINTER LOG FILES
listOfLogFiles = glob.glob(r"newPrintLogs\*.txt")
for logfile in listOfLogFiles:
#PARSING PRINTER LOG FILE
data = parsPrintingLog(logfile)
#WRITE EXCEL FILE
excelWrite(data, templatefilename)
# MOVE FINISHED FILES
dst = "finishedPrintLogs\\" + logfile.split('\\')[-1]
src = r"" + str(logfile)
shutil.move(src, dst)
consoleLog(src + " " + "successfully finished and moved to" + " " + dst)
# print (src, "successfully finished and moved to", dst)
and from this function I need to export the "# MOVE FINISHED FILES".
Before I've maked GUI I used print for printing where the log is moved, but now I don't know how to print it in GUI textbox, it's not necessary to be a textbox, I only need to show that in my GUI application.
Maybe i misunderstand your question, but from what I gathered you are wanting to dump the contents of your log file to be display in the tkinter GUI.
You could use a ttk ScrolledText widget.
Small minimal example"
textbox = ttk.ScrolledText(parent)
log_contents = open(log_file, "r").read()
textbox.insert("end", log_contents)
If you have some other encoding for your log file you could this for example
in textbox.insert log_contents could be decoded to utf-8 by log_contents.decode("utf-8")
You can then handle scrolling, searching the scrolledtext widget highlight found words etc by additional methods to search your log files contents for example.

Categories

Resources