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.
Robocopy entire photo directory to NAS?
-
@margusch here, little quick and dirty, but tested, script
from ftplib import FTP from objc_util import * import photos # get photos from NAS user = 'admin' pwd = '...' ip = '192.168.0.47' ftp = FTP(ip) # Connect NAS ftp.encoding = 'utf-8' ftp.login(user,pwd) remote_folder = 'Photos/' filesnas= ftp.nlst(remote_folder+'*') # get photos from camera roll for asset in photos.get_assets(): fname = str(ObjCInstance(asset).valueForKey_('filename')) if (remote_folder+fname) not in filesnas: b = asset.get_image_data(original=False) # file as io.BytesIO ftp.storbinary('STOR '+remote_folder+fname, b,blocksize=32768) print('sent:',fname) ftp.quit() # Disconnect
-
@margusch said:
I will try FileBrowser Pro and PhotoSync and if they are working fine I will go with one of that.
Compare the prices but if you know Python, you'll have a lot of fun with Pythonista for solving new ideas.
-
user = 'admin' pwd = '...' ip = '192.168.0.47' ftp = FTP(ip) # Connect NAS ftp.encoding = 'utf-8' # … ftp.quit() # Disconnect # —> with FTP(host='192.168.0.47', user='admin', passwd='…', encoding='utf-8') as ftp:
-
@ccc I didn't know that the quit was not mandatory. Anyway, nicer as usual.
-
@ccc thus, even ftp.login(..) is not necessary
-
@ccc said:
with FTP(host='192.168.0.47', user='admin', passwd='…', encoding='utf-8') as ftp:
encoding not a parameter of FTP.init, thus
from ftplib import FTP from objc_util import * import photos with FTP(host='192.168.0.47', user='admin', passwd='...') as ftp: ftp.encoding='utf-8' # get photos from NAS remote_folder = 'Photos/' filesnas= ftp.nlst(remote_folder+'*') # get photos from camera roll for asset in photos.get_assets(): fname = str(ObjCInstance(asset).valueForKey_('filename')) if (remote_folder+fname) not in filesnas: b = asset.get_image_data(original=False) # file as io.BytesIO ftp.storbinary('STOR '+remote_folder+fname, b,blocksize=32768) print('sent:',fname)
-
Python < 3.9 did not have an
encoding
parameter: https://docs.python.org/3.8/library/ftplib.html#ftplib.FTP but was added in Py3.9 -
@margusch: "build a application which gets triggered via shortcuts daily"
Good to note that it will (probably) not happen in the background on a locked device, so this would in effect be more like a reminder and an easier way for you to start the process.
-
@mikael said:
Good to note that it will (probably) not happen in the background on a locked device
I think that the shortcut runs in the background of a locked device (don't remember if I had tested) but if the shortcut launchs an app, this one would not, excepted perhaps if Pyto in background mode, not tested.
-
@mikael but perhaps could you SFTP a file to the NAS via the SSH action of shortcut....
-
@mikael I had tested background in locked device for this topic
-
@cvp, thanks, really nice if so. I remember some of my earlier attempts being somewhat hit and miss.
-
So far this is the code that I'm using uploading with Synology REST API. It works well until Pythonista crashes when uploading photos between 900-1000.
import appex import photos import requests import os import editor import sys from objc_util import * from datetime import datetime class Synology(object): def __init__(self, url, port, account, passwd): """ :param url: IP/URL or Synology. So far it only supports HTTP. :param port: :param account: :param passwd: :returnv: """ self.url = url self.port = port self.account = account self.passwd = passwd self.sid = None # self.session = requests.Session() def login(self): print("Logging in...") param = { "version": "2", "method": "login", "account": self.account, "passwd": self.passwd, "session": "FileStation", "format": "cookie" } url = f"http://{self.url}:{self.port}/webapi/auth.cgi?api=SYNO.API.Auth" r = requests.get(url, param, verify=False) r = r.json() if not r["success"]: raise Exception("Authenticatoin failed. Note that account with 2FA enabled does not work.") print("Logging successful.") self.sid = r["data"]["sid"] return self.sid def upload_file(self, files): upload_url = f"http://{self.url}:{self.port}/webapi/entry.cgi?api=SYNO.FileStation.Upload&version=2&method=upload&_sid={self.sid}" args = { "path": "/home/b", "create_parents": "true", "overwrite": "true" } # Ignore this ugly code. I am trying to figure out if I can do bulk upload in one request. file = {'file': (files[0]["fname"], files[0]["payload"], 'application/octet-stream')} # file = [('files', (x["fname"], x["payload"], "application/octet-stream")) for x in files] r = requests.post(upload_url, data=args, files=file, verify=False) def main(): # if not appex.is_running_extension(): # print("Sript is intended to be un from sharing extension.") # return print("Starting...") s = Synology(url="1.1.1.1", port="2000", account="user", passwd="pass") s.login() startTime = datetime.now() all_photos = photos.get_assets() images = [] for idx, asset in enumerate(all_photos): if idx % 10 == 0: print(f"Uploading... {idx}/{len(all_photos)}") fname = str(ObjCInstance(asset).valueForKey_('filename')) payload = asset.get_image_data(original=True) images = [{"fname": fname, "payload": payload}] s.upload_file(images) # print(fname) print(datetime.now() - startTime) if __name__ == "__main__": main()