anime-downloader/anime_downloader/downloader/base_downloader.py

91 lines
2.6 KiB
Python
Raw Normal View History

2018-07-27 11:52:21 -07:00
import os
import time
import logging
import sys
from anime_downloader import util
from anime_downloader import session
2018-07-27 11:52:21 -07:00
import requests
logger = logging.getLogger(__name__)
2018-07-27 11:52:21 -07:00
class BaseDownloader:
2020-03-27 06:50:08 -07:00
def __init__(self, source, path, force, range_size, callback=None):
2018-07-27 11:52:21 -07:00
self.chunksize = 16384
2019-05-22 10:04:27 -07:00
self._total_size = None
2020-03-27 06:50:08 -07:00
self.source = source
self.path = path
# these should be included in a options dict, maybe
self.force = force
self.range_size = range_size
if callback is None:
callback = write_status
self.callback = callback
2018-07-27 11:52:21 -07:00
2019-05-08 11:17:30 -07:00
def check_if_exists(self):
# Added Referer Header as kwik needd it.
headers = self.source.headers
if 'user-agent' not in headers:
headers['user-agent'] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101Firefox/56.0"
2020-03-27 06:50:08 -07:00
if self.source.referer:
headers['referer'] = self.source.referer
# using session downloads the whole file, essentially freezing the program.
r = requests.get(
2020-03-27 06:50:08 -07:00
self.source.stream_url, headers=headers, stream=True)
2018-07-27 11:52:21 -07:00
2019-05-22 10:04:27 -07:00
self._total_size = int(r.headers['Content-length'])
2020-03-27 06:50:08 -07:00
logger.debug('total size: ' + str(self._total_size))
2019-05-08 11:17:30 -07:00
if os.path.exists(self.path):
2019-05-22 10:04:27 -07:00
if abs(os.stat(self.path).st_size - self._total_size) < 10 \
2020-03-27 06:50:08 -07:00
and not self.force:
logger.warning('File already downloaded. Skipping download.')
2018-07-27 11:52:21 -07:00
return
else:
2019-05-08 11:17:30 -07:00
os.remove(self.path)
2018-07-27 11:52:21 -07:00
2020-03-27 06:50:08 -07:00
def download(self):
2019-05-22 10:04:27 -07:00
# TODO: Clean this up
2018-07-27 11:52:21 -07:00
self.pre_process()
2020-03-27 06:50:08 -07:00
logger.info(self.path)
2019-05-08 11:17:30 -07:00
# TODO: Use pathlib. Break into functions
2020-03-27 06:50:08 -07:00
util.make_dir(self.path.rsplit('/', 1)[0])
2019-05-08 11:17:30 -07:00
self.check_if_exists()
2018-07-27 11:52:21 -07:00
self.start_time = time.time()
self.downloaded = 0
self._download()
self.post_process()
def _download(self):
raise NotImplementedError
def pre_process(self):
pass
def post_process(self):
pass
def report_chunk_downloaded(self):
self.downloaded += self.chunksize
2020-03-27 06:50:08 -07:00
self.callback(self.downloaded, self._total_size, self.start_time)
2018-07-27 11:52:21 -07:00
def write_status(downloaded, total_size, start_time):
elapsed_time = time.time()-start_time
rate = (downloaded/1024)/elapsed_time if elapsed_time else 'x'
downloaded = float(downloaded)/1048576
total_size = float(total_size)/1048576
status = 'Downloaded: {0:.2f}MB/{1:.2f}MB, Rate: {2:.2f}KB/s'.format(
downloaded, total_size, rate)
sys.stdout.write("\r" + status + " "*5 + "\r")
sys.stdout.flush()