Last active
December 21, 2020 08:58
-
-
Save jerameel/d457f864e33b7d20d16dec42bfecb387 to your computer and use it in GitHub Desktop.
A python script to automatically backup Yi Hack camera into an FTP server.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3.7 | |
import sys | |
import time | |
from datetime import datetime,timedelta | |
from ftplib import FTP | |
from urllib.request import urlretrieve | |
DEBUG = True | |
FTP_HOST = "192.168.X.X" | |
FTP_DEFAULT_FOLDER = 'Data' | |
CAMERA_IPs = ['192.168.X.X', '192.168.X.X'] | |
MAX_SAVED_DAYS = 3 | |
SYNC_MINUTE_INTERVAL = 15 | |
def log(message): | |
if DEBUG: | |
print(message, flush=True) | |
def generate_download_url(camera_ip, target_date): | |
record_url = f"http://{camera_ip}:8080/record" | |
target_year = target_date.year | |
target_month = target_date.strftime("%m") | |
target_day = target_date.strftime("%d") | |
target_hour = target_date.strftime("%H") | |
target_minute = target_date.strftime("%M") | |
return f"{record_url}/{target_year}Y{target_month}M{target_day}D{target_hour}H/{target_minute}M00S60.mp4" | |
def download_file(url, filename): | |
try: | |
urlretrieve(url, filename) | |
return True | |
except Exception as e: | |
log(e) | |
return False | |
def get_tmp_filename(camera_index, index): | |
return f'/tmp/cam{camera_index}_tmp{index}.mp4' | |
def get_ouput_filename(target_date): | |
target_year = target_date.year | |
target_month = target_date.strftime("%m") | |
target_day = target_date.strftime("%d") | |
target_hour = target_date.strftime("%H") | |
target_minute = target_date.strftime("%M") | |
return f"{target_year}{target_month}{target_day}-{target_hour}{target_minute}.mp4" | |
target_range = range(SYNC_MINUTE_INTERVAL) | |
last_sync = None | |
while True: | |
reference_date = datetime.now() - timedelta(minutes=SYNC_MINUTE_INTERVAL) | |
if not last_sync or ((reference_date - last_sync).total_seconds()) >= (60 * SYNC_MINUTE_INTERVAL): | |
last_sync = reference_date | |
for camera_index,camera_ip in enumerate(CAMERA_IPs): | |
for target in target_range: | |
target_url = generate_download_url(camera_ip, reference_date + timedelta(minutes=target)) | |
temp_file = get_tmp_filename(camera_index, target) | |
log(f'Downloading {target_url} as {temp_file}') | |
retry = 0 | |
while (not download_file(target_url, temp_file)): | |
if (retry < 3): | |
log('Trying again...') | |
time.sleep(1) | |
retry += 1 | |
else: | |
sys.exit(f'Failed to download {target_url} as {temp_file}') | |
log('File has been downloaded') | |
# connect to the FTP server | |
log('Establishing ftp connection...') | |
ftp = FTP(FTP_HOST) | |
ftp.login() | |
# force UTF-8 encoding | |
ftp.encoding = "utf-8" | |
# open default dir | |
ftp.cwd(FTP_DEFAULT_FOLDER) | |
# get reference datetime for deleting old files, format to int yyyymmddhhmm | |
reference_file = get_ouput_filename(reference_date) | |
current_datetime_reference = int(reference_file.replace('-', '').replace('.mp4', '')) | |
for camera_index,camera_ip in enumerate(CAMERA_IPs): | |
# Upload file to ftp | |
ftp.cwd(f"CAM{camera_index}") | |
for target in target_range: | |
temp_file = get_tmp_filename(camera_index, target) | |
output_file = get_ouput_filename(reference_date + timedelta(minutes=target)) | |
log(f'Uploading {temp_file} as {output_file} to CAM{camera_index}') | |
with open(temp_file, "rb") as file: | |
ftp.storbinary(f"STOR {output_file}", file) | |
log('File has been uploaded') | |
# delete old files | |
existing_files = ftp.nlst() | |
for existing_file in existing_files: | |
try: | |
# format to int yyyymmddhhmm, delete if difference is atleast three days | |
current_file_day = int(existing_file.replace('-', '').replace('.mp4', '')) | |
if (current_datetime_reference - current_file_day) >= 10000 * MAX_SAVED_DAYS: | |
log(f"Deleting {existing_file} from CAM{camera_index}") | |
ftp.delete(existing_file) | |
except: | |
# delete foreign file | |
log(f"Deleting {existing_file} from CAM{camera_index}") | |
ftp.delete(existing_file) | |
# reset working directory | |
ftp.cwd(f"../") | |
log('Closing ftp connection...') | |
ftp.quit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added support for auto deletion