2022-02-11 16:26:11 +08:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
# -- coding:utf-8 --
|
|
|
|
|
# @Author: markushammered@gmail.com
|
|
|
|
|
# @Development Tool: PyCharm
|
2022-02-12 11:28:21 +08:00
|
|
|
# @Create Time: 2022/2/12
|
2022-02-13 18:50:58 +08:00
|
|
|
# @File Name: __init__.py
|
2022-02-11 16:26:11 +08:00
|
|
|
|
2022-02-12 11:28:21 +08:00
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import hashlib
|
|
|
|
|
import sys
|
|
|
|
|
import requests
|
|
|
|
|
import threading
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MulThreadDownload(threading.Thread):
|
|
|
|
|
"""继承threading使用多线程"""
|
|
|
|
|
def __init__(self, url, startpos, endpos, f, name):
|
|
|
|
|
super(MulThreadDownload, self).__init__()
|
|
|
|
|
self.session = requests.Session()
|
|
|
|
|
self.session.trust_env = False
|
|
|
|
|
self.url = url
|
|
|
|
|
self.startpos = startpos
|
|
|
|
|
self.endpos = endpos
|
|
|
|
|
self.fd = f
|
|
|
|
|
self.name = name
|
|
|
|
|
|
|
|
|
|
def download(self):
|
|
|
|
|
"""
|
|
|
|
|
多线程下载
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
print(f'I: 线程: Thread-{self.name} 开始下载')
|
|
|
|
|
headers = {"Range": "bytes=%s-%s" % (self.startpos, self.endpos)}
|
|
|
|
|
res = self.session.get(self.url, headers=headers)
|
|
|
|
|
self.fd.seek(self.startpos)
|
|
|
|
|
self.fd.write(res.content)
|
|
|
|
|
print(f'I: 线程: Thread-{self.name} 结束下载')
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
"""
|
|
|
|
|
此处启动
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
self.download()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Check:
|
|
|
|
|
"""检查md5是否相同和下载数据库"""
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.assets_url = 'https://themedatabases.vercel.app/assets'
|
|
|
|
|
self.remote_md5 = 'https://themedatabases.vercel.app/md5'
|
|
|
|
|
self.session = requests.Session()
|
|
|
|
|
self.session.trust_env = False
|
|
|
|
|
|
|
|
|
|
def check_md5(self):
|
|
|
|
|
"""
|
|
|
|
|
检验本地文件md5是否和远程md5相同
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
with open('./bin/assets/theme.db', 'rb') as fp:
|
|
|
|
|
data = fp.read()
|
|
|
|
|
local_md5 = hashlib.md5(data).hexdigest()
|
|
|
|
|
remote_md5 = self.session.get(self.remote_md5).json()['data'][0]
|
|
|
|
|
print(f'I: 本地数据库md5: {local_md5}\nI: 远程数据库md5: {remote_md5}')
|
|
|
|
|
if local_md5 != remote_md5:
|
|
|
|
|
print('E: 下载错误: 本地数据库md5和远程数据库md5检验不通过, 即将开始重新下载\nI: 本次下载将使用单线程下载')
|
|
|
|
|
single_download(self.assets_url)
|
|
|
|
|
else:
|
|
|
|
|
print('I: md5检验已通过')
|
|
|
|
|
|
|
|
|
|
def download(self):
|
|
|
|
|
"""
|
|
|
|
|
开始下载
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2022-02-14 16:45:59 +08:00
|
|
|
filesize = int(self.session.head(self.assets_url).headers['Content-Length'])
|
2022-02-12 11:28:21 +08:00
|
|
|
threaded_count = 3
|
|
|
|
|
print(f'I: 数据库大小: {round(filesize / 1024 / 1024, 2)}Mb. 下载线程: {threaded_count}')
|
|
|
|
|
threading.BoundedSemaphore(threaded_count)
|
|
|
|
|
step = filesize // threaded_count
|
|
|
|
|
mtd_list = []
|
|
|
|
|
start = 0
|
|
|
|
|
end = -1
|
|
|
|
|
with open('./bin/assets/theme.db', 'w') as initial_file:
|
|
|
|
|
initial_file.close()
|
|
|
|
|
with open('./bin/assets/theme.db', 'rb+') as f:
|
|
|
|
|
name = 1
|
|
|
|
|
fileno = f.fileno()
|
|
|
|
|
while end < filesize - 1:
|
|
|
|
|
start = end + 1
|
|
|
|
|
end = start + step - 1
|
|
|
|
|
if end > filesize:
|
|
|
|
|
end = filesize
|
|
|
|
|
dup = os.dup(fileno)
|
|
|
|
|
fd = os.fdopen(dup, 'rb+', -1)
|
|
|
|
|
t = MulThreadDownload(self.assets_url, start, end, fd, name)
|
|
|
|
|
name += 1
|
|
|
|
|
t.start()
|
|
|
|
|
mtd_list.append(t)
|
|
|
|
|
|
|
|
|
|
for i in mtd_list:
|
|
|
|
|
i.join()
|
|
|
|
|
|
|
|
|
|
self.check_md5()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def single_download(url):
|
|
|
|
|
"""
|
|
|
|
|
单线程进行下载
|
|
|
|
|
:param url:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
session = requests.Session()
|
|
|
|
|
session.trust_env = False
|
|
|
|
|
resp = session.get(url)
|
|
|
|
|
print(f'I: 正在使用单线程下载中')
|
|
|
|
|
with open('./bin/assets/theme.db', 'wb') as fp:
|
|
|
|
|
fp.write(resp.content)
|
|
|
|
|
print('I: 下载完成 正在检验文件md5')
|
|
|
|
|
with open('./bin/assets/theme.db', 'rb') as fp:
|
|
|
|
|
data = fp.read()
|
|
|
|
|
local_md5 = hashlib.md5(data).hexdigest()
|
|
|
|
|
remote_md5 = session.get('https://themedatabases.vercel.app/md5').json()['data'][0]
|
|
|
|
|
print(f'I: 本地数据库md5: {local_md5}\nI: 远程数据库md5: {remote_md5}')
|
|
|
|
|
if local_md5 != remote_md5:
|
|
|
|
|
print('E: md5检验未通过请手动前往 https://themedatabases.vercel.app/assets 下载文件并放入./bin/assets文件夹内')
|
|
|
|
|
sys.exit(-1)
|
|
|
|
|
else:
|
|
|
|
|
print('I: md5检验已通过')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ != '__main__':
|
|
|
|
|
if not os.path.exists('./bin/assets/theme.db'):
|
|
|
|
|
print('E: 没有检测到本地主题数据库即将开始下载')
|
|
|
|
|
Check().download()
|