Вот сокращенная версия обработчика, который закрывает соединение сразу после загрузки:
Код: Выделить всё
import os, logging, paramiko
class SFTPFileHandle(paramiko.SFTPHandle):
def __init__(self, flags, upload_file, file_name, file_path, rename_file) -> None:
super().__init__(flags)
self.upload_file = upload_file
self.file_name = file_name
self.file_path = file_path
self.rename_file = rename_file
def chattr(self, path, attr):
pass
def stat(self):
return paramiko.SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))
def close(self):
try:
super().close()
try:
exists = os.path.exists(self.file_path)
size = os.path.getsize(self.file_path) if exists else -1
logging.info(f"[Close] path='{self.file_path}' exists={exists} size={size}")
except Exception as e:
logging.warning(f"[Close] stat failed for '{self.file_path}': {e}")
fname = self.rename_file(file_name=self.file_name, file_path=self.file_path)
if fname:
if fname == "camera_off":
try:
os.remove(self.file_path)
logging.info("[Cleanup] removed local file (camera_off)")
except Exception as e:
logging.warning(f"[Cleanup] remove failed: {e}")
else:
ok = self.upload_file(fname, self.file_path)
if ok:
try:
os.remove(self.file_path)
logging.info("[Cleanup] removed local file after upload")
except Exception as e:
logging.warning(f"[Cleanup] remove failed after upload: {e}")
else:
logging.error("[Close] upload failed")
else:
logging.error("[Close] failed to build final name")
except Exception:
logging.exception("[Close] error while finalizing")
Это говорит о том, что мой клиент не получил явного сигнала об успешном завершении...
PS: Если кому-то интересно, как и мне самому, к сожалению, нет, невозможно получить доступ к журналам на NVR, чтобы увидеть, что происходит после завершения загрузки. Сетевые видеорегистраторы представляют собой картофельные камеры, практически не имеющие управления, со встроенным программным обеспечением, которое позволяет изменять только DNS SFTP-сервера, и никаких других опций нет.
Подробнее здесь: https://stackoverflow.com/questions/797 ... ad-in-clos
Мобильная версия