Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Upload any files from Any App via Pythonista Script to my Raspberry Pi connected Harddisk
-
Hi All,
I am a newbie for Pythonista and stopped using it for a few months (just due to busy work). I would like to see if I can make a script to upload file from my iPad in any apps to my Raspberry Pi connected harddisk. I would like to know if it is possible to use the Share Sheet from any apps to invoke this Pythonista script to upload the file to my raspberry?
I can upload the file to my Raspberry through SFTP. Should I use the module "paramiko" to do it? Can I transfer the file byte by byte or I need to wait the original app to transfer the whole file to Pythonista so that I can upload to my raspberry? Can anyone give me some clues? Thanks a lot.
-
This very little script does exactly what you want:
- from any app which can share a file
- share
- Run Pythonista script
- either you have already configured this script or you select it in 'All scripts'
- and the file will be uploaded to your FTP server
# coding: utf-8 import appex import console import os import ui from ftplib import FTP def main(): # Sharing: receive file fil = appex.get_file_path() if fil == None: print('no file passed') return server = 'Your ip' user = 'Your user' pwd = 'your password' server_file = os.path.basename(fil) try: ftp = FTP(server) #connect ftp.encoding = 'utf-8' ftp.login(user,pwd) ipad_file = open(fil,'rb') ftp.storbinary('STOR '+server_file,ipad_file,blocksize=8192) ipad_file.close() ftp.close() except Exception as e: print(str(e)) appex.finish() if __name__ == '__main__': main()
-
I have the same kinda script except mine uses SFTP to upload.
-
Thanks a lot @cvp ! I will try to modify using SFTP.
Hi @scj643, should I use the following method?
putfo(fl, remotepath, file_size=0, callback=None, confirm=True)
Copy the contents of an open file object (fl) to the SFTP server as remotepath. Any exception raised by operations will be passed through.The SFTP operations use pipelining for speed.
Parameters:
fl – opened file or file-like object to copy
remotepath (str) – the destination path on the SFTP server
file_size (int) – optional size parameter passed to callback. If none is specified, size defaults to 0
callback (callable) – optional callback function (form: func(int, int)) that accepts the bytes transferred so far and the total bytes to be transferred (since 1.7.4)
confirm (bool) – whether to do a stat() on the file afterwards to confirm the file size (since 1.7.7)
Returns:
an SFTPAttributes object containing attributes about the given file. -
# coding: utf-8 import appex import console import os import ui import paramiko from io import BytesIO def UploadCallBack(tran_bytes, total_bytes): print("Bytes Transferred:" +tran_bytes + "\nTotal Bytes:" + total_bytes) def main(): # Sharing: receive file input_file = appex.get_file_path() if input_file == None: print('no file passed') return # SFTP Configuration host = '192.168.1.x' port = 22 password = 'password' username = 'Username' remoteFilePath = '/media/sda/' server_file = os.path.basename(input_file) filesize = os.path.getsize(input_file) # print("server_file:" + server_file) print("Starting to upload the file:" + input_file + "(Size: ", end='') print(filesize, end='') print(")... ") try: transport = paramiko.Transport((host, port)) transport.connect(username = username, password = password) sftp = paramiko.SFTPClient.from_transport(transport,max_packet_size=8*1024*1024) ''' sftp.open() while with open(input_file, 'rb') as ipad_file: read(ipad_file, ) ''' #sftp.putfo(ipad_file, remoteFilePath + server_file, callback=UploadCallBack(int, int )) ipad_file = open(input_file, 'rb') sftp.putfo(ipad_file, remoteFilePath + server_file) ipad_file.close() sftp.close() transport.close() print('Upload done!') except Exception as e: print(str(e)) appex.finish() if __name__ == '__main__': main()```
-
This is my script. It works but slow as hell (maybe 40kb/s). Any suggestions? I would like to show the progress of upload too but can't figure out how to use the callback yet...
-
That's how I do
# coding: utf-8 import appex import console import os import ui from ftplib import FTP class MyView(ui.View): global file_path,loc_dir,books,lus_sur_ipad,authors_without_book def __init__(self,w,h): self.width = w self.height = h # Message Label for my_hud_alert msg = ui.Label(name='msg_label') msg.frame = (50,50,w-2*50,40) msg.background_color=(0.00, 0.50, 1.00, 0.5) msg.bg_color = 'bisque' msg.alignment = ui.ALIGN_CENTER msg.font= ('Courier-Bold',20) msg.hidden = True self.add_subview(msg) # progressbar progress_bar = ui.Label(name='progress_bar', flex='') progress_bar.background_color=(0.00, 0.50, 1.00, 0.5) progress_bar.bg_color=(0.00, 0.50, 1.00, 0.5) progress_bar.hidden = True self.add_subview(progress_bar) def will_close(self): appex.finish() def callback(p): # only one system parameter = buffer sent/receive global my_ui_view,total_file_size,transmit_file_size transmit_file_size = transmit_file_size + len(p) if my_ui_view['progress_bar'].hidden: my_ui_view['progress_bar'].x = my_ui_view['msg_label'].x my_ui_view['progress_bar'].y = my_ui_view['msg_label'].y my_ui_view['progress_bar'].height = my_ui_view['msg_label'].height my_ui_view['msg_label'].hidden = False my_ui_view['progress_bar'].hidden = False my_ui_view['progress_bar'].bring_to_front() my_ui_view['progress_bar'].width = my_ui_view['msg_label'].width * (transmit_file_size/total_file_size) if transmit_file_size == total_file_size: my_ui_view['msg_label'].hidden = True # hide msg my_ui_view['progress_bar'].hidden = True # hide progress bar def main(): global my_ui_view,total_file_size,transmit_file_size w, h = (540,620) disp_mode = 'sheet' my_ui_view = MyView(w,h) my_ui_view.background_color='white' my_ui_view.name = 'Upload' my_ui_view.present(disp_mode,hide_title_bar=False) # Sharing: receive file fil = appex.get_file_path() if fil == None: print('no file passed') return server = 'Xxxxx' user = 'Xxxxx' pwd = 'xxxx' server_file = os.path.basename(fil) my_ui_view['msg_label'].text =server_file try: ftp = FTP(server) #connect ftp.encoding = 'utf-8' ftp.login(user,pwd) ipad_file = open(fil,'rb') transmit_file_size = 0 total_file_size = os.path.getsize(fil) ftp.storbinary('STOR '+server_file,ipad_file,blocksize=8192,callback=callback) ipad_file.close() ftp.close() except Exception as e: print(str(e)) if __name__ == '__main__': main()
-
It works very well. Thanks a lot!