Skip to content

Instantly share code, notes, and snippets.

@jerameel
Last active December 21, 2020 08:58
Show Gist options
  • Save jerameel/d457f864e33b7d20d16dec42bfecb387 to your computer and use it in GitHub Desktop.
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.
#!/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()
@jerameel
Copy link
Author

Added support for auto deletion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment