123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- const axios_1 = require("axios");
- const fetchCookie = require("fetch-cookie");
- const fs_1 = require("fs");
- const mediawiki2_1 = require("mediawiki2");
- const node_fetch_1 = require("node-fetch");
- const playwright_1 = require("playwright");
- const gifski_1 = require("./gifski");
- const loggers_1 = require("./loggers");
- const twitter_1 = require("./twitter");
- const logger = (0, loggers_1.getLogger)('wiki');
- const baseUrl = 'https://wiki.biligame.com/idolypride';
- class default_1 {
- constructor(lock) {
- this.login = (sessdata) => playwright_1.firefox.launch().then(browser => {
- const jar = this.bot.cookieJar;
- return browser.newPage().then(page => page.context().addCookies([{
- name: 'SESSDATA',
- value: sessdata,
- domain: '.biligame.com',
- path: '/',
- }])
- .then(() => page.route('**/*.{png,jpg,jpeg,gif}', route => route.abort()))
- .then(() => page.route('*://*.baidu.com/**', route => route.abort()))
- .then(() => page.goto(`${baseUrl}/index.php?curid=2`, { waitUntil: 'networkidle' }))
- .then(() => { logger.info('logging in via browser...'); return page.context().cookies(); })
- .then(cookies => {
- const uidIndex = cookies.findIndex(cookie => cookie.name === 'gamecenter_wiki_UserName');
- if (!uidIndex)
- throw new Error('auth error');
- return Promise.all(cookies.map(({ name, value, domain, path }) => jar.setCookie(`${name}=${value}; Domain=${domain}; Path=${path}`, baseUrl))).then(() => cookies[uidIndex].value);
- })
- .then(uid => {
- logger.info(`finished logging in via browser, wiki username: ${uid}`);
- this.bot.fetch = fetchCookie(node_fetch_1.default, jar);
- return browser.close();
- })
- .catch((err) => browser.close().then(() => {
- logger.fatal(`error logging in via browser, error: ${err}`);
- process.exit(0);
- })));
- });
- this.fetchMedia = (url) => new Promise((resolve, reject) => {
- logger.info(`fetching ${url}`);
- const fetch = () => (0, axios_1.default)({
- method: 'get',
- url,
- responseType: 'arraybuffer',
- timeout: 150000,
- }).then(res => {
- if (res.status === 200) {
- logger.info(`successfully fetched ${url}`);
- resolve(res.data);
- }
- else {
- logger.error(`failed to fetch ${url}: ${res.status}`);
- reject();
- }
- }).catch(err => {
- logger.error(`failed to fetch ${url}: ${err instanceof Error ? err.message : err}`);
- logger.info(`trying to fetch ${url} again...`);
- fetch();
- });
- fetch();
- }).then(data => {
- var _a;
- return (([_, filename, ext]) => {
- if (ext) {
- const mediaFileName = `${filename}.${ext}`;
- (0, fs_1.writeFileSync)(mediaFileName, Buffer.from(data));
- return (ext === 'mp4' ?
- (0, gifski_1.default)(mediaFileName, 320) :
- Promise.resolve(mediaFileName));
- }
- logger.warn('unable to find MIME type of fetched media, failing this fetch');
- throw Error();
- })((_a = /([^/]*)\?format=([a-z]+)&/.exec(url)) !== null && _a !== void 0 ? _a : /.*\/([^/]*)\.([^?]+)/.exec(url));
- });
- this.uploadMediaItems = (tweet, fileNamePrefix, indexOffset = 0) => {
- const mediaItems = [];
- if (tweet.extended_entities) {
- tweet.extended_entities.media.forEach((media, index) => {
- let url;
- if (media.type === 'photo') {
- url = media.media_url_https.replace(/\.([a-z]+)$/, '?format=$1') + '&name=orig';
- }
- else {
- url = media.video_info.variants
- .filter(variant => variant.bitrate !== undefined)
- .sort((var1, var2) => var2.bitrate - var1.bitrate)
- .map(variant => variant.url)[0];
- }
- const mediaPromise = this.fetchMedia(url)
- .then(mediaFileName => {
- const filename = `${fileNamePrefix}${indexOffset + index + 1}.${mediaFileName.split('.')[1]}`;
- logger.info(`uploading ${mediaFileName} as ${filename}...`);
- return this.bot.simpleUpload({
- file: mediaFileName,
- filename,
- })
- .then(() => filename)
- .catch(error => {
- if (error instanceof mediawiki2_1.WikiError && error.data.result === 'Warning') {
- const { duplicate } = error.data.warnings;
- if (duplicate)
- return duplicate[0];
- }
- else
- throw error;
- });
- });
- mediaItems.push(mediaPromise);
- });
- }
- return Promise.all(mediaItems);
- };
- this.appendMedia = (tweet, genre, indexOffset) => {
- const { pageTitle } = (0, twitter_1.processTweetBody)(tweet);
- const pageLongTitle = `公告/${pageTitle}`;
- const mediaFilePrefix = `公告-${genre}-${pageTitle}-`;
- return this.uploadMediaItems(tweet, mediaFilePrefix, indexOffset)
- .then(fileNames => {
- logger.info(`updating page ${pageLongTitle}...`);
- return this.bot.edit({
- title: pageLongTitle,
- appendtext: `${fileNames.map(fileName => `[[文件:${fileName}|无框|左]]\n`).join('')}`,
- bot: true,
- notminor: true,
- nocreate: true,
- })
- .then(({ new: isNewPost, newtimestamp, pageid, result, title }) => ({
- pageid,
- title,
- new: isNewPost,
- mediafiles: fileNames,
- result,
- timestamp: new Date(newtimestamp).toString(),
- }));
- })
- .catch(error => {
- logger.error(`error updating page, error: ${error}`);
- return {
- pageid: undefined,
- title: pageLongTitle,
- new: undefined,
- mediafiles: [],
- result: 'Failed',
- timestamp: undefined,
- };
- });
- };
- this.post = (tweet, genre) => {
- const { title, body, pageTitle, date } = (0, twitter_1.processTweetBody)(tweet);
- const pageLongTitle = `公告/${pageTitle}`;
- const mediaFilePrefix = `公告-${genre}-${pageTitle}-`;
- const sameTitleAction = this.lock.lastActions.find(action => action.title === pageLongTitle);
- if (sameTitleAction)
- return this.appendMedia(tweet, genre, sameTitleAction.mediafiles.length);
- return this.uploadMediaItems(tweet, mediaFilePrefix)
- .then(fileNames => {
- logger.info(`creating page ${pageLongTitle}`);
- return this.bot.edit({
- title: pageLongTitle,
- basetimestamp: new Date(),
- text: `{{文章戳
- |文章上级页面=公告
- |子类别=${genre}
- |时间=${date}
- |作者=IDOLY PRIDE
- |是否原创=否
- |来源=[https://twitter.com/idolypride IDOLY PRIDE]
- |原文地址=[https://twitter.com/idolypride/status/${tweet.id_str} ${pageTitle}]
- }}
- ====${title.replace('\n', '<br />')}====
- <poem>
- ${body}
- </poem>
- ${fileNames.map(fileName => `[[文件:${fileName}|无框|左]]`).join('\n')}
- `,
- bot: true,
- notminor: true,
- createonly: true,
- })
- .then(({ new: isNewPost, newtimestamp, pageid, result, title }) => ({
- pageid,
- title,
- new: isNewPost,
- mediafiles: fileNames,
- result,
- timestamp: new Date(newtimestamp).toString(),
- }));
- })
- .catch(error => {
- logger.error(`error creating page, error: ${error}`);
- return {
- pageid: undefined,
- title: pageLongTitle,
- new: undefined,
- mediafiles: [],
- result: 'Failed',
- timestamp: undefined,
- };
- });
- };
- this.bot = new mediawiki2_1.MWBot(`${baseUrl}/api.php`);
- this.lock = lock;
- const updateCsrfToken = this.bot.updateCsrfToken.bind(this.bot);
- this.bot.updateCsrfToken = (function () {
- setTimeout(() => { this.lastCsrfToken = undefined; }, 7200000);
- return updateCsrfToken();
- }).bind(this.bot);
- }
- }
- exports.default = default_1;
|