Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getting file path #86

Closed
fennecinspace opened this issue Dec 4, 2018 · 6 comments
Closed

getting file path #86

fennecinspace opened this issue Dec 4, 2018 · 6 comments

Comments

@fennecinspace
Copy link

Hello, i have an input of type file, i want to get the path from the input to my python script, for example electron provides an additional input.files[0].path field that allows for this to happen, since the default web browser path would look like this c:/fakepath/filename.

@brumar
Copy link

brumar commented Dec 5, 2018

I don't think it's possible. The workaround I personally picked is to use the tkinter to do that (https://pythonspot.com/tk-file-dialogs/) . As this is in the standard library, this is not a problematic dependency to manage.

@ChrisKnott
Copy link
Collaborator

I did the same as @brumar. It's not possible unless you actually do use Electron as the browser

@ylmazmehmet60
Copy link

ylmazmehmet60 commented Dec 5, 2018

For security reasons it is not possible to get the file path through the browser as @ChrisKnott said. Using the Tkinter library, you can easily do it as shown in the example below.

app.py

@eel.expose
def btn_ResimyoluClick():
	root = Tk()
	root.withdraw()
	root.wm_attributes('-topmost', 1)
	folder = filedialog.askdirectory()
	return folder

main.html

<script>
async function getFolder() {
var dosya_path = await eel.btn_ResimyoluClick()();
	if (dosya_path) {
		console.log(dosya_path);
	}
}
</script>
<a onclick="getFolder()">GetFolder</a>

@brumar
Copy link

brumar commented Dec 6, 2018

I don't know if it's useful for anyone, but a creative alternative could be to use a jquery plug-in (like this one) to give the user an in-browser experience of file choosing. You need to make it call the python back-end so that it informs the plugin of the files and directory name at a given path (by using both os.listdir(path) and os.path.isdir(filepath). It's not the easiest path, but depending on you use case, that may fit.

Edit : I just tried it, the integration was quite straightforward. In case some people are interested :

backend.py

from pathlib import Path
HOME = str(Path.home())
@eel.expose
def get_root():
    return HOME
    
@eel.expose
def get_path_infos(path):
    try:
        files = os.listdir(path)
        real_files = [f for f in files if os.path.isfile(os.path.join(path, f))]
        real_dirs = [f for f in files if os.path.isdir(os.path.join(path, f))]
    except PermissionError:
        eel.alert_error("Can't read this files")
        return {"dirs": [], "files": []}
    except Exception as e:
        #do some things
        return {"dirs": [], "files": []}
    return {"dirs": real_dirs, "files": real_files}

script.js (adapted from https://github.com/jcubic/jquery.filebrowser)

$(function() {
	asynccontext = async function(){
		rootpath = await eel.get_root()()
		var browse = $('#browser').browse({
			root: rootpath,
			separator: '/',
			contextmenu: true,
			dir: function(path) {
				return(eel.get_path_infos(path)());
			},
			open: function(filename) {
				console.log('opening ' + filename);
			}
		});
	};
	asynccontext();
});

Of course you have to download the js, css, svg files from the repository and set up an index.html a bit like this.

<html>
<head>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script src="../js/jquery.filebrowser-src.js"></script>
  <link href="../css/jquery.filebrowser-src.css" rel="stylesheet"/>
  <style>
#browser {
	width: 600px;
	height: 400px;
	border: 1px solid gray;
}
  </style>
<script src="../script.js"></script>
</head>
	<div id="browser"></div>
<body>
</body>
</html>

edit: correct errors in code

@fennecinspace
Copy link
Author

thank you everyone for the amazing responses, i have been using this, i just thought i would open an issue for this to be added.

@gburlet
Copy link

gburlet commented Aug 12, 2020

I ran into this issue as well. Was hoping for some sort of solution like Electron as the OP mentioned. However, I understand why it doesn't exist. I wasn't a fan of the solutions given because you have to modify the UI and having a web frontend UI is the whole reason for the Eel library.

From the JS side we have the filename, last modified date, and file size in bytes. You can search filesystem on Python side for name match and weed out duplicates based on modified date & file size. Alternatively, you can calculate a checksum hash from the base64 file data on JS side and use that for searching on Python side. I'll implement this and post here for those interested. I can't imagine the run time is going to be great.

Edit: I implemented this two ways:

  1. When the file is selected on HTML side, call readAsArrayBuffer and send the byte array as a variable to python via eel exposed function that is then saved to a temporary file and therefore you know the path. Downsides: redundant data. Takes a LONG time for the data to be passed to Python even for files < 1MB.
  2. The solution I thought of above, doing a file search on Python side. It's also way too slow, even on my SSD and using heuristics for search locations.

I'll try setting electron as the client-side browser and maybe I can get access to the file path field it attaches as @ChrisKnott
suggested and report back.

Edit 2: following #57 and the Electron-Eel minimal example I was able to get Electron up and running as my client with Eel. All <input type="file"> now have a path variable attached to them with the absolute path. A little bit of setup but works great and no hacky solutions necessary. This is the way to go 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants