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()