Skip to content

Commit

Permalink
配置添加数据库版本号
Browse files Browse the repository at this point in the history
新增数据库更新逻辑
数据库ns列改名为sn
视频信息获取失败友好提示
当已下载文件丢失时, 在数据库里重新标记为未下载, 下次更新时重启下载
  • Loading branch information
miyouzi committed Jan 24, 2019
1 parent 1aba154 commit 44d257d
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 30 deletions.
70 changes: 67 additions & 3 deletions Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# @Software: PyCharm

import os, json, re, sys, requests, time
import sqlite3
from ColorPrint import err_print

working_dir = os.path.dirname(os.path.realpath(__file__))
Expand All @@ -14,7 +15,8 @@
sn_list_path = os.path.join(working_dir, 'sn_list.txt')
cookies_path = os.path.join(working_dir, 'cookie.txt')
aniGamerPlus_version = 'v8.1'
latest_config_version = 3.1
latest_config_version = 3.2
latest_database_version = 2.0


def __init_settings():
Expand Down Expand Up @@ -51,7 +53,8 @@ def __init_settings():
'check_latest_version': True, # 是否检查新版本
'read_sn_list_when_checking_update': True,
'read_config_when_checking_update': True,
'config_version': latest_config_version
'config_version': latest_config_version,
'database_version': latest_database_version
}
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(settings, f, ensure_ascii=False, indent=4)
Expand Down Expand Up @@ -101,12 +104,65 @@ def __update_settings(old_settings): # 升级配置文件
if 'multi_downloading_segment' not in new_settings.keys(): # v3.1 新增分段下载模式下每个视频并发下载分段数
new_settings['multi_downloading_segment'] = 2

new_settings['database_version'] = latest_database_version # v3.2 新增数据库版本号
new_settings['config_version'] = latest_config_version
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(new_settings, f, ensure_ascii=False, indent=4)
err_print('配置文件從 v'+str(old_settings['config_version'])+' 升級到 v'+str(latest_config_version)+' 你的有效配置不會丟失!', True)


def __update_database(old_version):
db_path = os.path.join(working_dir, 'aniGamer.db')
conn = sqlite3.connect(db_path)
cursor = conn.cursor()

def creat_table():
cursor.execute('CREATE TABLE IF NOT EXISTS anime ('
'sn INTEGER PRIMARY KEY NOT NULL,'
'title VARCHAR(100) NOT NULL,'
'anime_name VARCHAR(100) NOT NULL, '
'episode VARCHAR(10) NOT NULL,'
'status TINYINT DEFAULT 0,'
'remote_status INTEGER DEFAULT 0,'
'resolution INTEGER DEFAULT 0,'
'file_size INTEGER DEFAULT 0,'
'local_file_path VARCHAR(500),'
"[CreatedTime] TimeStamp NOT NULL DEFAULT (datetime('now','localtime')))")

try:
cursor.execute('SELECT COUNT(*) FROM anime')
except sqlite3.OperationalError as e:
if 'no such table' in str(e):
# 如果不存在表, 则新建
creat_table()

try:
cursor.execute('SELECT COUNT(local_file_path) FROM anime')
except sqlite3.OperationalError as e:
if 'no such column' in str(e):
# 更早期的数据库没有 local_file_path , 做兼容
cursor.execute('ALTER TABLE anime ADD local_file_path VARCHAR(500)')

try:
cursor.execute('SELECT COUNT(sn) FROM anime')
except sqlite3.OperationalError as e:
if 'no such column' in str(e):
# 数据库 v2.0 将 ns 列改名为 sn
cursor.execute('ALTER TABLE anime RENAME TO animeOld')
creat_table()
cursor.execute("INSERT INTO "
"anime (sn,title,anime_name,episode,status,remote_status,resolution,file_size,local_file_path,[CreatedTime]) "
"SELECT "
"ns,title,anime_name,episode,status,remote_status,resolution,file_size,local_file_path,[CreatedTime] "
"FROM animeOld")
cursor.execute('DROP TABLE animeOld')

cursor.close()
conn.commit()
conn.close()
err_print('資料庫從 v'+str(old_version)+' 升級到 v'+str(latest_database_version)+' 内部資料不會丟失', True)


def __read_settings_file():
with open(config_path, 'r', encoding='utf-8') as f:
# 转义win路径
Expand All @@ -119,8 +175,16 @@ def read_settings():

settings = __read_settings_file()

if 'database_version' in settings.keys():
if settings['database_version'] < latest_database_version:
__update_database(settings['database_version'])
else:
# 如果该版本配置下没有 database_version 项, 则数据库版本应该是1.0
settings['database_version'] = 1.0
__update_database(1.0)

if settings['config_version'] < latest_config_version:
__update_settings(settings) # 升级旧版配置
__update_settings(settings) # 升级配置
settings = __read_settings_file() # 重新载入

if settings['ftp']['port']:
Expand Down
118 changes: 92 additions & 26 deletions aniGamerPlus.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@
from ColorPrint import err_print


def read_db(ns):
def build_anime(sn):
anime = {'anime': None, 'failed': True}
try:
anime['anime'] = Anime(sn)
anime['failed'] = False
except TryTooManyTimeError:
err_print('抓取失敗! sn='+str(sn)+' 影片信息抓取失敗!')
return anime


def read_db(sn):
# 传入sn(int),读取该 sn 资料,返回 dict
conn = sqlite3.connect(db_path)
cursor = conn.cursor()

cursor.execute("select * FROM anime WHERE ns=:ns", {'ns': ns})
cursor.execute("select * FROM anime WHERE sn=:sn", {'sn': sn})

try:
values = cursor.fetchall()[0]
Expand All @@ -50,20 +60,19 @@ def read_db(ns):

def insert_db(anime):
# 向数据库插入新资料
anime_dict = {}
anime_dict['ns'] = str(anime.get_sn())
anime_dict['title'] = anime.get_title()
anime_dict['anime_name'] = anime.get_bangumi_name()
anime_dict['episode'] = anime.get_episode()
anime_dict = {'sn': str(anime.get_sn()),
'title': anime.get_title(),
'anime_name': anime.get_bangumi_name(),
'episode': anime.get_episode()}

conn = sqlite3.connect(db_path)
cursor = conn.cursor()

try:
cursor.execute("INSERT INTO anime (ns, title, anime_name, episode) VALUES (:ns, :title, :anime_name, :episode)",
cursor.execute("INSERT INTO anime (sn, title, anime_name, episode) VALUES (:sn, :title, :anime_name, :episode)",
anime_dict)
except sqlite3.IntegrityError as e:
err_msg = 'ERROR: sn=' + anime_dict['ns'] + ' title=' + anime_dict['title'] + ' 数据已存在!' + str(e)
err_msg = 'ERROR: sn=' + anime_dict['sn'] + ' title=' + anime_dict['title'] + ' 数据已存在!' + str(e)
err_print(err_msg)

cursor.close()
Expand All @@ -78,12 +87,14 @@ def update_db(anime):
anime_dict['status'] = 1
else:
# 下载失败
sys.exit(1)
anime_dict['status'] = 0

if anime.upload_succeed_flag:
anime_dict['remote_status'] = 1
else:
anime_dict['remote_status'] = 0
anime_dict['ns'] = anime.get_sn()

anime_dict['sn'] = anime.get_sn()
anime_dict['title'] = anime.get_title()
anime_dict['anime_name'] = anime.get_bangumi_name()
anime_dict['episode'] = anime.get_episode()
Expand All @@ -99,7 +110,7 @@ def update_db(anime):
"remote_status=:remote_status,"
"resolution=:resolution,"
"file_size=:file_size,"
"local_file_path=:local_file_path WHERE ns=:ns",
"local_file_path=:local_file_path WHERE sn=:sn",
anime_dict)

cursor.close()
Expand All @@ -108,27 +119,51 @@ def update_db(anime):


def worker(sn, bangumi_tag=''):
def upload_quit():
queue.pop(sn)
processing_queue.remove(sn)
upload_limiter.release() # 并发上传限制器
sys.exit(0)

anime_in_db = read_db(sn)
# 如果用户设定要上传且已经下载好了但还没有上传成功, 那么仅上传
if settings['upload_to_server'] and anime_in_db['status'] == 1 and anime_in_db['remote_status'] == 0:
upload_limiter.acquire() # 并发上传限制器
anime = Anime(sn)
anime = build_anime(sn)
if anime['failed']:
err_print('任务失敗: sn=' + str(sn) + ' 從任務列隊中移除, 等待下次更新重試.')
upload_quit()

# 视频信息抓取成功
anime = anime['anime']
if not os.path.exists(anime_in_db['local_file_path']):
# 如果数据库中记录的文件路径已失效
update_db(anime)
err_print('上传失敗! sn=' + str(anime.get_sn()) + ' title=\"' + anime.get_title() + '\" 本地文件丢失, 從任務列隊中移除, 等待下次更新重試.')
upload_quit()

anime.local_video_path = anime_in_db['local_file_path'] # 告知文件位置
anime.video_size = anime_in_db['file_size'] # 通過 update_db() 下载状态检查
anime.video_resolution = anime_in_db['resolution'] # 避免更新时把分辨率变成0
if not anime.upload(bangumi_tag): # 如果上传失败
err_print('sn=' + str(anime.get_sn()) + ' title=\"' + anime.get_title() + '\" 上传失敗! 從任務列隊中移除, 等待下次更新重試.')
err_print('上传失敗! sn=' + str(anime.get_sn()) + ' title=\"' + anime.get_title() + '\" 從任務列隊中移除, 等待下次更新重試.')
else:
update_db(anime)
err_print('任务完成: sn=' + str(sn), True)
queue.pop(sn)
processing_queue.remove(sn)
upload_limiter.release() # 并发上传限制器
sys.exit(0)
upload_quit()

# =====下载模块 =====
thread_limiter.acquire() # 并发下载限制器
anime = Anime(sn)
anime = build_anime(sn)

if anime['failed']:
queue.pop(sn)
processing_queue.remove(sn)
thread_limiter.release()
err_print('任务失敗: sn=' + str(sn) + ' 從任務列隊中移除, 等待下次更新重試.')
sys.exit(1)

anime = anime['anime']
anime.download(settings['download_resolution'], bangumi_tag=bangumi_tag)
if anime.video_size < 10:
# 下载失败
Expand Down Expand Up @@ -205,7 +240,12 @@ def __download_only(sn, dl_resolution='', dl_save_dir='', realtime_show_file_siz
# 仅下载,不操作数据库
thread_limiter.acquire()
err_counter = 0
anime = Anime(sn)

anime = build_anime(sn)
if anime['failed']:
sys.exit(1)
anime = anime['anime']

if dl_resolution:
anime.download(dl_resolution, dl_save_dir, realtime_show_file_size=realtime_show_file_size)
else:
Expand Down Expand Up @@ -235,15 +275,25 @@ def __cui(sn, cui_resolution, cui_download_mode, cui_thread_limit, ep_range, cui

if cui_download_mode == 'single':
print('當前下載模式: 僅下載本集\n')
Anime(sn).download(cui_resolution, cui_save_dir, realtime_show_file_size=True) # True 是实时显示文件大小, 仅一个下载任务时适用

anime = build_anime(sn)
if anime['failed']:
sys.exit(1)
anime = anime['anime']

anime.download(cui_resolution, cui_save_dir, realtime_show_file_size=True) # True 是实时显示文件大小, 仅一个下载任务时适用

elif cui_download_mode == 'latest' or cui_download_mode == 'largest-sn':
if cui_download_mode == 'latest':
print('當前下載模式: 下載本番劇最後一集\n')
else:
print('當前下載模式: 下載本番劇最近上傳的一集\n')

anime = Anime(sn)
anime = build_anime(sn)
if anime['failed']:
sys.exit(1)
anime = anime['anime']

bangumi_list = list(anime.get_episode_list().values())

if cui_download_mode == 'largest-sn':
Expand All @@ -252,11 +302,22 @@ def __cui(sn, cui_resolution, cui_download_mode, cui_thread_limit, ep_range, cui
if bangumi_list[-1] == sn:
anime.download(cui_resolution, cui_save_dir, realtime_show_file_size=True)
else:
Anime(bangumi_list[-1]).download(cui_resolution, cui_save_dir, realtime_show_file_size=True)

anime = build_anime(bangumi_list[-1])
if anime['failed']:
sys.exit(1)
anime = anime['anime']

anime.download(cui_resolution, cui_save_dir, realtime_show_file_size=True)

elif cui_download_mode == 'all':
print('當前下載模式: 下載本番劇所有劇集\n')
anime = Anime(sn)

anime = build_anime(sn)
if anime['failed']:
sys.exit(1)
anime = anime['anime']

bangumi_list = list(anime.get_episode_list().values())
bangumi_list.sort()
for anime_sn in bangumi_list:
Expand All @@ -269,7 +330,12 @@ def __cui(sn, cui_resolution, cui_download_mode, cui_thread_limit, ep_range, cui

elif cui_download_mode == 'range':
print('當前下載模式: 下載本番劇指定劇集\n')
anime = Anime(sn)

anime = build_anime(sn)
if anime['failed']:
sys.exit(1)
anime = anime['anime']

episode_dict = anime.get_episode_list()
bangumi_ep_list = list(episode_dict.keys()) # 本番剧集列表
for ep in ep_range:
Expand Down Expand Up @@ -429,7 +495,7 @@ def run_gost():
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS anime ('
'ns INTEGER PRIMARY KEY NOT NULL,'
'sn INTEGER PRIMARY KEY NOT NULL,'
'title VARCHAR(100) NOT NULL,'
'anime_name VARCHAR(100) NOT NULL, '
'episode VARCHAR(10) NOT NULL,'
Expand Down
3 changes: 2 additions & 1 deletion config-sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"check_latest_version": true,
"read_sn_list_when_checking_update": true,
"read_config_when_checking_update": true,
"config_version": 3.1
"config_version": 3.2,
"database_version": 2.0
}

0 comments on commit 44d257d

Please sign in to comment.