cejs
Version:
A JavaScript module framework that is simple to use.
745 lines (667 loc) • 27.6 kB
JavaScript
/**
* @name CeL module for downloading comico comics.
*
* @fileoverview 本檔案包含了解析並處理、批量下載 韓國 NHN comico Corp. 漫畫 的工具。
*
* 2021/12/22 改版
*
* <code>
CeL.comico(configuration, function(crawler) {
start_crawler(crawler, typeof module === 'object' && module);
}, function(crawler) {
setup_crawler(crawler, typeof module === 'object' && module);
});
</code>
*
* @see http://comico.kr/
*
* @since 2018/8/19 5:49:8 模組化。
*/
// More examples:
// @see
// https://github.com/kanasimi/work_crawler/blob/master/comic.cmn-Hans-CN/comico.js
;
// --------------------------------------------------------------------------------------------
// 不採用 if 陳述式,可以避免 Eclipse JSDoc 與 format 多縮排一層。
typeof CeL === 'function' && CeL.run({
// module name
name : 'application.net.work_crawler.sites.comico',
require : 'application.net.work_crawler.',
// 設定不匯出的子函式。
no_extend : '*',
// 為了方便格式化程式碼,因此將 module 函式主體另外抽出。
code : module_code
});
function module_code(library_namespace) {
// requiring
// --------------------------------------------------------------------------------------------
function add_navigation_data(data, html) {
var navigation_data;
try {
navigation_data = JSON.parse(html.between(
// コミコ 日文版有時 json 結構有問題。
// e.g., http://www.comico.jp/articleList.nhn?titleNo=3410
'<script type="application/ld+json">', '</script>')
// e.g., http://www.comico.com.tw/2870/17/
.replace(/\t+"/g, '"'));
} catch (e) {
// TODO: handle exception
}
return Object.assign(data, navigation_data);
}
var PATTERN_work_info = /<(p|div) class="[^<>"]+?__(author|(?:sub-)?description|meta)">([\s\S]+?)<\/\1>/g,
// assert: (NO_ticket_notified>=0) === false
// gettext_config:{"id":"no-read-volumes-are-available"}
NO_ticket_notified = '已無閱讀卷可用。', auto_use_ticket_notified,
// 可以用閱讀卷閱讀的章節。
READABLE_FLAG = 'W',
//
default_configuration = {
// 所有的子檔案要修訂註解說明時,應該都要順便更改在CeL.application.net.comic中Comic_site.prototype內的母comments,並以其為主體。
// e.g., 20099 俺のメンタルは限界です\0003 3話 「マンガを描く原点」\20099-3-022.jpg
MIN_LENGTH : 180,
// one_by_one : true,
base_URL : '',
// have already read the chapter
set_downloaded_if_read : true,
convert_id : {
// switch
// 警告: 需要自行呼叫 insert_id_list(id_list);
adult : function(insert_id_list, get_label) {
// TW only: 此前被當作是一般作品。
library_namespace.info([ this.id + ': ', {
// gettext_config:{"id":"subsequent-titles-of-the-work-are-considered-to-be-web-limited-works"}
T : '此後的作品標題都被當作是網頁限定作品。'
} ]);
// webonly
this.adult = true;
insert_id_list();
}
},
// 解析 作品名稱 → 作品id get_work()
search_URL : function(work_title) {
var url = (this.adult ? 'webonly/' : '')
// ↑ webonly, オトナ限定: TW only
+ 'search/index.nhn?searchWord='
+ encodeURIComponent(work_title.replace(/\s+\d+$/, ''));
if (this.base_URL.includes('\/\/plus.comico')) {
url = this.base_URL
.replace('\/\/plus.comico', '\/\/www.comico')
+ url;
}
return url;
},
// 每個項目的<li>開頭。
search_head_token : '<li class="list-article02__item">',
// title 不能用 [^<>"]+ : for case of "薔薇的嘆息 <薔薇色的疑雲 I>"
PATTERN_search : /<a href="[^<>"]*?\/(\d+)\/"[^<>]*? title="([^"]+)"/,
parse_search_result : function(html, get_label) {
// console.log(html);
html = html.between(' id="officialList">') || html;
// console.log(html);
var _this = this, id_list = [], id_data = [];
html.each_between(this.search_head_token, '</li>', function(token) {
// console.log(token);
var matched = token.match(_this.PATTERN_search);
// console.log(matched);
if (matched) {
// コミコ有些整本賣的作品,而非一話一話。
id_list.push(matched[1]);
id_data.push(get_label(matched[2]));
}
});
return [ id_list, id_data ];
},
// 取得作品的章節資料。 get_work_data()
work_URL : function(work_id) {
return work_id + '/';
},
parse_work_data : function(html, get_label, extract_work_data) {
// console.log(html);
if (this.archive_old_works) {
// 因為不會遍歷所有章節檔案,得到的是錯誤的 `work_data.last_file_modified_date`。
// 因此必須避免執行 check_and_archive_old_work()。
library_namespace.warn([ this.id + ': ', {
// gettext_config:{"id":"this-website-does-not-support-the-function-of-archiving-old-works-(.archive_old_works)"}
T : '本網站不支援封存舊作品功能 (.archive_old_works)!'
} ]);
this.archive_old_works = false;
}
var cmnData = html.between('var cmnData =', '</script>'), matched;
if (!cmnData) {
// 公式作品の「掲載終了日」について、お知らせいたします。
// 出版社の都合により、以下2作品を掲載終了とさせていただきます。
// 更新中の掲載終了につき、大変ご迷惑をおかけし申し訳ございません。
// 下記の公式作品は既に掲載終了しています。
matched = get_label(html.between(
// <p class="m-section-error__heading">お探しのページは存在しません</p>
'<p class="m-section-error__heading">', '</p>'));
if (matched) {
throw new Error(matched);
}
}
eval('cmnData=' + cmnData);
var title = (html.between('<h1 class="article', '</h1>') || html
.between('<h1', '</h1>')).between('>'), tags = [];
/**
* e.g., http://www.comico.com.tw/challenge/3263/ 去除label
*
* <code>
<h1 class="article-hero03__ttl"><i class="i-label i-label--fill article-hero03__ttl-icon">精選</i><span class="o-hidden _challengeTitle">小惡魔與草莓男友</span></h1>
</code>
*/
if (title.includes('</i>')) {
tags.push(get_label(title.between(null, '</i>')));
title = title.between('</i>');
}
var work_data = {
// 必要屬性:須配合網站平台更改。
// <h1 class="article-hero05__ttl">美麗的代價</h1>
title : get_label(title),
// 選擇性屬性:須配合網站平台更改。
tags : tags
};
extract_work_data(work_data, html);
// e.g., '<li class="article-hero03__list-tag-item">中篇故事</li>'
html.each_between('list-tag-item">', '</li>', function(text) {
tags.push(get_label(text));
});
// JavaScript Object Notation for Linked Data 關聯的資料
matched = html.between('<script type="application/ld+json">',
'</script>');
if (matched) {
// Structured Data 結構化資料
// https://search.google.com/structured-data/testing-tool
try {
matched = JSON.parse(matched);
work_data.linked_data = matched;
} catch (e) {
// library_namespace.error(matched);
}
}
while (matched = PATTERN_work_info.exec(html)) {
if (matched[3] = get_label(matched[3]).replace(/\t/g, ''))
work_data[matched[2]] = matched[3];
}
Object.assign(add_navigation_data(work_data, html),
// 警告: 這會留下個人資訊!
cmnData, {
// 更新日期:每週連載時間/是否為完結作品。 e.g., 完結作品, 每週六, 隔週週日
status : get_label(html.between('__info-value">', '</dd>')
// コミコ e.g., 完結作品, 毎週金曜日
|| html.between('<span class="o-txt-bold">', '</span>'))
.replace(/[\s\n]{2,}/g, ' '),
// 可用的閱讀券數量。
ticket_left : (cmnData.eventRentalTicket || 0)
// 若是不用等的話,表示已收到閱讀券,還有一張可用。
+ (cmnData.time && cmnData.time.leftTime === 0 ? 1 : 0),
last_checked : null
});
if (cmnData.time && cmnData.time.leftTime > 0) {
library_namespace.info({
// gettext_config:{"id":"the-next-time-you-receive-a-reading-voucher-you-will-need-$1"}
T : [ '下次收到閱讀券還要 %1。',
// レンタル券で無料 レンタル券が届きました(1日で回復)
// 作品を1話レンタルできます
library_namespace.age_of(0, 1000 * cmnData.time.leftTime) ]
});
}
// console.log(work_data);
return work_data;
},
chapter_list_URL : function(work_id, work_data) {
// console.log(work_data);
// library_namespace.set_debug(9);
var api = work_data.api && work_data.api.articleListAPI;
if (!api) {
api = work_data.isOfficial === false
// 2019/10: 'api/getArticleListAll.nhn' 沒有 .freeFlg
// 標記,無法自動使用閱讀卷。
// 但是對新手村作品如 '3729 神光拜達摩' 來說,
// 用 'api/getArticleListAll.nhn' 才能取得所有作品之列表。
//
// https://github.com/kanasimi/work_crawler/issues/384
// 第一次執行時,尚未取得 .isOfficial 標記,必須先採用 api/getArticleList.nhn
? 'api/getArticleListAll.nhn'
// 2019/9: 'api/getArticleList.nhn'
: 'api/getArticleList.nhn'
}
return [ api, {
titleNo : work_id
} ];
},
get_chapter_list : function(work_data, html, get_label) {
if (!Array.isArray(work_data.downloaded_chapter_list))
work_data.downloaded_chapter_list = [];
// console.log(html);
var recerse_count = 0;
html = JSON.parse(html);
html = html.result;
// for 'api/getArticleList.nhn', there is no .totalPageCnt
if (('totalPageCnt' in html) && html.totalPageCnt !== 1) {
console.log(html);
throw new Error(work_data.title + ': ' + 'Total page is '
+ html.totalPageCnt + ', not 1!');
}
// 作品改變 titleNo 時,舊 id 可能會回傳 `{"result":{}}`
html.list.forEach(function(chapter_data, index) {
chapter_data.url = chapter_data.articleDetailUrl;
// 原先都將標題設在 subtitle,title 沒東西。
chapter_data.title = get_label(chapter_data.subtitle);
if (this.set_downloaded_if_read
&& !work_data.downloaded_chapter_list[index]) {
work_data.downloaded_chapter_list[index]
// 記錄是否已經下載過本章節。
= chapter_data.read;
}
if (index > 0) {
recerse_count += Math.sign(html.list[index - 1].articleNo
- chapter_data.articleNo);
}
}, this);
work_data.chapter_list = html.list;
// 預防尾大不掉。
delete html.list;
// console.log(recerse_count);
if (recerse_count > 0) {
library_namespace.info([ work_data.title + ': ', {
// gettext_config:{"id":"change-the-list-of-reversed-chapters-to-positive-order"}
T : '將倒序章節列表轉為正序。'
} ]);
work_data.chapter_list.reverse();
}
Object.assign(work_data, html);
// 先檢查是不是還有還有沒讀過的章節。
if (work_data.ticket_left > 0) {
if (work_data.last_download) {
work_data.chapter_list.some(function(chapter_data, index) {
if (++index >= work_data.last_download.chapter) {
return true;
}
if (!chapter_data.freeFlg) {
throw new Error(this.id + ': '
+ '網站改版?未發現 .freeFlg!');
}
if (!work_data.downloaded_chapter_list[index]
&& chapter_data.freeFlg === READABLE_FLAG) {
library_namespace.info([ work_data.title + ': ', {
// gettext_config:{"id":"there-are-still-$1-reading-volume-but-$2-$3-chapter-has-not-been-downloaded-yet.-so-checking-from-this-chapter"}
T : [ '還有%1張{{PLURAL:%1|閱讀卷}},且第 %2/%3 章還有沒下載過,從此章開始檢查。',
//
work_data.ticket_left, index,
//
work_data.chapter_list.length ]
} ]);
work_data.last_checked
// 記錄最後檢查過的章節。
= work_data.last_download.chapter;
work_data.last_download.chapter = index;
return true;
}
});
} else {
work_data.recheck = true;
}
}
},
consume_url : 'consume/index.nhn',
pre_parse_chapter_data
// 執行在解析章節資料 process_chapter_data() 之前的作業 (async)。
// 必須自行保證執行 callback(),不丟出異常、中斷。
: function(XMLHttp, work_data, callback, chapter_NO) {
// console.log(work_data);
var chapter_data = work_data.chapter_list[chapter_NO - 1],
//
skip_chapter = !chapter_data.price || chapter_data.isPurchased && {
// gettext_config:{"id":"«$1»-has-been-purchased"}
T : [ '已購買章節《%1》。', chapter_data.title ]
};
// console.log(chapter_data);
if (!skip_chapter && chapter_data.expireDate > 0) {
skip_chapter = {
// gettext_config:{"id":"you-can-read-«$3»-in-this-section-before-$1-(and-$2)"}
T : [ '在 %1 之前(還有 %2)可以閱讀本章節《%3》。',
//
new Date(chapter_data.expireDate).format('%m/%d %H:%M'),
//
library_namespace.age_of(Date.now(),
//
chapter_data.expireDate), chapter_data.title ]
};
}
if (!skip_chapter
&& work_data.downloaded_chapter_list[chapter_NO - 1]) {
// TODO: 應該檢查是不是真的有圖片檔案存在。若有檔案不見,
// 或者有損壞檔案,
// 那麼就把 work_data.downloaded_chapter_list[index] 設成 false。
skip_chapter = {
// gettext_config:{"id":"the-section-«$1»-has-been-downloaded-before-and-will-not-be-re-purchased"}
T : [ '之前已下載過章節《%1》,不再重新購買。', chapter_data.title ]
};
}
if (!skip_chapter && chapter_data.freeFlg !== READABLE_FLAG) {
// N: TW: 本章節需要錢(coin)來閱讀。
if (chapter_data.freeFlg === 'N'
// P: JP: 本章節需要錢(30コイン) or point(15ポイント)來閱讀。
|| chapter_data.freeFlg === 'P') {
skip_chapter = true;
} else {
skip_chapter = {
// gettext_config:{"id":"the-status-of-this-chapter-is-unknown-($1).-skipping-$1-does-not-use-reading-volumes"}
T : [ '本章節狀況不明(%1)。跳過《%1》不採用閱讀卷。',
chapter_data.freeFlg, chapter_data.title ]
};
}
}
if (!skip_chapter && !(work_data.ticket_left > 0)) {
if (work_data.ticket_left !== NO_ticket_notified) {
work_data.ticket_left = NO_ticket_notified;
skip_chapter = [ {
T : NO_ticket_notified
}, {
T : [ '跳過《%1》,不使用閱讀券。', chapter_data.title ]
} ];
} else
skip_chapter = true;
}
if (!skip_chapter && !this.auto_use_ticket) {
skip_chapter = auto_use_ticket_notified ? true
// @see https://github.com/kanasimi/work_crawler
: {
// gettext_config:{"id":"the-tool-is-not-set-to-automatically-use-the-reading-volume.-if-you-are-not-using-the-installation-package-and-want-to-have-the-tool-automatically-use-the-reading-volume-please-open-the-file-manager"}
T : '未設定讓本工具自動使用閱讀卷。若您並非使用安裝包,並想要讓本工具自動使用閱讀卷,請打開檔案總管,到安裝本工具的目錄下(若是您使用安裝包,就不能夠設定帳號密碼了。),在「work_crawler.configuration.js」這個 .js 組態檔案中設定好帳號密碼資料,並設定「auto_use_ticket:true」。您可以參考 work_crawler.default_configuration.js 這個檔案來做設定。'
};
auto_use_ticket_notified = true;
}
if (skip_chapter) {
if (skip_chapter !== true) {
if (!Array.isArray(skip_chapter)) {
skip_chapter = [ skip_chapter ];
}
skip_chapter.unshift(work_data.title, ': ');
library_namespace.info(skip_chapter);
}
callback();
return;
}
// http://www.comico.com.tw/notice/detail.nhn?no=751
library_namespace.info([ work_data.title + ': ', {
// gettext_config:{"id":"reading-«$1»-with-a-reading-voucher"}
T : [ '用閱讀券閱讀《%1》。', chapter_data.title ]
} ]);
var _this = this, html = XMLHttp.responseText;
this.get_URL(this.consume_url, function(XMLHttp) {
// console.log(XMLHttp.responseText);
var matched = XMLHttp.responseText && XMLHttp.responseText
// var msg = '很抱歉,帳號需要通過電話認證才可購買。';
.match(/[\s;]msg *= *'([^']+)/);
if (matched) {
library_namespace
.error(work_data.title + ': ' + matched[1]);
// 歸零。
work_data.ticket_left = 1;
}
if (--work_data.ticket_left === 0
// 僅僅下載有閱讀券的章節,然後就回到最後讀取的章節。
&& work_data.last_checked > 0) {
// 回到原先應該檢查的章節號碼。
work_data.jump_to_chapter = work_data.last_checked;
delete work_data.last_checked;
}
// XMLHttp 只是一個轉址網頁,必須重新擷取網頁。
_this.get_URL(chapter_data.url, callback);
}, {
titleNo : work_data.id,
articleNo : chapter_data.articleNo,
// K: 專用閱讀券, P: 用point, C: 用coin購買
paymentCode : 'K',
// 使用coin時才需要
// https://github.com/zhongfly/comico/blob/master/comico.py
// ['http://www.comico.com.tw/consume/coin/publish.nhn',{paymentCode:'C'}]
// JSON.parse(result).result.coinUseToken
coinUseToken : '',
// 5, 6, コミコ:36, ...?
productNo : html
//
.between(' name="productNo" value="', '"') || 5,
// coin price
price : chapter_data.price,
// 用coin租用價格,一般能租用的都可以用閱讀券。 コミコ: 20
rentalPrice : html.between(' name="rentalPrice" value="', '"')
|| '',
// point price, コミコ 漫畫作品無此項, TW only
pointRentalPrice : html.between(
' name="pointRentalPrice" value="', '"') || 120
});
},
parse_chapter_data : function(html, work_data, get_label, chapter_NO) {
// http://static.comico.com.tw/tw/syn/spn/js/manga/article/plusMangaDetailApp/app.1.12.0.js
var chapter_data = work_data.chapter_list[chapter_NO - 1],
//
cmnData = html.between('var cmnData =', '</script>');
// console.log(cmnData);
if (cmnData) {
eval('cmnData=' + cmnData);
} else if (cmnData = html.between(
// e.g., http://plus.comico.jp/manga/24517/8/
'<p class="m-section-error__heading">', '</p>')) {
var message = work_data.title + ' §' + chapter_NO + ' '
+ chapter_data.title + ': ' + cmnData;
if (cmnData !== 'お探しのページは存在しません') {
throw new Error(message);
}
library_namespace.error(message);
return chapter_data;
}
var matched, image_url_list = html.between(
// TW: <div class="locked-episode__kv _lockedEpisodeKv"
// コミコ: <div class="locked-episode locked-episode--show-kv">
'<div class="locked-episode', '</div>');
if (image_url_list) {
chapter_data.limited = true;
// TW: style="background-image: url('...');">
image_url_list = image_url_list.between("url('", "'")
// コミコ: <img src=".jpg" width="88" height="88" alt="" />
|| image_url_list.between(' src="', '"');
// 日文版plus.comico 此時雖然有 {Array}cmnData.imageData
// 但缺少hash而不能取得。
if (/\.jpg$/.test(image_url_list)) {
// 日文版plus.comico 此時僅有一個縮圖可用,跳過不取。
cmnData.imageData = [];
} else if (cmnData.imageData
&& cmnData.imageData.filter(function(url) {
return url && !/\.jpg$/.test(url);
}).length > 0) {
// 應該不會到這裡來了。
cmnData.imageData.unshift(image_url_list);
} else {
// 中文版的狀況。
cmnData.imageData = [ image_url_list ];
}
} else if (image_url_list = html
// comico_jp: <div class="comic-image _comicImage">
// e.g., 新手村
.between(' _comicImage">', '</div>')) {
// 一般正常可取得圖片的情況。
// 去除 placeholder。 <div class="comic-image__blank-layer">
image_url_list = image_url_list.between(null, '<div ')
|| image_url_list;
image_url_list = image_url_list.all_between(' src="', '"');
// assert: {Array}image_url_list
if (cmnData.imageData) {
// 中文版, 日文版plus.comico 將除第一張外所有圖片網址放在
// {Array}cmnData.imageData 裡面。
if (image_url_list.length === 1) {
cmnData.imageData.unshift(image_url_list[0]);
} else if (
/**
* e.g.,
* http://www.comico.jp/detail.nhn?titleNo=27605&articleNo=1
* <code>
<div class="swiper-wrapper _swiperWrapper _comicImage">
<!-- Slides -->
<div class="swiper-slide _swiperSlide o-hidden">
<div dir="ltr">
<div id="_popIn_video"></div>
</code>
*/
!html.includes(' class="swiper-slide _swiperSlide')) {
// gettext_config:{"id":"web-page-revision?-unable-to-parse"}
var message = '網頁改版?無法解析!';
if (library_namespace.gettext)
message = library_namespace.gettext(message);
throw new Error('parse_chapter_data: '
+ work_data.title + ' §' + chapter_NO + ': '
+ message);
Array.prototype.unshift.apply(cmnData.imageData,
image_url_list);
}
} else {
// コミコ 日文版一般漫畫將所有圖片放在這之間,無 cmnData.imageData。
cmnData.imageData = image_url_list;
}
} else if (matched = html
// e.g., https://www.comico.jp/detail.nhn?titleNo=4235&articleNo=219
.match(/<h2 class="[^"<>]*o-txt-error[^"<>]*">([\s\S]+?)<\/h2>/)) {
var message = get_label(matched[1]);
throw new Error(work_data.title + ' §' + chapter_NO + ': '
+ message);
} else if (html.includes('<p class="error-section__ttl">')) {
var message = get_label(html.between(
/**
* <code>
<div class="error-section o-mt100 o-mb100">
<p class="error-section__ttl">無法閱讀</p>
<p class="error-section__description">本話正在審查當中。<br/>審查完成後將會開放閱讀</p>
<p class="o-mt30"><a href="" class="btn03" onclick="javascript:history.back();">離開</a></p>
<!-- /.m-section-error --></div>
</code>
*/
'<p class="error-section__ttl">', '</p>'))
//
+ ': ' + get_label(html.between(
//
'<p class="error-section__description">', '</p>'));
throw new Error(work_data.title + ' §' + chapter_NO + ': '
+ message);
} else {
console.log(html);
// gettext_config:{"id":"web-page-revision?-unable-to-parse"}
var message = '網頁改版?無法解析!';
if (library_namespace.gettext)
message = library_namespace.gettext(message);
throw new Error(work_data.title + ' §' + chapter_NO + ': '
+ message);
}
if (cmnData.url) {
// e.g., http://plus.comico.jp/manga/24529/13/
// 預防 chapter_data.url 被污染。
cmnData._url = cmnData.url;
delete cmnData.url;
}
// console.log(work_data);
// console.log(chapter_data);
// console.log(cmnData);
Object.assign(add_navigation_data(chapter_data, html), {
// 設定必要的屬性。
image_list : cmnData.imageData.map(function(url) {
if (chapter_data.limited
// http://comicimg.comico.jp/tmb/00000/1/hexhex_hexhexhex.jpg"
&& url.includes('.jp/tmb/') && /\.jpg$/.test(url))
return;
// chapter_data.isOfficial ? 官方作品 : 新手村
if (chapter_data.isOfficial && chapter_data.freeFlg !== 'Y'
// 付費章節: 中文版提供第一張的完整版,日文版只提供縮圖。
// 圖片都應該要有hash,且不該是縮圖。
&& (url.includes('.jp/tmb/') || /\.jpg$/.test(url))) {
var message = library_namespace.gettext
// gettext_config:{"id":"invalid-image-url-$1"}
? library_namespace.gettext('Invalid image url: %1',
url) : 'Invalid image url: ' + url;
throw new Error(work_data.title + ' §' + chapter_NO
+ ' ' + chapter_data.title + ': ' + message);
}
return {
url : url
};
})
}, cmnData);
return chapter_data;
},
// @see work_crawler_loader.js
after_download_list : function() {
// logout
}
};
// --------------------------------------------------------------------------------------------
/**
* full module name.
*
* @type {String}
*/
var module_name = this.id;
function new_comico_comics_crawler(configuration, callback, initializer) {
configuration = configuration ? Object.assign(Object.create(null),
default_configuration, configuration) : default_configuration;
// 每次呼叫皆創建一個新的實體。
var crawler = new library_namespace.work_crawler(configuration);
if (typeof initializer === 'function') {
initializer(crawler);
}
// for 年齡確認您是否已滿18歲?
crawler.setup_value('cookie', 'islt18age=' + Date.now());
// https://github.com/nodejs/node/issues/27384
// node.js v12 disable TLS v1.0 and v1.1 by default
require('tls').DEFAULT_MIN_VERSION = 'TLSv1';
if (crawler.password && crawler.loginid) {
library_namespace.log([ (crawler.id || module_name) + ': ', {
// gettext_config:{"id":"login-as-$1"}
T : [ 'Login as [%1]', crawler.loginid ]
} ]);
var account_api_host = crawler.base_URL.replace(/^.+?[a-z]+\./,
// https://id.comico.com.tw/login/login.nhn
// https://id.comico.jp/login/login.nhn
'https://id.');
crawler.get_URL(account_api_host + 'login/login.nhn', after_login,
//
{
autoLoginChk : 'Y',
loginid : crawler.loginid,
password : crawler.password,
nexturl : ''
});
} else {
callback(crawler);
}
function after_login(XMLHttp) {
// XMLHttp 只是一個轉址網頁。
// 必須先進入收件箱才能取得所有"有期限的物品"
crawler.get_URL(
// https://id.comico.com.tw/settings/inbox/
account_api_host + 'settings/inbox/', function to_inbox(XMLHttp) {
// 收件箱: 全部接收 有期限的物品
// 受け取りBOX: すべて受け取る
crawler.get_URL(
// https://id.comico.com.tw/api/incentiveall/index.nhn
account_api_host + 'api/incentiveall/index.nhn', get_ticket);
});
}
function get_ticket(XMLHttp) {
// e.g., XMLHttp.responseText ===
// '{"result":[121703625,121703626,121703627,121703628]}'
// console.log(XMLHttp.responseText);
var item_list = JSON.parse(XMLHttp.responseText).result;
if (item_list.length > 0) {
// TODO: 顯示物品的資訊。
library_namespace.info({
// gettext_config:{"id":"$1-items-with-a-time-limit-have-been-received"}
T : [ '已收到 %1 個有期限的{{PLURAL:%1|項目}}。', item_list.length ]
});
}
// 最新消息
// http://www.comico.com.tw/notice/
callback(crawler);
}
}
return new_comico_comics_crawler;
}