Add download from github.com/koenkk

Pythony naming
Signed-off-by: Daniel Demus <daniel-github@demus.dk>
This commit is contained in:
Daniel Demus 2022-10-04 00:01:06 +02:00
parent 7c4e3aa4a7
commit cadbbb8666
6 changed files with 70 additions and 39 deletions

View File

@ -7,7 +7,7 @@ from downloader import Downloader
class Danfoss(Downloader): class Danfoss(Downloader):
def getUrlList(self): def get_url_list(self):
res = [] res = []
page = parse(urlopen('https://files.danfoss.com/download/Heating/Ally/')).getroot() page = parse(urlopen('https://files.danfoss.com/download/Heating/Ally/')).getroot()
page.make_links_absolute('https://files.danfoss.com/download/Heating/Ally/') page.make_links_absolute('https://files.danfoss.com/download/Heating/Ally/')
@ -16,4 +16,3 @@ class Danfoss(Downloader):
res.append((link.get('href'), link.text_content())) res.append((link.get('href'), link.text_content()))
return res return res

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from abc import ABC, abstractmethod from abc import ABC, abstractmethod, abstractproperty
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from email.utils import parsedate_to_datetime from email.utils import parsedate_to_datetime
import os, requests, re, time import os, requests, re, time
@ -9,28 +9,28 @@ import shutil
class Downloader(ABC): class Downloader(ABC):
extensions = ('.ota', '.ota.signed', '.zigbee', '.fw2', '.sbl-ota') extensions = ('.ota', '.ota.signed', '.zigbee', '.fw2', '.sbl-ota')
archive_extensions = [ ext for sublist in [ x[1] for x in shutil.get_unpack_formats() ] for ext in sublist ]
def __init__(self): otau_path = os.path.join(os.path.expanduser('~/otau/'))
self.otauPath = os.path.expanduser('~/otau') log_path = os.path.join(otau_path, 'log.log')
@abstractmethod @abstractmethod
def getUrlList(self): def get_url_list(self):
pass pass
def performDownloads(self): def perform_downloads(self):
print("") print("")
print(f"Putting {self.__class__.__name__} updates in {self.otauPath}") print(f"Putting {self.__class__.__name__} updates in {self.otau_path}")
if not os.path.exists(self.otauPath): if not os.path.exists(self.otau_path):
os.makedirs(self.otauPath) os.makedirs(self.otau_path)
cnt = 0 cnt = 0
retries = self.getUrlList() retries = self.get_url_list()
delay = None delay = None
while cnt == 0 or (cnt < 50 and delay): while cnt == 0 or (cnt < 50 and delay):
retries, delay = self.handleDownloads(retries, delay) retries, delay = self.handle_downloads(retries, delay)
cnt += 1 cnt += 1
def handleDownloads(self, lst, delay): def handle_downloads(self, lst, delay):
retries = [] retries = []
if delay: if delay:
@ -48,18 +48,18 @@ class Downloader(ABC):
newDelay = None newDelay = None
for (url, filename) in lst: for (url, filename) in lst:
ret = self.downloadFile(url, filename, retries) ret = self.download_file(url, filename, retries)
if ret is None or isinstance(ret, datetime): if ret is None or isinstance(ret, datetime):
if ret is not None or newDelay is None or ret > newDelay: if ret is not None or newDelay is None or ret > newDelay:
newDelay = ret newDelay = ret
continue continue
fname, firmwarecontent = ret fname, firmwarecontent = ret
self.handleContent(fname, firmwarecontent) self.handle_content(fname, firmwarecontent, url)
return retries, newDelay return retries, newDelay
def downloadFile(self, url, filename, retries): def download_file(self, url, filename, retries):
if filename and os.path.isfile(os.path.join(self.otauPath, filename)): if filename and os.path.isfile(os.path.join(self.otau_path, filename)):
print(f"{filename} skipped. A file with that name already exists") print(f"{filename} skipped. A file with that name already exists")
return None return None
@ -78,17 +78,19 @@ class Downloader(ABC):
contentDisposition = contentDisposition.split(";") contentDisposition = contentDisposition.split(";")
fname = contentDisposition[0] fname = contentDisposition[0]
return fname, response.content return fname, response.content
def handleContent(self, fname, firmwarecontent): def handle_content(self, fname: str, firmwarecontent, src: str):
if fname.endswith(self.extensions): if fname.lower().endswith(self.extensions):
fullname = os.path.join(self.otauPath, fname) fullname = os.path.join(self.otau_path, fname)
if not os.path.isfile(fullname): if not os.path.isfile(fullname):
file = open(fullname, "wb") file = open(fullname, "wb")
file.write(firmwarecontent) file.write(firmwarecontent)
file.close() file.close()
print(f"{fname} downloaded") print(f"{fname} downloaded")
self.write_log(src, fname, len(firmwarecontent))
else: else:
print(f"{fname} skipped. A file with that name already exists") print(f"{fname} skipped. A file with that name already exists")
else: else:
@ -99,18 +101,26 @@ class Downloader(ABC):
file = open(fullname, 'wb') file = open(fullname, 'wb')
file.write(firmwarecontent) file.write(firmwarecontent)
file.close() file.close()
if list(filter(lambda ext: fname.endswith(ext), self.archive_extensions)):
shutil.unpack_archive(fullname, tmpdirname) shutil.unpack_archive(fullname, tmpdirname)
print(f"Downloaded and unpacked {fname}") print(f"Downloaded and unpacked {fname}")
for f in self.filteredFilelist(tmpdirname): for f in self.filtered_filelist(tmpdirname):
target = os.path.join(self.otauPath, os.path.basename(f)) target = os.path.join(self.otau_path, os.path.basename(f))
if not os.path.isfile(target): if not os.path.isfile(target):
shutil.copyfile(f, target) shutil.copyfile(f, target)
print('Extracted %s' % os.path.basename(f)) print(f"Extracted {os.path.basename(f)}")
else: self.write_log(fname, os.path.basename(f), os.path.getsize(f))
print('%s skipped. A file with that name already exists' % os.path.basename(f)) else:
print('%s skipped. A file with that name already exists' % os.path.basename(f))
else:
print(f"{fname} is not a supported file type")
def filteredFilelist(self, rootDir): def filtered_filelist(self, rootDir):
return [os.path.join(r, fn) return [os.path.join(r, fn)
for r, ds, fs in os.walk(rootDir) for r, ds, fs in os.walk(rootDir)
for fn in fs if fn.endswith(self.extensions)] for fn in fs if fn.endswith(self.extensions)]
def write_log(self, src, fname, size):
o = open(self.log_path, "at")
o.write(src.ljust(100) + fname.ljust(50) + str(size).ljust(16))
o.close()

View File

@ -9,11 +9,13 @@ import datetime
from danfoss import Danfoss from danfoss import Danfoss
from ikea import Ikea from ikea import Ikea
from ligthify import Lightify from ligthify import Lightify
from github_koenkk import GithubKoenkk
print ('%s - Downloadscript started' % f"{datetime.datetime.now():%Y-%m-%d %H:%M:%S}") print ('%s - Downloadscript started' % f"{datetime.datetime.now():%Y-%m-%d %H:%M:%S}")
Danfoss().performDownloads() Danfoss().perform_downloads()
Ikea().performDownloads() Ikea().perform_downloads()
Lightify().performDownloads() Lightify().perform_downloads()
GithubKoenkk().perform_downloads()
print ('%s - Downloadscript finished' % f"{datetime.datetime.now():%Y-%m-%d %H:%M:%S}") print ('%s - Downloadscript finished' % f"{datetime.datetime.now():%Y-%m-%d %H:%M:%S}")

22
github_koenkk.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python3
from posixpath import basename
import requests, json, time
from downloader import Downloader
class GithubKoenkk(Downloader):
def get_url_list(self):
res = []
response = requests.get('https://raw.githubusercontent.com/Koenkk/zigbee-OTA/master/index.json')
data = json.loads(response.content)
for x in data:
url = x['url']
if 'path' in x:
filename = basename(x['path'])
else:
filename = basename(url)
res.append((url, filename))
return res

View File

@ -6,7 +6,7 @@ from downloader import Downloader
class Ikea(Downloader): class Ikea(Downloader):
def getUrlList(self): def get_url_list(self):
f = urlopen("http://fw.ota.homesmart.ikea.net/feed/version_info.json") f = urlopen("http://fw.ota.homesmart.ikea.net/feed/version_info.json")
data = f.read() data = f.read()
@ -22,5 +22,3 @@ class Ikea(Downloader):
res.append((url, fname)) res.append((url, fname))
return res return res

View File

@ -5,7 +5,7 @@ from downloader import Downloader
class Lightify(Downloader): class Lightify(Downloader):
def getUrlList(self): def get_url_list(self):
response = requests.get("https://api.update.ledvance.com/v1/zigbee/products") response = requests.get("https://api.update.ledvance.com/v1/zigbee/products")
if 'Retry-After' in response.headers: if 'Retry-After' in response.headers:
defer = int(response.headers['Retry-After']) + 1 defer = int(response.headers['Retry-After']) + 1