download.py
Go to the documentation of this file.
1 # Copyright 2017 Mycroft AI Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15 from threading import Thread
16 
17 import os
18 import requests
19 from os.path import exists, dirname
20 import subprocess
21 
22 _running_downloads = {}
23 
24 
26  tmp_base = dest + '.part'
27  if not exists(tmp_base):
28  return tmp_base
29  else:
30  i = 1
31  while(True):
32  tmp = tmp_base + '.' + str(i)
33  if not exists(tmp):
34  return tmp
35  else:
36  i += 1
37 
38 
39 class Downloader(Thread):
40  """
41  Downloader is a thread based downloader instance when instanciated
42  it will download the provided url to a file on disk.
43 
44  When the download is complete or failed the `.done` property will
45  be set to true and the `.status` will indicate the status code.
46  200 = Success.
47 
48  Args:
49  url: Url to download
50  dest: Path to save data to
51  complet_action: Function to run when download is complete.
52  `func(dest)`
53  """
54 
55  def __init__(self, url, dest, complete_action=None, header=None):
56  super(Downloader, self).__init__()
57  self.url = url
58  self.dest = dest
59  self.complete_action = complete_action
60  self.status = None
61  self.done = False
62  self._abort = False
63  self.header = header
64 
65  # Create directories as needed
66  if not exists(dirname(dest)):
67  os.makedirs(dirname(dest))
68 
69  # Start thread
70  self.daemon = True
71  self.start()
72 
73  def perform_download(self, dest):
74 
75  cmd = ['wget', '-c', self.url, '-O', dest,
76  '--tries=20', '--read-timeout=5']
77  if self.header:
78  cmd += ['--header={}'.format(self.header)]
79  return subprocess.call(cmd)
80 
81  def run(self):
82  """
83  Does the actual download.
84  """
85  tmp = _get_download_tmp(self.dest)
86  self.status = self.perform_download(tmp)
87 
88  if not self._abort and self.status == 0:
89  self.finalize(tmp)
90  else:
91  self.cleanup(tmp)
92  self.done = True
93  arg_hash = hash(self.url + self.dest)
94 
95  # Remove from list of currently running downloads
96  if arg_hash in _running_downloads:
97  _running_downloads.pop(arg_hash)
98 
99  def finalize(self, tmp):
100  """
101  Move the .part file to the final destination and perform any
102  actions that should be performed at completion.
103  """
104  os.rename(tmp, self.dest)
105  if self.complete_action:
106  self.complete_action(self.dest)
107 
108  def cleanup(self, tmp):
109  """
110  Cleanup after download attempt
111  """
112  if exists(tmp):
113  os.remove(self.dest + '.part')
114  if self.status == 200:
115  self.status = -1
116 
117  def abort(self):
118  """
119  Abort download process
120  """
121  self._abort = True
122 
123 
124 def download(url, dest, complete_action=None, header=None):
125  global _running_downloads
126  arg_hash = hash(url + dest)
127  if arg_hash not in _running_downloads:
128  _running_downloads[arg_hash] = Downloader(url, dest, complete_action,
129  header)
130  return _running_downloads[arg_hash]
def __init__(self, url, dest, complete_action=None, header=None)
Definition: download.py:55
def download(url, dest, complete_action=None, header=None)
Definition: download.py:124
def perform_download(self, dest)
Definition: download.py:73
def _get_download_tmp(dest)
Definition: download.py:25


mycroft_ros
Author(s):
autogenerated on Mon Apr 26 2021 02:35:40