mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-04 16:48:44 +08:00
feature: #132 同步游戏
This commit is contained in:
parent
001cb5dc3e
commit
9403fef320
@ -233,6 +233,7 @@ export const SyncTypeRecords: { [key in SyncType | string]: string } = {
|
|||||||
// [SyncType.broadcast]: i18nHelper.getMessage('504104'),
|
// [SyncType.broadcast]: i18nHelper.getMessage('504104'),
|
||||||
// [SyncType.note]: i18nHelper.getMessage('504105'),
|
// [SyncType.note]: i18nHelper.getMessage('504105'),
|
||||||
[SyncType.music]: i18nHelper.getMessage('504106'),
|
[SyncType.music]: i18nHelper.getMessage('504106'),
|
||||||
|
// [SyncType.game]: i18nHelper.getMessage('504108'),
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -10,3 +10,7 @@ export const doubanHeaders = {
|
|||||||
export const doubanSubjectSyncListUrl = function(subjectType:string, userId:string, doType:string, start:number):string {
|
export const doubanSubjectSyncListUrl = function(subjectType:string, userId:string, doType:string, start:number):string {
|
||||||
return `https://${subjectType}.douban.com/people/${userId}/${doType}?start=${start}&sort=time&rating=all&filter=all&mode=list`;
|
return `https://${subjectType}.douban.com/people/${userId}/${doType}?start=${start}&sort=time&rating=all&filter=all&mode=list`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const doubanGameSubjectSyncListUrl = function(subjectType:string, userId:string, doType:string, start:number):string {
|
||||||
|
return `https://douban.com/people/${userId}/games?start=${start}&sort=time&rating=all&filter=all&mode=list${doType != 'all' ? '&action='+doType : ''}`;
|
||||||
|
}
|
||||||
|
|||||||
@ -106,6 +106,15 @@ export const DoubanSubjectStateRecords_BOOK_SYNC: { [key in DoubanSubjectState]:
|
|||||||
[DoubanSubjectState.collect]: i18nHelper.getMessage('500304'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500304'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export const DoubanSubjectStateRecords_GAME_SYNC: { [key in DoubanSubjectState]: string } = {
|
||||||
|
// @ts-ignore
|
||||||
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500602'),
|
||||||
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500603'),
|
||||||
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500604'),
|
||||||
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_BROADCAST_SYNC: { [key :string]: string } = {
|
export const DoubanSubjectStateRecords_BROADCAST_SYNC: { [key :string]: string } = {
|
||||||
[ALL]: i18nHelper.getMessage('500004'),
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
}
|
}
|
||||||
@ -129,7 +138,7 @@ export const DoubanSubjectStateRecords_SYNC: { [key in SyncType]: Record<DoubanS
|
|||||||
[SyncType.book]:DoubanSubjectStateRecords_BOOK_SYNC,
|
[SyncType.book]:DoubanSubjectStateRecords_BOOK_SYNC,
|
||||||
[SyncType.music]:DoubanSubjectStateRecords_MUSIC_SYNC,
|
[SyncType.music]:DoubanSubjectStateRecords_MUSIC_SYNC,
|
||||||
// [SyncType.note]:DoubanSubjectStateRecords_NOTE_SYNC,
|
// [SyncType.note]:DoubanSubjectStateRecords_NOTE_SYNC,
|
||||||
// [SyncType.game]:DoubanSubjectStateRecords_GAME_SYNC,
|
[SyncType.game]:DoubanSubjectStateRecords_GAME_SYNC,
|
||||||
[SyncType.teleplay]:DoubanSubjectStateRecords_TELEPLAY_SYNC,
|
[SyncType.teleplay]:DoubanSubjectStateRecords_TELEPLAY_SYNC,
|
||||||
// [SyncType.theater]:DoubanSubjectStateRecords_THEATER_SYNC,
|
// [SyncType.theater]:DoubanSubjectStateRecords_THEATER_SYNC,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
ALL, DoubanSubjectState, DoubanSubjectStateRecords,
|
ALL, DoubanSubjectState, DoubanSubjectStateRecords,
|
||||||
DoubanSubjectStateRecords_BOOK_SYNC,
|
DoubanSubjectStateRecords_BOOK_SYNC,
|
||||||
DoubanSubjectStateRecords_BROADCAST_SYNC,
|
DoubanSubjectStateRecords_BROADCAST_SYNC, DoubanSubjectStateRecords_GAME_SYNC,
|
||||||
DoubanSubjectStateRecords_MOVIE_SYNC,
|
DoubanSubjectStateRecords_MOVIE_SYNC,
|
||||||
DoubanSubjectStateRecords_MUSIC_SYNC,
|
DoubanSubjectStateRecords_MUSIC_SYNC,
|
||||||
DoubanSubjectStateRecords_NOTE_SYNC,
|
DoubanSubjectStateRecords_NOTE_SYNC,
|
||||||
@ -234,14 +234,16 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
case SyncType.teleplay:
|
case SyncType.teleplay:
|
||||||
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_TELEPLAY_SYNC, config, disable);
|
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_TELEPLAY_SYNC, config, disable);
|
||||||
break;
|
break;
|
||||||
|
case SyncType.game:
|
||||||
|
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_GAME_SYNC, config, disable);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private showTypeDropdown(containerEl:HTMLElement, config: SyncConfig, disable:boolean) {
|
private showTypeDropdown(containerEl:HTMLElement, config: SyncConfig, disable:boolean) {
|
||||||
const settings = new Setting(containerEl);
|
const settings = new Setting(containerEl);
|
||||||
const scopeSelections = containerEl.createDiv("scope-selection");
|
const scopeSelections = containerEl.createDiv("scope-selection");
|
||||||
const templateFile:HTMLDivElement = containerEl.createDiv('template-file-path-selection');
|
// const templateFile:HTMLDivElement = containerEl.createDiv('template-file-path-selection');
|
||||||
settings
|
settings
|
||||||
.setName(i18nHelper.getMessage('110030'))
|
.setName(i18nHelper.getMessage('110030'))
|
||||||
.addDropdown((dropdown) => {
|
.addDropdown((dropdown) => {
|
||||||
@ -251,7 +253,7 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
config.syncType = value;
|
config.syncType = value;
|
||||||
config.templateFile = this.getDefaultTemplatePath(value);
|
config.templateFile = this.getDefaultTemplatePath(value);
|
||||||
this.openScopeDropdown(scopeSelections, config, disable);
|
this.openScopeDropdown(scopeSelections, config, disable);
|
||||||
this.showTemplateFileSelectionSetting(templateFile, config, disable);
|
// this.showTemplateFileSelectionSetting(templateFile, config, disable);
|
||||||
});
|
});
|
||||||
}).setDisabled(disable);
|
}).setDisabled(disable);
|
||||||
this.openScopeDropdown(scopeSelections, config, disable);
|
this.openScopeDropdown(scopeSelections, config, disable);
|
||||||
@ -274,6 +276,9 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
case SyncType.teleplay:
|
case SyncType.teleplay:
|
||||||
result = (settings.teleplayTemplateFile == '' || settings.teleplayTemplateFile == null) ? DEFAULT_SETTINGS.teleplayTemplateFile : settings.teleplayTemplateFile
|
result = (settings.teleplayTemplateFile == '' || settings.teleplayTemplateFile == null) ? DEFAULT_SETTINGS.teleplayTemplateFile : settings.teleplayTemplateFile
|
||||||
break;
|
break;
|
||||||
|
case SyncType.game:
|
||||||
|
result = (settings.gameTemplateFile == '' || settings.gameTemplateFile == null) ? DEFAULT_SETTINGS.gameTemplateFile : settings.gameTemplateFile
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ export function constructLoginSettingsUI(containerEl: HTMLElement, manager: Sett
|
|||||||
'a',
|
'a',
|
||||||
{
|
{
|
||||||
text: i18nHelper.getMessage('100139'),
|
text: i18nHelper.getMessage('100139'),
|
||||||
href: 'https://obsidian-douban.wanxuping.com/20_howtouse_25_setting_login_douban_cookie.html',
|
href: 'https://wanxp.github.io/obsidian-douban/20_howtouse_25_setting_login_douban_cookie.html',
|
||||||
},
|
},
|
||||||
(a) => {
|
(a) => {
|
||||||
a.setAttr('target', '_blank');
|
a.setAttr('target', '_blank');
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { DoubanBookSyncHandler } from "./DoubanBookSyncHandler";
|
|||||||
import {i18nHelper} from "../../../lang/helper";
|
import {i18nHelper} from "../../../lang/helper";
|
||||||
import {DoubanTeleplaySyncHandler} from "./DoubanTeleplaySyncHandler";
|
import {DoubanTeleplaySyncHandler} from "./DoubanTeleplaySyncHandler";
|
||||||
import {SyncConditionType} from "../../../constant/Constsant";
|
import {SyncConditionType} from "../../../constant/Constsant";
|
||||||
|
import {DoubanGameSyncHandler} from "./DoubanGameSyncHandler";
|
||||||
|
|
||||||
export default class SyncHandler {
|
export default class SyncHandler {
|
||||||
private app: App;
|
private app: App;
|
||||||
@ -34,6 +35,7 @@ export default class SyncHandler {
|
|||||||
// new DoubanNoteSyncHandler(plugin),
|
// new DoubanNoteSyncHandler(plugin),
|
||||||
new DoubanMusicSyncHandler(plugin),
|
new DoubanMusicSyncHandler(plugin),
|
||||||
new DoubanTeleplaySyncHandler(plugin),
|
new DoubanTeleplaySyncHandler(plugin),
|
||||||
|
new DoubanGameSyncHandler(plugin),
|
||||||
this.defaultSyncHandler
|
this.defaultSyncHandler
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export default abstract class DoubanAbstractListHandler
|
|||||||
|
|
||||||
async delay(ms: number) {}
|
async delay(ms: number) {}
|
||||||
|
|
||||||
private getUrl(context: HandleContext, start: number) {
|
protected getUrl(context: HandleContext, start: number) {
|
||||||
return doubanSubjectSyncListUrl(
|
return doubanSubjectSyncListUrl(
|
||||||
this.getSyncTypeDomain(),
|
this.getSyncTypeDomain(),
|
||||||
context.userComponent.getUserId(),
|
context.userComponent.getUserId(),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { DoubanMovieListHandler } from "./DoubanMovieListHandler";
|
|||||||
import {DoubanGameListHandler} from "./DoubanGameListHandler";
|
import {DoubanGameListHandler} from "./DoubanGameListHandler";
|
||||||
|
|
||||||
|
|
||||||
export default class DoubanGameCollectListHandler extends DoubanMovieListHandler{
|
export default class DoubanGameCollectListHandler extends DoubanGameListHandler{
|
||||||
getDoType(): string {
|
getDoType(): string {
|
||||||
return DoubanSubjectState.collect;
|
return DoubanSubjectState.collect;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { DoubanMovieListHandler } from "./DoubanMovieListHandler";
|
|||||||
import {DoubanGameListHandler} from "./DoubanGameListHandler";
|
import {DoubanGameListHandler} from "./DoubanGameListHandler";
|
||||||
|
|
||||||
|
|
||||||
export default class DoubanGameDoListHandler extends DoubanMovieListHandler{
|
export default class DoubanGameDoListHandler extends DoubanGameListHandler{
|
||||||
getDoType(): string {
|
getDoType(): string {
|
||||||
return DoubanSubjectState.do;
|
return DoubanSubjectState.do;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,13 @@
|
|||||||
import DoubanAbstractListHandler from "./DoubanAbstractListHandler";
|
import DoubanAbstractListHandler from "./DoubanAbstractListHandler";
|
||||||
import { SyncType} from "../../../../constant/Constsant";
|
import {PAGE_SIZE, SubjectHandledStatus, SyncType} from "../../../../constant/Constsant";
|
||||||
|
import {CheerioAPI} from "cheerio";
|
||||||
|
import HandleContext from "../../../data/model/HandleContext";
|
||||||
|
import {SearchPageTypeOf} from "../../../data/model/SearchPageTypeOf";
|
||||||
|
import {SubjectListItem} from "../../../data/model/SubjectListItem";
|
||||||
|
import {log} from "../../../../utils/Logutil";
|
||||||
|
import {SearchPage} from "../../../data/model/SearchPage";
|
||||||
|
import {doubanGameSubjectSyncListUrl, doubanSubjectSyncListUrl} from "../../../../constant/Douban";
|
||||||
|
import {ALL, DoubanSubjectState} from "../../../../constant/DoubanUserState";
|
||||||
|
|
||||||
export abstract class DoubanGameListHandler extends DoubanAbstractListHandler {
|
export abstract class DoubanGameListHandler extends DoubanAbstractListHandler {
|
||||||
getSyncType(): SyncType {
|
getSyncType(): SyncType {
|
||||||
@ -8,6 +16,90 @@ export abstract class DoubanGameListHandler extends DoubanAbstractListHandler {
|
|||||||
|
|
||||||
abstract getDoType(): string;
|
abstract getDoType(): string;
|
||||||
|
|
||||||
|
protected getUrl(context: HandleContext, start: number) {
|
||||||
|
return doubanGameSubjectSyncListUrl(
|
||||||
|
this.getSyncTypeDomain(),
|
||||||
|
context.userComponent.getUserId(),
|
||||||
|
this.getDoType(),
|
||||||
|
start,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseSubjectFromHtml(
|
||||||
|
dataHtml: CheerioAPI,
|
||||||
|
context: HandleContext,
|
||||||
|
): SearchPageTypeOf<SubjectListItem> {
|
||||||
|
const items = dataHtml(".common-item")
|
||||||
|
.get()
|
||||||
|
.map((i: any) => {
|
||||||
|
const item = dataHtml(i);
|
||||||
|
const linkValue: string = item
|
||||||
|
.find("div.title > a")
|
||||||
|
.attr("href");
|
||||||
|
const titleValue: string = item
|
||||||
|
.find("div.title > a")
|
||||||
|
.text()
|
||||||
|
.trim();
|
||||||
|
const updateDateStr: string = item.find("div.date").text().trim();
|
||||||
|
let updateDate = null;
|
||||||
|
try {
|
||||||
|
updateDate = new Date(updateDateStr);
|
||||||
|
}catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
log.info("parse date error:" + titleValue);
|
||||||
|
}
|
||||||
|
let idPattern = /(\d){5,10}/g;
|
||||||
|
let ececResult = idPattern.exec(linkValue);
|
||||||
|
return !ececResult ? null : {id: ececResult[0], url: linkValue, title: titleValue, updateDate: updateDate};
|
||||||
|
// return linkValue;
|
||||||
|
});
|
||||||
|
const total = this.getTotal(dataHtml, context);
|
||||||
|
return new SearchPage(
|
||||||
|
total,
|
||||||
|
Math.floor(context.syncOffset / PAGE_SIZE) + 1,
|
||||||
|
PAGE_SIZE,
|
||||||
|
null,
|
||||||
|
items,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTotal(dataHtml: CheerioAPI,
|
||||||
|
context: HandleContext):number {
|
||||||
|
const countDescs = dataHtml("div.tabs > a")
|
||||||
|
.get()
|
||||||
|
.map((i: any) => {
|
||||||
|
const item = dataHtml(i);
|
||||||
|
return item.text().trim();
|
||||||
|
});
|
||||||
|
const {syncConfig} = context;
|
||||||
|
const {scope} = syncConfig;
|
||||||
|
const pattern = /(\d+)/g;
|
||||||
|
|
||||||
|
const wishCount = this.getCount(countDescs, '想玩', pattern);
|
||||||
|
const collectCount = this.getCount(countDescs, '玩过', pattern);
|
||||||
|
const doCount = this.getCount(countDescs, '在玩', pattern);
|
||||||
|
|
||||||
|
|
||||||
|
switch (scope) {
|
||||||
|
case DoubanSubjectState.wish:
|
||||||
|
return wishCount;
|
||||||
|
case DoubanSubjectState.collect:
|
||||||
|
return collectCount;
|
||||||
|
case DoubanSubjectState.do:
|
||||||
|
return doCount;
|
||||||
|
case ALL:
|
||||||
|
return wishCount + collectCount + doCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCount(countDescs:string[], keyword:string, pattern:RegExp):number {
|
||||||
|
return countDescs.filter(desc => desc.includes(keyword)).map(desc => {
|
||||||
|
const result = pattern.exec(desc);
|
||||||
|
return result ? parseInt(result[0], 10) : 0;
|
||||||
|
})[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { DoubanMovieListHandler } from "./DoubanMovieListHandler";
|
|||||||
import {DoubanGameListHandler} from "./DoubanGameListHandler";
|
import {DoubanGameListHandler} from "./DoubanGameListHandler";
|
||||||
|
|
||||||
|
|
||||||
export default class DoubanGameWishListHandler extends DoubanMovieListHandler{
|
export default class DoubanGameWishListHandler extends DoubanGameListHandler{
|
||||||
getDoType(): string {
|
getDoType(): string {
|
||||||
return DoubanSubjectState.wish;
|
return DoubanSubjectState.wish;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -628,6 +628,7 @@ PS: This file could be delete if you want to.
|
|||||||
'504104': `My Broadcast`,
|
'504104': `My Broadcast`,
|
||||||
'504105': `My Note`,
|
'504105': `My Note`,
|
||||||
'504106': `My Music`,
|
'504106': `My Music`,
|
||||||
|
'504108': `My Game`,
|
||||||
|
|
||||||
'500002': `Sync Status`,
|
'500002': `Sync Status`,
|
||||||
|
|
||||||
|
|||||||
@ -641,6 +641,7 @@ export default {
|
|||||||
'504104': `我的广播`,
|
'504104': `我的广播`,
|
||||||
'504105': `我的日记`,
|
'504105': `我的日记`,
|
||||||
'504106': `我的音乐`,
|
'504106': `我的音乐`,
|
||||||
|
'504108': `我的游戏`,
|
||||||
|
|
||||||
|
|
||||||
'ALL': `全部类型`,
|
'ALL': `全部类型`,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user