CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/cameras_gimbals/siyi-download/siyi-download.py
Views: 1799
1
#!/usr/bin/env python3
2
3
"""
4
Downloads files from a Siyi camera connected via ethernet
5
6
AP_FLAKE8_CLEAN
7
"""
8
9
#
10
# utility to download files from a siyi camera
11
#
12
13
import os
14
import json
15
from argparse import ArgumentParser
16
from urllib.request import urlopen, urlretrieve
17
from urllib.parse import urlencode
18
from urllib.error import URLError, HTTPError
19
from enum import Enum
20
21
# prefix string for text outout to user
22
prefix_str = "siyi-download.py: "
23
ip_address_default = "192.168.144.25"
24
25
26
# media types
27
class MediaTypes(Enum):
28
IMAGE = 0
29
VIDEO = 1
30
31
32
# media type strings. used to display to user
33
MEDIA_TYPE_STR = ["image", "video"]
34
35
36
# get URL for list of directories
37
def get_dirlist_url(ip_address, media_type):
38
params = {'media_type': media_type}
39
return f"http://{ip_address}:82/cgi-bin/media.cgi/api/v1/getdirectories?" + urlencode(params)
40
41
42
# get URL for list of files in a directory
43
def get_filelist_url(ip_address, media_type, dir_path):
44
params = {
45
'media_type': str(media_type),
46
'path': dir_path,
47
'start': 0,
48
'count': 999
49
}
50
return f"http://{ip_address}:82/cgi-bin/media.cgi/api/v1/getmedialist?" + urlencode(params)
51
52
53
# download files from camera
54
def download_files(ip_address, dest_dir):
55
56
# repeat for images and videos
57
for media_type in [mt.value for mt in MediaTypes]:
58
59
# display output to user
60
print(prefix_str + f"downloading {MEDIA_TYPE_STR[media_type]} files")
61
62
# download list of directories in JSON format
63
dir_list_url = get_dirlist_url(ip_address, media_type)
64
with urlopen(dir_list_url) as get_dir_url:
65
dir_dict = json.load(get_dir_url)
66
67
# check that the request succeeded
68
if (not dir_dict['success']):
69
exit(prefix_str + "failed to get list of directories")
70
71
# check response includes 'data'
72
if ('data' not in dir_dict.keys()):
73
exit(prefix_str + "could not get list of directories, no 'data' in response")
74
dir_dict_data = dir_dict['data']
75
76
# check response includes 'directories'
77
if ('directories' not in dir_dict_data.keys()):
78
exit(prefix_str + "could not get list of directories, no 'directories' in response")
79
dir_dict_data_directories = dir_dict_data['directories']
80
81
# create list of directories from 'path' values
82
dir_list = []
83
for dir in dir_dict_data_directories:
84
if ('path' in dir.keys()):
85
dir_list.append(dir['path'])
86
print(prefix_str + f"{len(dir_list)} directories")
87
88
# get list of files in each directory
89
for dir_path in dir_list:
90
filenames_url = get_filelist_url(ip_address, media_type, dir_path)
91
with urlopen(filenames_url) as get_filenames_url:
92
filename_dict = json.load(get_filenames_url)
93
94
# check that the request succeeded
95
if (not filename_dict['success']):
96
exit(prefix_str + "failed to get list of files")
97
98
# check response includes 'data'
99
if ('data' not in filename_dict.keys()):
100
exit(prefix_str + "could not get list of files, no 'data' in response")
101
filename_dict_data = filename_dict['data']
102
103
# check response includes 'list'
104
if ('list' not in filename_dict_data.keys()):
105
exit(prefix_str + "could not get list of files, no 'list' in response")
106
filename_dict_data_list = filename_dict_data['list']
107
print(prefix_str + f"{len(filename_dict_data_list)} files")
108
109
# download each image
110
for fileinfo in filename_dict_data_list:
111
if ('name' not in fileinfo.keys() or 'url' not in fileinfo.keys()):
112
exit(prefix_str + "could not get list of files, no 'name' or 'url' in response")
113
filename = fileinfo['name']
114
file_url = fileinfo['url']
115
116
# correct incorrect ip address in returned url
117
file_url_fixed = file_url.replace(ip_address_default, ip_address)
118
119
# download file
120
print(prefix_str + f"downloading {filename} from {file_url_fixed}")
121
dest_filename = os.path.join(dest_dir, filename)
122
try:
123
urlretrieve(file_url_fixed, dest_filename)
124
except (URLError, HTTPError) as e:
125
print(prefix_str + f"failed to download {filename}: {e}")
126
127
128
# main function
129
def main():
130
parser = ArgumentParser(description=__doc__)
131
parser.add_argument("--ipaddr", default=ip_address_default, help="IP address of camera")
132
parser.add_argument("--dest", default=".", help="destination directory where downloaded files will be saved")
133
args = parser.parse_args()
134
135
# check destination directory exists
136
if not os.path.exists(args.dest):
137
exit(prefix_str + "invalid destination directory")
138
139
# download files
140
download_files(args.ipaddr, args.dest)
141
142
143
# main
144
if __name__ == "__main__":
145
main()
146
147