Path: blob/master/Tools/cameras_gimbals/xfrobot-download/xfrobot-download.py
4232 views
#!/usr/bin/env python312# flake8: noqa34"""5Downloads image and video files from an XFRobot camera connected via ethernet6"""78import os9import re10from argparse import ArgumentParser11from urllib.request import urlretrieve, urlopen12from urllib.error import URLError, HTTPError13from html.parser import HTMLParser1415# prefix string for output16prefix_str = "xfrobot-download.py: "17ip_address_default = "192.168.144.108"1819# directory suffixes20MEDIA_DIRS = {21"image": "IMG",22"video": "VID"23}2425# HTML parser to extract links from HTML pages26class LinkExtractor(HTMLParser):27def __init__(self):28super().__init__()29self.links = []3031def handle_starttag(self, tag, attrs):32if tag == 'a':33for attr in attrs:34if attr[0] == 'href':35self.links.append(attr[1])3637# extract file links from HTML page38def extract_file_links(base_url):39try:40with urlopen(base_url) as response:41html = response.read().decode('utf-8')42parser = LinkExtractor()43parser.feed(html)44return [link for link in parser.links if re.search(r'\.(jpg|jpeg|png|mp4|mov)$', link, re.IGNORECASE)]45except Exception as e:46print(prefix_str + f"Failed to fetch or parse URL {base_url}: {e}")47return []4849# download files from the given list of links50# returns the number of successfully downloaded files51def download_files(base_url, links, dest_dir):52count = 053for link in links:54filename = os.path.basename(link)55full_url = link if link.startswith("http") else base_url + filename56dest_path = os.path.join(dest_dir, filename)57print(prefix_str + f"Downloading {filename} from {full_url}")58try:59urlretrieve(full_url, dest_path)60count += 161except (URLError, HTTPError) as e:62print(prefix_str + f"Failed to download {filename}: {e}")63return count6465# main function66def main():67parser = ArgumentParser(description="Download files from an XFRobot camera")68parser.add_argument("--ipaddr", default=ip_address_default, help="IP address of camera")69parser.add_argument("--dest", default=".", help="Destination directory")70args = parser.parse_args()7172if not os.path.exists(args.dest):73print(prefix_str + "Invalid destination directory")74return7576for media_type, subdir in MEDIA_DIRS.items():77print(prefix_str + f"Fetching {media_type} files")78base_url = f"http://{args.ipaddr}/static/{subdir}/"79links = extract_file_links(base_url)80count = download_files(base_url, links, args.dest)81print(prefix_str + f"Downloaded {count} {media_type} file(s)")8283if __name__ == "__main__":84main()858687