commit
ce21648ca8
@ -0,0 +1,99 @@ |
||||
import requests, os, datetime, sys |
||||
|
||||
# Cookie 中 phpdisk_info 的值 |
||||
cookie_phpdisk_info = os.environ.get('phpdisk_info') |
||||
# Cookie 中 ylogin 的值 |
||||
cookie_ylogin = os.environ.get('ylogin') |
||||
|
||||
# 请求头 |
||||
headers = { |
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45', |
||||
'Accept-Language': 'zh-CN,zh;q=0.9', |
||||
'Referer': 'https://pc.woozooo.com/account.php?action=login' |
||||
} |
||||
|
||||
# 小饼干 |
||||
cookie = { |
||||
'ylogin': cookie_ylogin, |
||||
'phpdisk_info': cookie_phpdisk_info |
||||
} |
||||
|
||||
|
||||
# 日志打印 |
||||
def log(msg): |
||||
utc_time = datetime.datetime.utcnow() |
||||
china_time = utc_time + datetime.timedelta(hours=8) |
||||
print(f"[{china_time.strftime('%Y.%m.%d %H:%M:%S')}] {msg}") |
||||
|
||||
|
||||
# 检查是否已登录 |
||||
def login_by_cookie(): |
||||
url_account = "https://pc.woozooo.com/account.php" |
||||
if cookie['phpdisk_info'] is None: |
||||
log('ERROR: 请指定 Cookie 中 phpdisk_info 的值!') |
||||
return False |
||||
if cookie['ylogin'] is None: |
||||
log('ERROR: 请指定 Cookie 中 ylogin 的值!') |
||||
return False |
||||
res = requests.get(url_account, headers=headers, cookies=cookie, verify=True) |
||||
if '网盘用户登录' in res.text: |
||||
log('ERROR: 登录失败,请更新Cookie') |
||||
return False |
||||
else: |
||||
log('登录成功') |
||||
return True |
||||
|
||||
|
||||
# 上传文件 |
||||
def upload_file(file_dir, folder_id): |
||||
file_name = os.path.basename(file_dir) |
||||
url_upload = "https://up.woozooo.com/fileup.php" |
||||
headers['Referer'] = f'https://up.woozooo.com/mydisk.php?item=files&action=index&u={cookie_ylogin}' |
||||
post_data = { |
||||
"task": "1", |
||||
"folder_id": folder_id, |
||||
"id": "WU_FILE_0", |
||||
"name": file_name, |
||||
} |
||||
files = {'upload_file': (file_name, open(file_dir, "rb"), 'application/octet-stream')} |
||||
res = requests.post(url_upload, data=post_data, files=files, headers=headers, cookies=cookie, timeout=120, |
||||
verify=True).json() |
||||
log(f"{file_dir} -> {res['info']}") |
||||
return res['zt'] == 1 |
||||
|
||||
|
||||
# 上传文件夹内的文件 |
||||
def upload_folder(folder_dir, folder_id): |
||||
file_list = os.listdir(folder_dir) |
||||
for file in file_list: |
||||
path = os.path.join(folder_dir, file) |
||||
if os.path.isfile(path): |
||||
upload_file(path, folder_id) |
||||
else: |
||||
upload_folder(path, folder_id) |
||||
|
||||
|
||||
# 上传 |
||||
def upload(dir, folder_id): |
||||
if dir is None: |
||||
log('ERROR: 请指定上传的文件路径') |
||||
return |
||||
if folder_id is None: |
||||
log('ERROR: 请指定蓝奏云的文件夹id') |
||||
return |
||||
if os.path.isfile(dir): |
||||
upload_file(dir, str(folder_id)) |
||||
else: |
||||
upload_folder(dir, str(folder_id)) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
argv = sys.argv[1:] |
||||
if len(argv) != 2: |
||||
log('ERROR: 参数错误,请以这种格式重新尝试\npython lzy_web.py 需上传的路径 蓝奏云文件夹id') |
||||
# 需上传的路径 |
||||
upload_path = argv[0] |
||||
# 蓝奏云文件夹id |
||||
lzy_folder_id = argv[1] |
||||
if login_by_cookie(): |
||||
upload(upload_path, lzy_folder_id) |
@ -1,147 +1,237 @@ |
||||
[ |
||||
{ |
||||
"id": -100, |
||||
"name": "0", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -99, |
||||
"name": "zaixianai.cn", |
||||
"url": "<js>\nlet url='https://www.zaixianai.cn/voiceCompose';\n\nlet ua=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\";\n\nlet doc=java.get(url,{\"User-Agent\":ua});\nlet cookie=String(doc.header(\"set-cookie\")).match(/laravel_session=[^\\n]+/)[0];\nlet token=String(doc.body()).match(/token=\"([^\"]+)/)[1];\n\nurl='https://www.zaixianai.cn/Api_getVoice,'+JSON.stringify({\n\"method\": \"POST\",\n\"body\": \"content=\" + java.encodeURI(speakText) + \"&volume=50&speech_rate=0&voice=Aixia&_token=\"+token,\n\"headers\": {\n\"User-Agent\": ua,\n\"cookie\": cookie\n}\n});\n\nlet res=java.ajax(url);\n\n'https://www.zaixianai.cn/voice/'+JSON.parse(res).data.file_name+','+JSON.stringify({\n\"headers\": {\n\"User-Agent\": ua,\n\"accept\": \"*/*\",\n\"referer\": \"https://www.zaixianai.cn/voiceCompose\",\n\"cookie\": cookie,\n\"accept-encoding\": \"identity;q=1, *;q=0\"\n}\n})\n</js>" |
||||
}, |
||||
{ |
||||
"id": -98, |
||||
"name": "台湾女声", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4007&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -1, |
||||
"name": "度丫丫", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -2, |
||||
"name": "度博文①", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -3, |
||||
"name": "度博文②", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -4, |
||||
"name": "度博文③", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -97, |
||||
"name": "度小乔", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -5, |
||||
"name": "度小娇", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -6, |
||||
"name": "度小宇", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=2&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -7, |
||||
"name": "度小童", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -96, |
||||
"name": "度小童", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -95, |
||||
"name": "度小粤", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=cte&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -8, |
||||
"name": "度小美", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -94, |
||||
"name": "度小芳", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4125&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -9, |
||||
"name": "度小萌", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -93, |
||||
"name": "度小贤", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"}" |
||||
}, |
||||
{ |
||||
"id": -92, |
||||
"name": "度小雯", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -10, |
||||
"name": "度小鹿①", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -11, |
||||
"id": -12, |
||||
"name": "度小鹿②", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -12, |
||||
"id": -11, |
||||
"name": "度小鹿③", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -91, |
||||
"name": "度灵儿", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -13, |
||||
"name": "度米朵①", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -14, |
||||
"name": "度米朵②", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -15, |
||||
"name": "度逍遥-基础", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -16, |
||||
"name": "度逍遥-精品①", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -17, |
||||
"name": "度逍遥-精品②", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -18, |
||||
"name": "情感女声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -19, |
||||
"name": "情感男声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -20, |
||||
"name": "标准女声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -90, |
||||
"name": "标准女声-基础", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -21, |
||||
"name": "标准男声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160=&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -22, |
||||
"name": "治愈女声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"id": -89, |
||||
"name": "温柔女声", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4126&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -23, |
||||
"name": "治愈男声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"id": -88, |
||||
"name": "甜美女声①", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1200&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=&rate=32=5&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -24, |
||||
"name": "甜美女声①", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"name": "甜美女声②", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -25, |
||||
"name": "甜美女声②", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"name": "甜美女声③", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -22, |
||||
"name": "电台女声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=&rate=32=5&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -23, |
||||
"name": "电台男声", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -26, |
||||
"name": "百度主持", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -87, |
||||
"name": "百度主持", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -86, |
||||
"name": "百度解说①", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4123&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=12&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -85, |
||||
"name": "百度解说②", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4128&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=12&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -84, |
||||
"name": "百度解说③", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4129&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=12&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -27, |
||||
"name": "百度评书①", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -28, |
||||
"name": "百度评书②", |
||||
"url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=301&vol=5&pit=5&_res_tag_=audio\"\n}" |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -83, |
||||
"name": "萝莉少女音", |
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5201&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=160&vol=5&aue=6&pit=5&_res_tag_=audio\"\n}" |
||||
}, |
||||
{ |
||||
"id": -29, |
||||
"name": "阿里云语音", |
||||
"url": "<js>/*播音人Aiting可改其他https://cdn.jsdelivr.net/gh/Celeter/build/.github/scripts/speaker.json,详见https://ai.aliyun.com/nls/tts*/;eval(''+java.ajax('https://cdn.jsdelivr.net/gh/Celeter/build/.github/scripts/ttsDemo.js'));ttsDemo(speakText,speakSpeed,'Aiting')</js>" |
||||
} |
||||
] |
||||
] |
File diff suppressed because one or more lines are too long
@ -1,3 +1,3 @@ |
||||
<!DOCTYPE html><html lang="en" style="padding: 0;height:100%"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="favicon.ico" /><![endif]--><title>Legado Bookshelf</title><link href="css/about.dbe575e1.css" rel="prefetch"><link href="css/detail.b4324411.css" rel="prefetch"><link href="js/about.d8b0dc91.js" rel="prefetch"><link href="js/about~detail.1caf6ef5.js" rel="prefetch"><link href="js/detail.6a5cc86c.js" rel="prefetch"><link href="css/app.e4c919b7.css" rel="preload" as="style"><link href="css/chunk-vendors.ad4ff18f.css" rel="preload" as="style"><link href="js/app.d60dad33.js" rel="preload" as="script"><link href="js/chunk-vendors.060eee33.js" rel="preload" as="script"><link href="css/chunk-vendors.ad4ff18f.css" rel="stylesheet"><link href="css/app.e4c919b7.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="yd-web-tool"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><style>body::-webkit-scrollbar { |
||||
<!DOCTYPE html><html lang="en" style="padding: 0;height:100%"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="favicon.ico" /><![endif]--><title>Legado Bookshelf</title><link href="css/about.dbe575e1.css" rel="prefetch"><link href="css/detail.79c91c30.css" rel="prefetch"><link href="js/about.32f651f9.js" rel="prefetch"><link href="js/about~detail.c1b29cbc.js" rel="prefetch"><link href="js/detail.0cc184f2.js" rel="prefetch"><link href="css/app.e4c919b7.css" rel="preload" as="style"><link href="css/chunk-vendors.ad4ff18f.css" rel="preload" as="style"><link href="js/app.3f3311a5.js" rel="preload" as="script"><link href="js/chunk-vendors.305d5536.js" rel="preload" as="script"><link href="css/chunk-vendors.ad4ff18f.css" rel="stylesheet"><link href="css/app.e4c919b7.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="yd-web-tool"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><style>body::-webkit-scrollbar { |
||||
display: none; |
||||
}</style><body style="margin: 0;height:100%"><noscript><strong>We're sorry but yd-web-tool doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.060eee33.js"></script><script src="js/app.d60dad33.js"></script></body></html> |
||||
}</style><body style="margin: 0;height:100%"><noscript><strong>We're sorry but yd-web-tool doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.305d5536.js"></script><script src="js/app.3f3311a5.js"></script></body></html> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,27 +0,0 @@ |
||||
package io.legado.app.constant |
||||
|
||||
import android.provider.Settings |
||||
import splitties.init.appCtx |
||||
|
||||
val androidId: String by lazy { |
||||
Settings.System.getString(appCtx.contentResolver, Settings.Secure.ANDROID_ID) |
||||
} |
||||
|
||||
val appInfo: AppInfo by lazy { |
||||
val appInfo = AppInfo() |
||||
appCtx.packageManager.getPackageInfo(appCtx.packageName, 0)?.let { |
||||
appInfo.versionName = it.versionName |
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) { |
||||
appInfo.versionCode = it.longVersionCode |
||||
} else { |
||||
@Suppress("DEPRECATION") |
||||
appInfo.versionCode = it.versionCode.toLong() |
||||
} |
||||
} |
||||
appInfo |
||||
} |
||||
|
||||
data class AppInfo( |
||||
var versionCode: Long = 0L, |
||||
var versionName: String = "" |
||||
) |
@ -0,0 +1,122 @@ |
||||
package io.legado.app.help.http |
||||
|
||||
import io.legado.app.constant.AppConst |
||||
import io.legado.app.help.AppConfig |
||||
import io.legado.app.utils.EncodingDetect |
||||
import io.legado.app.utils.UTF8BOMFighter |
||||
import kotlinx.coroutines.suspendCancellableCoroutine |
||||
import okhttp3.* |
||||
import okhttp3.HttpUrl.Companion.toHttpUrl |
||||
import okhttp3.MediaType.Companion.toMediaType |
||||
import okhttp3.RequestBody.Companion.toRequestBody |
||||
import java.io.IOException |
||||
import java.nio.charset.Charset |
||||
import kotlin.coroutines.resume |
||||
import kotlin.coroutines.resumeWithException |
||||
|
||||
suspend fun OkHttpClient.newCall( |
||||
retry: Int = 0, |
||||
builder: Request.Builder.() -> Unit |
||||
): ResponseBody { |
||||
val requestBuilder = Request.Builder() |
||||
requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) |
||||
requestBuilder.apply(builder) |
||||
var response: Response? = null |
||||
for (i in 0..retry) { |
||||
response = this.newCall(requestBuilder.build()).await() |
||||
if (response.isSuccessful) { |
||||
return response.body!! |
||||
} |
||||
} |
||||
return response!!.body ?: throw IOException(response.message) |
||||
} |
||||
|
||||
suspend fun OkHttpClient.newCallStrResponse( |
||||
retry: Int = 0, |
||||
builder: Request.Builder.() -> Unit |
||||
): StrResponse { |
||||
val requestBuilder = Request.Builder() |
||||
requestBuilder.header(AppConst.UA_NAME, AppConfig.userAgent) |
||||
requestBuilder.apply(builder) |
||||
var response: Response? = null |
||||
for (i in 0..retry) { |
||||
response = this.newCall(requestBuilder.build()).await() |
||||
if (response.isSuccessful) { |
||||
return StrResponse(response, response.body!!.text()) |
||||
} |
||||
} |
||||
return StrResponse(response!!, response.body?.text() ?: response.message) |
||||
} |
||||
|
||||
suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> |
||||
|
||||
block.invokeOnCancellation { |
||||
cancel() |
||||
} |
||||
|
||||
enqueue(object : Callback { |
||||
override fun onFailure(call: Call, e: IOException) { |
||||
block.resumeWithException(e) |
||||
} |
||||
|
||||
override fun onResponse(call: Call, response: Response) { |
||||
block.resume(response) |
||||
} |
||||
}) |
||||
|
||||
} |
||||
|
||||
fun ResponseBody.text(encode: String? = null): String { |
||||
val responseBytes = UTF8BOMFighter.removeUTF8BOM(bytes()) |
||||
var charsetName: String? = encode |
||||
|
||||
charsetName?.let { |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
//根据http头判断 |
||||
contentType()?.charset()?.let { |
||||
return String(responseBytes, it) |
||||
} |
||||
|
||||
//根据内容判断 |
||||
charsetName = EncodingDetect.getHtmlEncode(responseBytes) |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
fun Request.Builder.addHeaders(headers: Map<String, String>) { |
||||
headers.forEach { |
||||
addHeader(it.key, it.value) |
||||
} |
||||
} |
||||
|
||||
fun Request.Builder.get(url: String, queryMap: Map<String, String>, encoded: Boolean = false) { |
||||
val httpBuilder = url.toHttpUrl().newBuilder() |
||||
queryMap.forEach { |
||||
if (encoded) { |
||||
httpBuilder.addEncodedQueryParameter(it.key, it.value) |
||||
} else { |
||||
httpBuilder.addQueryParameter(it.key, it.value) |
||||
} |
||||
} |
||||
url(httpBuilder.build()) |
||||
} |
||||
|
||||
fun Request.Builder.postForm(form: Map<String, String>, encoded: Boolean = false) { |
||||
val formBody = FormBody.Builder() |
||||
form.forEach { |
||||
if (encoded) { |
||||
formBody.addEncoded(it.key, it.value) |
||||
} else { |
||||
formBody.add(it.key, it.value) |
||||
} |
||||
} |
||||
post(formBody.build()) |
||||
} |
||||
|
||||
fun Request.Builder.postJson(json: String?) { |
||||
json?.let { |
||||
val requestBody = json.toRequestBody("application/json; charset=UTF-8".toMediaType()) |
||||
post(requestBody) |
||||
} |
||||
} |
@ -0,0 +1,12 @@ |
||||
package io.legado.app.help.http |
||||
|
||||
import okhttp3.Interceptor |
||||
import okhttp3.Response |
||||
|
||||
class RetryInterceptor : Interceptor { |
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response { |
||||
TODO("Not yet implemented") |
||||
} |
||||
|
||||
} |
@ -1,13 +0,0 @@ |
||||
package io.legado.app.help.http.parser |
||||
|
||||
import okhttp3.Response |
||||
import rxhttp.wrapper.annotation.Parser |
||||
|
||||
@Parser(name = "ByteArray") |
||||
class ByteParser : rxhttp.wrapper.parse.Parser<ByteArray> { |
||||
|
||||
override fun onParse(response: Response): ByteArray { |
||||
return response.body!!.bytes() |
||||
} |
||||
|
||||
} |
@ -1,14 +0,0 @@ |
||||
package io.legado.app.help.http.parser |
||||
|
||||
import okhttp3.Response |
||||
import rxhttp.wrapper.annotation.Parser |
||||
import java.io.InputStream |
||||
|
||||
@Parser(name = "InputStream") |
||||
class InputStreamParser : rxhttp.wrapper.parse.Parser<InputStream> { |
||||
|
||||
override fun onParse(response: Response): InputStream { |
||||
return response.body!!.byteStream() |
||||
} |
||||
|
||||
} |
@ -1,40 +0,0 @@ |
||||
package io.legado.app.help.http.parser |
||||
|
||||
import io.legado.app.help.http.StrResponse |
||||
import io.legado.app.utils.EncodingDetect |
||||
import io.legado.app.utils.UTF8BOMFighter |
||||
import okhttp3.Response |
||||
import rxhttp.wrapper.annotation.Parser |
||||
import rxhttp.wrapper.exception.HttpStatusCodeException |
||||
import java.nio.charset.Charset |
||||
|
||||
@Parser(name = "StrResponse") |
||||
class StrResponseParser(private val encode: String? = null) : |
||||
rxhttp.wrapper.parse.Parser<StrResponse> { |
||||
|
||||
override fun onParse(response: Response): StrResponse { |
||||
val body = getString(response) |
||||
return StrResponse(response, body) |
||||
} |
||||
|
||||
private fun getString(response: Response): String { |
||||
|
||||
val responseBody = response.body ?: throw HttpStatusCodeException(response, "内容为空") |
||||
val responseBytes = UTF8BOMFighter.removeUTF8BOM(responseBody.bytes()) |
||||
var charsetName: String? = encode |
||||
|
||||
charsetName?.let { |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
//根据http头判断 |
||||
responseBody.contentType()?.charset()?.let { |
||||
return String(responseBytes, it) |
||||
} |
||||
|
||||
//根据内容判断 |
||||
charsetName = EncodingDetect.getHtmlEncode(responseBytes) |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
} |
@ -1,33 +0,0 @@ |
||||
package io.legado.app.help.http.parser |
||||
|
||||
import io.legado.app.utils.EncodingDetect |
||||
import io.legado.app.utils.UTF8BOMFighter |
||||
import okhttp3.Response |
||||
import rxhttp.wrapper.annotation.Parser |
||||
import rxhttp.wrapper.exception.HttpStatusCodeException |
||||
import java.nio.charset.Charset |
||||
|
||||
@Parser(name = "Text") |
||||
class TextParser(private val encode: String? = null) : rxhttp.wrapper.parse.Parser<String> { |
||||
|
||||
override fun onParse(response: Response): String { |
||||
|
||||
val responseBody = response.body ?: throw HttpStatusCodeException(response, "内容为空") |
||||
val responseBytes = UTF8BOMFighter.removeUTF8BOM(responseBody.bytes()) |
||||
var charsetName: String? = encode |
||||
|
||||
charsetName?.let { |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
//根据http头判断 |
||||
responseBody.contentType()?.charset()?.let { |
||||
return String(responseBytes, it) |
||||
} |
||||
|
||||
//根据内容判断 |
||||
charsetName = EncodingDetect.getHtmlEncode(responseBytes) |
||||
return String(responseBytes, Charset.forName(charsetName)) |
||||
} |
||||
|
||||
} |
@ -1,7 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
interface OnPermissionsDeniedCallback { |
||||
|
||||
fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) |
||||
|
||||
} |
@ -1,7 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
interface OnPermissionsGrantedCallback { |
||||
|
||||
fun onPermissionsGranted(requestCode: Int) |
||||
|
||||
} |
@ -1,9 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
interface OnPermissionsResultCallback { |
||||
|
||||
fun onPermissionsGranted(requestCode: Int) |
||||
|
||||
fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) |
||||
|
||||
} |
@ -1,10 +0,0 @@ |
||||
package io.legado.app.help.permission |
||||
|
||||
import android.content.Intent |
||||
|
||||
interface OnRequestPermissionsResultCallback { |
||||
|
||||
fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) |
||||
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) |
||||
} |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.help.permission |
||||
package io.legado.app.lib.permission |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.help.permission |
||||
package io.legado.app.lib.permission |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
@ -0,0 +1,7 @@ |
||||
package io.legado.app.lib.permission |
||||
|
||||
interface OnPermissionsDeniedCallback { |
||||
|
||||
fun onPermissionsDenied(deniedPermissions: Array<String>) |
||||
|
||||
} |
@ -0,0 +1,7 @@ |
||||
package io.legado.app.lib.permission |
||||
|
||||
interface OnPermissionsGrantedCallback { |
||||
|
||||
fun onPermissionsGranted() |
||||
|
||||
} |
@ -0,0 +1,9 @@ |
||||
package io.legado.app.lib.permission |
||||
|
||||
interface OnPermissionsResultCallback { |
||||
|
||||
fun onPermissionsGranted() |
||||
|
||||
fun onPermissionsDenied(deniedPermissions: Array<String>) |
||||
|
||||
} |
@ -0,0 +1,8 @@ |
||||
package io.legado.app.lib.permission |
||||
|
||||
interface OnRequestPermissionsResultCallback { |
||||
|
||||
fun onRequestPermissionsResult(permissions: Array<String>, grantResults: IntArray) |
||||
|
||||
fun onSettingActivityResult() |
||||
} |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.help.permission |
||||
package io.legado.app.lib.permission |
||||
|
||||
@Suppress("unused") |
||||
object Permissions { |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.help.permission |
||||
package io.legado.app.lib.permission |
||||
|
||||
internal object RequestPlugins { |
||||
|
@ -1,4 +1,4 @@ |
||||
package io.legado.app.help.permission |
||||
package io.legado.app.lib.permission |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
@ -1,185 +0,0 @@ |
||||
package io.legado.app.model.localBook |
||||
|
||||
import android.graphics.Bitmap |
||||
import android.graphics.BitmapFactory |
||||
import android.net.Uri |
||||
import android.text.TextUtils |
||||
import io.legado.app.data.entities.BookChapter |
||||
import io.legado.app.utils.* |
||||
import nl.siegmann.epublib.domain.Book |
||||
import nl.siegmann.epublib.domain.TOCReference |
||||
import nl.siegmann.epublib.epub.EpubReader |
||||
import org.jsoup.Jsoup |
||||
import splitties.init.appCtx |
||||
import java.io.File |
||||
import java.io.FileOutputStream |
||||
import java.io.IOException |
||||
import java.io.InputStream |
||||
import java.nio.charset.Charset |
||||
import java.util.* |
||||
|
||||
class EPUBFile(val book: io.legado.app.data.entities.Book) { |
||||
|
||||
companion object { |
||||
private var eFile: EPUBFile? = null |
||||
|
||||
@Synchronized |
||||
private fun getEFile(book: io.legado.app.data.entities.Book): EPUBFile { |
||||
if (eFile == null || eFile?.book?.bookUrl != book.bookUrl) { |
||||
eFile = EPUBFile(book) |
||||
return eFile!! |
||||
} |
||||
return eFile!! |
||||
} |
||||
|
||||
@Synchronized |
||||
fun getChapterList(book: io.legado.app.data.entities.Book): ArrayList<BookChapter> { |
||||
return getEFile(book).getChapterList() |
||||
} |
||||
|
||||
@Synchronized |
||||
fun getContent(book: io.legado.app.data.entities.Book, chapter: BookChapter): String? { |
||||
return getEFile(book).getContent(chapter) |
||||
} |
||||
|
||||
@Synchronized |
||||
fun getImage( |
||||
book: io.legado.app.data.entities.Book, |
||||
href: String |
||||
): InputStream? { |
||||
return getEFile(book).getImage(href) |
||||
} |
||||
} |
||||
|
||||
private var epubBook: Book? = null |
||||
private var mCharset: Charset = Charset.defaultCharset() |
||||
|
||||
init { |
||||
try { |
||||
val epubReader = EpubReader() |
||||
val inputStream = if (book.bookUrl.isContentScheme()) { |
||||
val uri = Uri.parse(book.bookUrl) |
||||
appCtx.contentResolver.openInputStream(uri) |
||||
} else { |
||||
File(book.bookUrl).inputStream() |
||||
} |
||||
epubBook = epubReader.readEpub(inputStream) |
||||
if (book.coverUrl.isNullOrEmpty()) { |
||||
book.coverUrl = FileUtils.getPath( |
||||
appCtx.externalFilesDir, |
||||
"covers", |
||||
"${MD5Utils.md5Encode16(book.bookUrl)}.jpg" |
||||
) |
||||
} |
||||
if (!File(book.coverUrl!!).exists()) { |
||||
epubBook!!.coverImage?.inputStream?.use { |
||||
val cover = BitmapFactory.decodeStream(it) |
||||
val out = FileOutputStream(FileUtils.createFileIfNotExist(book.coverUrl!!)) |
||||
cover.compress(Bitmap.CompressFormat.JPEG, 90, out) |
||||
out.flush() |
||||
out.close() |
||||
} |
||||
} |
||||
} catch (e: Exception) { |
||||
e.printStackTrace() |
||||
} |
||||
} |
||||
|
||||
private fun getContent(chapter: BookChapter): String? { |
||||
epubBook?.let { eBook -> |
||||
val resource = eBook.resources.getByHref(chapter.url) |
||||
val doc = Jsoup.parse(String(resource.data, mCharset)) |
||||
val elements = doc.body().children() |
||||
elements.select("script").remove() |
||||
elements.select("style").remove() |
||||
return elements.outerHtml().htmlFormat() |
||||
} |
||||
return null |
||||
} |
||||
|
||||
private fun getImage(href: String): InputStream? { |
||||
val abHref = href.replace("../", "") |
||||
return epubBook?.resources?.getByHref(abHref)?.inputStream |
||||
} |
||||
|
||||
private fun getChapterList(): ArrayList<BookChapter> { |
||||
val chapterList = ArrayList<BookChapter>() |
||||
epubBook?.let { eBook -> |
||||
val metadata = eBook.metadata |
||||
book.name = metadata.firstTitle |
||||
if (metadata.authors.size > 0) { |
||||
val author = |
||||
metadata.authors[0].toString().replace("^, |, $".toRegex(), "") |
||||
book.author = author |
||||
} |
||||
if (metadata.descriptions.size > 0) { |
||||
book.intro = Jsoup.parse(metadata.descriptions[0]).text() |
||||
} |
||||
|
||||
val refs = eBook.tableOfContents.tocReferences |
||||
if (refs == null || refs.isEmpty()) { |
||||
val spineReferences = eBook.spine.spineReferences |
||||
var i = 0 |
||||
val size = spineReferences.size |
||||
while (i < size) { |
||||
val resource = |
||||
spineReferences[i].resource |
||||
var title = resource.title |
||||
if (TextUtils.isEmpty(title)) { |
||||
try { |
||||
val doc = |
||||
Jsoup.parse(String(resource.data, mCharset)) |
||||
val elements = doc.getElementsByTag("title") |
||||
if (elements.size > 0) { |
||||
title = elements[0].text() |
||||
} |
||||
} catch (e: IOException) { |
||||
e.printStackTrace() |
||||
} |
||||
} |
||||
val chapter = BookChapter() |
||||
chapter.index = i |
||||
chapter.bookUrl = book.bookUrl |
||||
chapter.url = resource.href |
||||
if (i == 0 && title.isEmpty()) { |
||||
chapter.title = "封面" |
||||
} else { |
||||
chapter.title = title |
||||
} |
||||
chapterList.add(chapter) |
||||
i++ |
||||
} |
||||
} else { |
||||
parseMenu(chapterList, refs, 0) |
||||
for (i in chapterList.indices) { |
||||
chapterList[i].index = i |
||||
} |
||||
} |
||||
} |
||||
book.latestChapterTitle = chapterList.lastOrNull()?.title |
||||
book.totalChapterNum = chapterList.size |
||||
return chapterList |
||||
} |
||||
|
||||
private fun parseMenu( |
||||
chapterList: ArrayList<BookChapter>, |
||||
refs: List<TOCReference>?, |
||||
level: Int |
||||
) { |
||||
if (refs == null) return |
||||
for (ref in refs) { |
||||
if (ref.resource != null) { |
||||
val chapter = BookChapter() |
||||
chapter.bookUrl = book.bookUrl |
||||
chapter.title = ref.title |
||||
chapter.url = ref.completeHref |
||||
chapterList.add(chapter) |
||||
} |
||||
if (ref.children != null && ref.children.isNotEmpty()) { |
||||
parseMenu(chapterList, ref.children, level + 1) |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,227 @@ |
||||
package io.legado.app.model.localBook |
||||
|
||||
import android.graphics.Bitmap |
||||
import android.graphics.BitmapFactory |
||||
import android.text.TextUtils |
||||
import io.legado.app.data.entities.Book |
||||
import io.legado.app.data.entities.BookChapter |
||||
import io.legado.app.help.BookHelp |
||||
import io.legado.app.utils.FileUtils |
||||
import io.legado.app.utils.HtmlFormatter |
||||
import io.legado.app.utils.MD5Utils |
||||
import io.legado.app.utils.externalFilesDir |
||||
import me.ag2s.epublib.domain.EpubBook |
||||
import me.ag2s.epublib.epub.EpubReader |
||||
import org.jsoup.Jsoup |
||||
import splitties.init.appCtx |
||||
import java.io.File |
||||
import java.io.FileOutputStream |
||||
import java.io.IOException |
||||
import java.io.InputStream |
||||
import java.nio.charset.Charset |
||||
import java.util.* |
||||
import java.util.zip.ZipFile |
||||
|
||||
class EpubFile(var book: Book) { |
||||
|
||||
companion object { |
||||
private var eFile: EpubFile? = null |
||||
|
||||
@Synchronized |
||||
private fun getEFile(book: Book): EpubFile { |
||||
BookHelp.getEpubFile(book) |
||||
if (eFile == null || eFile?.book?.bookUrl != book.bookUrl) { |
||||
eFile = EpubFile(book) |
||||
return eFile!! |
||||
} |
||||
eFile?.book = book |
||||
return eFile!! |
||||
} |
||||
|
||||
@Synchronized |
||||
fun getChapterList(book: Book): ArrayList<BookChapter> { |
||||
return getEFile(book).getChapterList() |
||||
} |
||||
|
||||
@Synchronized |
||||
fun getContent(book: Book, chapter: BookChapter): String? { |
||||
return getEFile(book).getContent(chapter) |
||||
} |
||||
|
||||
@Synchronized |
||||
fun getImage( |
||||
book: Book, |
||||
href: String |
||||
): InputStream? { |
||||
return getEFile(book).getImage(href) |
||||
} |
||||
|
||||
@Synchronized |
||||
fun upBookInfo(book: Book) { |
||||
return getEFile(book).upBookInfo() |
||||
} |
||||
} |
||||
|
||||
private var mCharset: Charset = Charset.defaultCharset() |
||||
private var epubBook: EpubBook? = null |
||||
get() { |
||||
if (field != null) { |
||||
return field |
||||
} |
||||
field = readEpub() |
||||
return field |
||||
} |
||||
|
||||
init { |
||||
try { |
||||
epubBook?.let { |
||||
if (book.coverUrl.isNullOrEmpty()) { |
||||
book.coverUrl = FileUtils.getPath( |
||||
appCtx.externalFilesDir, |
||||
"covers", |
||||
"${MD5Utils.md5Encode16(book.bookUrl)}.jpg" |
||||
) |
||||
} |
||||
if (!File(book.coverUrl!!).exists()) { |
||||
/*部分书籍DRM处理后,封面获取异常,待优化*/ |
||||
it.coverImage?.inputStream?.use { input -> |
||||
val cover = BitmapFactory.decodeStream(input) |
||||
val out = FileOutputStream(FileUtils.createFileIfNotExist(book.coverUrl!!)) |
||||
cover.compress(Bitmap.CompressFormat.JPEG, 90, out) |
||||
out.flush() |
||||
out.close() |
||||
} |
||||
} |
||||
} |
||||
} catch (e: Exception) { |
||||
e.printStackTrace() |
||||
} |
||||
} |
||||
|
||||
/*重写epub文件解析代码,直接读出压缩包文件生成Resources给epublib,这样的好处是可以逐一修改某些文件的格式错误*/ |
||||
private fun readEpub(): EpubBook? { |
||||
try { |
||||
|
||||
val file = BookHelp.getEpubFile(book) |
||||
//通过懒加载读取epub |
||||
return EpubReader().readEpubLazy(ZipFile(file), "utf-8") |
||||
|
||||
|
||||
} catch (e: Exception) { |
||||
e.printStackTrace() |
||||
} |
||||
return null |
||||
} |
||||
|
||||
private fun getContent(chapter: BookChapter): String? { |
||||
/*获取当前章节文本*/ |
||||
return getChildChapter(chapter, chapter.url) |
||||
} |
||||
|
||||
private fun getChildChapter(chapter: BookChapter, href: String): String? { |
||||
epubBook?.let { |
||||
val body = Jsoup.parse(String(it.resources.getByHref(href).data, mCharset)).body() |
||||
|
||||
if (chapter.url == href) { |
||||
val startFragmentId = chapter.startFragmentId |
||||
val endFragmentId = chapter.endFragmentId |
||||
/*一些书籍依靠href索引的resource会包含多个章节,需要依靠fragmentId来截取到当前章节的内容*/ |
||||
/*注:这里较大增加了内容加载的时间,所以首次获取内容后可存储到本地cache,减少重复加载*/ |
||||
if (!startFragmentId.isNullOrBlank()) |
||||
body.getElementById(startFragmentId)?.previousElementSiblings()?.remove() |
||||
if (!endFragmentId.isNullOrBlank() && endFragmentId != startFragmentId) |
||||
body.getElementById(endFragmentId)?.nextElementSiblings()?.remove() |
||||
} |
||||
|
||||
/*选择去除正文中的H标签,部分书籍标题与阅读标题重复待优化*/ |
||||
var tag = Book.hTag |
||||
if (book.getDelTag(tag)) { |
||||
body.getElementsByTag("h1")?.remove() |
||||
body.getElementsByTag("h2")?.remove() |
||||
body.getElementsByTag("h3")?.remove() |
||||
body.getElementsByTag("h4")?.remove() |
||||
body.getElementsByTag("h5")?.remove() |
||||
body.getElementsByTag("h6")?.remove() |
||||
//body.getElementsMatchingOwnText(chapter.title)?.remove() |
||||
} |
||||
|
||||
/*选择去除正文中的img标签,目前图片支持效果待优化*/ |
||||
tag = Book.imgTag |
||||
if (book.getDelTag(tag)) { |
||||
body.getElementsByTag("img")?.remove() |
||||
} |
||||
|
||||
val elements = body.children() |
||||
elements.select("script").remove() |
||||
elements.select("style").remove() |
||||
/*选择去除正文中的ruby标签,目前注释支持效果待优化*/ |
||||
tag = Book.rubyTag |
||||
var html = elements.outerHtml() |
||||
if (book.getDelTag(tag)) { |
||||
html = html.replace("<ruby>\\s?([\\u4e00-\\u9fa5])\\s?.*?</ruby>".toRegex(), "$1") |
||||
} |
||||
return HtmlFormatter.formatKeepImg(html) |
||||
} |
||||
return null |
||||
} |
||||
|
||||
private fun getImage(href: String): InputStream? { |
||||
val abHref = href.replace("../", "") |
||||
return epubBook?.resources?.getByHref(abHref)?.inputStream |
||||
} |
||||
|
||||
private fun upBookInfo() { |
||||
if (epubBook == null) { |
||||
eFile = null |
||||
book.intro = "书籍导入异常" |
||||
} else { |
||||
val metadata = epubBook!!.metadata |
||||
book.name = metadata.firstTitle |
||||
if (book.name.isEmpty()) { |
||||
book.name = book.originName.replace(".epub", "") |
||||
} |
||||
|
||||
if (metadata.authors.size > 0) { |
||||
val author = |
||||
metadata.authors[0].toString().replace("^, |, $".toRegex(), "") |
||||
book.author = author |
||||
} |
||||
if (metadata.descriptions.size > 0) { |
||||
book.intro = Jsoup.parse(metadata.descriptions[0]).text() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private fun getChapterList(): ArrayList<BookChapter> { |
||||
val chapterList = ArrayList<BookChapter>() |
||||
epubBook?.tableOfContents?.allUniqueResources?.forEachIndexed { index, resource -> |
||||
var title = resource.title |
||||
if (TextUtils.isEmpty(title)) { |
||||
try { |
||||
val doc = |
||||
Jsoup.parse(String(resource.data, mCharset)) |
||||
val elements = doc.getElementsByTag("title") |
||||
if (elements != null && elements.size > 0) { |
||||
title = elements[0].text() |
||||
} |
||||
} catch (e: IOException) { |
||||
e.printStackTrace() |
||||
} |
||||
} |
||||
val chapter = BookChapter() |
||||
chapter.index = index |
||||
chapter.bookUrl = book.bookUrl |
||||
chapter.url = resource.href |
||||
if (index == 0 && title.isEmpty()) { |
||||
chapter.title = "封面" |
||||
} else { |
||||
chapter.title = title |
||||
} |
||||
chapterList.add(chapter) |
||||
} |
||||
book.latestChapterTitle = chapterList.lastOrNull()?.title |
||||
book.totalChapterNum = chapterList.size |
||||
return chapterList |
||||
} |
||||
|
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue