c87839f604f7f8f982a98129a33dbfbb45feedc5
2 # Copyright 2016 RIFT.IO Inc
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # Author(s): Varun Prasad
17 # Creation Date: 09/25/2016
27 class InvalidDestinationError(Exception):
31 class DownloaderProtocol
:
32 """Listener of this class can implement the following method to get a
35 def on_download_started(self
, job
):
36 """Called when the download starts
39 job (DownloadJob): Yang Model
44 def on_download_progress(self
, job
):
45 """Called after each chunk is downloaded
48 job (DownloadJob): Yang Model
53 def on_download_succeeded(self
, job
):
54 """Called when the download is completed successfully
57 job (DownloadJob): Yang Model
62 def on_download_failed(self
, job
):
63 """Called when the download fails
66 job (DownloadJob): Yang Model
71 def on_download_cancelled(self
, job
):
72 """Called when the download is canceled
75 job (DownloadJob): Yang Model
80 def on_download_finished(self
, job
):
81 """Called when the download finishes regardless of the status of the
82 download (success, failed or canceled)
85 job (DownloadJob): Yang Model
91 class DownloadStatus(enum
.Enum
):
100 """Model data used by the downloader.
102 def __init__(self
, url
, dest_file
):
104 self
.filepath
= dest_file
105 self
.download_id
= str(uuid
.uuid4())
107 self
.progress_percent
= 0
108 self
.bytes_downloaded
= 0
109 self
.bytes_per_second
= 0
118 return os
.path
.basename(self
.filepath
)
120 def start_download(self
):
121 self
.start_time
= time
.time()
123 def end_download(self
):
124 self
.end_time
= time
.time()
126 def set_state(self
, state
):
129 def update_with_data(self
, downloaded_chunk
):
130 self
.bytes_downloaded
+= len(downloaded_chunk
)
132 if self
.bytes_total
!= 0:
133 self
.progress_percent
= \
134 int((self
.bytes_downloaded
/ self
.bytes_total
) * 100)
137 seconds_elapsed
= time
.time() - self
.start_time
138 self
.bytes_per_second
= self
.bytes_downloaded
// seconds_elapsed
140 def update_data_with_head(self
, headers
):
141 """Update the model from the header of HEAD request
144 headers (dict): headers from HEAD response
146 if 'Content-Length' in headers
:
147 self
.bytes_total
= int(headers
['Content-Length'])
153 class AbstractDownloader
:
156 self
._delegate
= None
160 return self
._delegate
163 def delegate(self
, delegate
):
164 self
._delegate
= delegate
166 @abc.abstractproperty
167 def download_id(self
):
171 def cancel_download(self
):