1
mirror of https://github.com/home-assistant/core synced 2024-08-25 01:22:25 +02:00

Downloader downloads file in seperate thread now so it doesn't block bus queue

This commit is contained in:
Paulus Schoutsen 2014-02-14 11:57:42 -08:00
parent c735e32361
commit 4ab362531f

View File

@ -7,6 +7,7 @@ Provides functionality to download files.
import os import os
import logging import logging
import re import re
import threading
import homeassistant.util as util import homeassistant.util as util
@ -15,6 +16,7 @@ DOMAIN = "downloader"
SERVICE_DOWNLOAD_FILE = "download_file" SERVICE_DOWNLOAD_FILE = "download_file"
# pylint: disable=too-many-branches
def setup(bus, download_path): def setup(bus, download_path):
""" Listens for download events to download files. """ """ Listens for download events to download files. """
@ -36,53 +38,68 @@ def setup(bus, download_path):
return False return False
def _download_file(service): def download_file(service):
""" Downloads file specified in the url. """ """ Starts thread to download file specified in the url. """
try: if not 'url' in service.data:
req = requests.get(service.data['url'], stream=True) logger.error("Service called but 'url' parameter not specified.")
if req.status_code == 200: return
filename = None
if 'content-disposition' in req.headers: def do_download():
match = re.findall(r"filename=(\S+)", """ Downloads the file. """
req.headers['content-disposition']) try:
url = service.data['url']
req = requests.get(url, stream=True)
if len(match) > 0: if req.status_code == 200:
filename = match[0].strip("'\" ") filename = None
if not filename: if 'content-disposition' in req.headers:
filename = os.path.basename(service.data['url']).strip() match = re.findall(r"filename=(\S+)",
req.headers['content-disposition'])
if not filename: if len(match) > 0:
filename = "ha_download" filename = match[0].strip("'\" ")
# Remove stuff to ruin paths if not filename:
filename = util.sanitize_filename(filename) filename = os.path.basename(
url).strip()
path, ext = os.path.splitext(os.path.join(download_path, if not filename:
filename)) filename = "ha_download"
# If file exist append a number. We test filename, filename_2.. # Remove stuff to ruin paths
tries = 1 filename = util.sanitize_filename(filename)
final_path = path + ext
while os.path.isfile(final_path):
tries += 1
final_path = path + "_{}".format(tries) + ext path, ext = os.path.splitext(os.path.join(download_path,
filename))
logger.info("{} -> {}".format( # If file exist append a number.
service.data['url'], final_path)) # We test filename, filename_2..
tries = 1
final_path = path + ext
while os.path.isfile(final_path):
tries += 1
with open(final_path, 'wb') as fil: final_path = path + "_{}".format(tries) + ext
for chunk in req.iter_content(1024):
fil.write(chunk)
except requests.exceptions.ConnectionError: logger.info("{} -> {}".format(
logger.exception("ConnectionError occured for {}". url, final_path))
format(service.data['url']))
with open(final_path, 'wb') as fil:
for chunk in req.iter_content(1024):
fil.write(chunk)
logger.info("Downloading of {} done".format(
url))
except requests.exceptions.ConnectionError:
logger.exception("ConnectionError occured for {}".
format(url))
threading.Thread(target=do_download).start()
bus.register_service(DOMAIN, SERVICE_DOWNLOAD_FILE, bus.register_service(DOMAIN, SERVICE_DOWNLOAD_FILE,
_download_file) download_file)
return True return True