tfatool
tfatool copied to clipboard
Delete files on FlashAir
Hi,
Can I delete the files on FlashAir?
Hey @hntuan94, try out the branch in pull request #9 for the ability to delete from the command line. It hasn't been merged because it's not fully tested, so if you can test it with a FlashAir device we can merge it!
Hi @TadLeonard ,
-
Before testing the delete function I already tried using CGI on the web browser and got the following error: Command: http://flashair/upload.cgi?DEL=/DCIM/100__TSB/EK000003.JPG Response: 500 Server Error The server encountered an internal error and could not complete your request.
-
Reference: https://flashair-developers.com/en/documents/api/uploadcgi/
-
I don't know if the new firmware does not allow to delete remotely. Any idea?
Hi @TadLeonard ,
Simple modification I could delete file using CGI. I'll test the delete function and let you know soon. In the /SD_WLAN/ folder open the CONFIG file with notepad or a text editor and add 'UPLOAD=1' into config file. https://shop.prusa3d.com/forum/user-mods-octoprint-enclosures-nozzles--f65/flashair-wifi-sd-card-setup-and-drive-mapping-t13693.html
Hey @hntuan94, yeah that UPLOAD=1
thing is an annoying feature. I suppose it's for security, but the device is not secure to begin with.
Hi @TadLeonard ,
I found an issue with delete function.
def delete_file(remote_file: str, url=URL):
response = get(url=url, **{Upload.delete: remote_file})
if response.status_code != 200:
raise UploadError("Failed to delete file", response)
return response
It seems that you have not added the DEFAULT_REMOTE_DIR. So when I run the test the request output is shown below:
http://flashair/upload.cgi?DEL=EK000001.JPG
If I add the DEFAULT_REMOTE_DIR It will work well.
upload.delete_file("=/DCIM/100__TSB/EK000006.JPG")
Hey @hntuan94,
That's a good idea. Another way to solve this would be to use the branch in pull request #13. The branch solves these problems by having all functions take a Session
, which contains this info:
class _Session(NamedTuple):
url: str = URL # device URL (http://flashair by default)
remote_dir: str = DEFAULT_REMOTE_DIR # /DCIM/100__TSB by default
local_dir: str = "." # local directory for sychronizing files
filters: Tuple[Callable] = ()
This means that we could rewrite the delete_file function to join Session.remote_dir
with the remote_file
argument.
The reason I haven't merged #13 is because I can't test it. If you are able to make the changes you need to delete_file
and test them, it'd be great to merge this and cut a new release.
Regards, Tad
To be clear, the way we might solve it is to make (and test) this adjustment in the session
branch:
Take this function as it is currently defined:
def delete_file(remote_file: str, session: Session = Session()):
response = get(url=url, **{Upload.delete: remote_file)
if response.status_code != 200:
raise UploadError("Failed to delete file", response)
return response
...and make some small changes like this:
import pathlib # near the top of the file
...
def delete_file(remote_file: str, session: Session = Session()):
remote_file = pathlib.PurePosixPath(session.remote_dir, remote_file)
response = get(url=url, **{Upload.delete: str(remote_file))
if response.status_code != 200:
raise UploadError("Failed to delete file", response)
return response
That's great. I modified your function a little and it works.
def delete_file(remote_file: str, session: Session = Session()):
remote_file = pathlib.PurePosixPath(session.remote_dir, remote_file)
response = get(url=session.url, **{Upload.delete: str(remote_file)})
if response.status_code != 200:
raise UploadError("Failed to delete file", response)
return response
The response's [200] even thought I delete an unavailable file. Any idea?
<Response[200]>
I tried the CGI if there's no file the response will be NG
The response's [200] even thought I delete an unavailable file. Any idea? <Response[200]>
I tried the CGI if there's no file the response will be NG
Hmm, this is very strange. Do you get any useful log messages when this happens? Maybe we can compare the full CGI URL used against the URL you tested manually.
In order to raise the error. May we use response.text
instead of response.status_code
How you do think of?
Ref: https://stackoverflow.com/questions/40488882/pythons-request-get-only-show-200-status
The response of CGI is below: SUCCESS NG
In order to raise the error. May we use response.status_code instead of response.status_code How you do think of?
Oh, do you mean that we should use the text
instead of the status code? I think that makes sense. From the docs it seems we could make the check be this:
if response.text != "SUCCESS":
raise UploadError(...)
Actually even better would be this:
if response.text != info.ResponseCode.success:
raise ...
Yeah! I did it :)
Great! Please feel free to make a PR with those changes. I can then merge it into session
. Also, if you can run the functional tests with your FlashAir device connected (and if they pass) I'll make a new release and tfatool
will be much better off!
Hi @TadLeonard ,
We can use delete function from now on. Do we need to support deleting folder? or close the issue?
Many thanks for your support.
Do we need to support deleting folder? or close the issue?
I think it's probably best to leave that up to the user (for now). It seems like folders are tricky on FlashAir. You may have read this in their docs already, but if you attempt deleting a folder without deleting the files inside it first you'll never be able to recover the files again! They'll just sit around taking up space, yet they'll be unreadable and undeletable. Scary.
I ordered another FlashAir device a few hours ago, so in a week I'll finally be able to test on my own. Then I can make a new release and you'll be able to pip install
the changes you've suggested.
If you want a release earlier, you can help out by running the functional tests and pushing a few PRs. Otherwise we'll get these improvements released to pip
eventually anyway.
Thank you very much for your help in identifying these problems, @hntuan94!
I ordered another FlashAir device a few hours ago, so in a week I'll finally be able to test on my own. Then I can make a new release and you'll be able to
pip install
the changes you've suggested.If you want a release earlier, you can help out by running the functional tests and pushing a few PRs. Otherwise we'll get these improvements released to
pip
eventually anyway.Thank you very much for your help in identifying these problems, @hntuan94!
I'm waiting for your new one. Once again, thank you very much for your contribution.
Why not using:
if response.code != info.ResponseCode:
I always recommend to compare numbers in these cases instead of strings :raising_hand: However, that might be my own style of coding :wink: