Files
pixiv/backend/core.js
T

322 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const Fse = require('fs-extra');
const Path = require('path');
const PixivAuth = require('./auth');
const DownloadService = require('./services/download');
// 配置文件路径
const CONFIG_FILE_DIR = require('appdata-path').getAppDataPath('pmanager');
const CONFIG_FILE = Path.resolve(CONFIG_FILE_DIR, 'config.json');
// 默认配置
const defaultConfig = {
download: {
thread: 5,
timeout: 30,
path: null
},
refresh_token: null,
access_token: null,
user: null,
proxy: null
};
class PixivBackend {
constructor() {
this.config = null;
this.auth = null;
this.isLoggedIn = false;
this.downloadService = null;
}
/**
* 初始化后端
*/
async init() {
console.log('正在初始化 Pixiv 后端...');
// 初始化配置
this.initConfig();
this.config = this.readConfig();
// 创建认证实例,传入代理配置
this.auth = new PixivAuth(this.config.proxy);
// 同步已保存的token状态
if (this.config.access_token && this.config.refresh_token) {
this.auth.syncTokens(
this.config.access_token,
this.config.refresh_token,
this.config.user
);
}
// 创建下载服务实例
this.downloadService = new DownloadService(this.auth);
await this.downloadService.init();
// 检查登录状态
if (this.config.refresh_token) {
console.log('检测到已保存的登录信息,正在验证...');
await this.relogin();
} else {
console.log('未检测到登录信息,需要先登录');
}
// 启动token同步定时任务
this.startTokenSyncTask();
return this;
}
/**
* 启动token同步定时任务
*/
startTokenSyncTask() {
// 每5分钟同步一次token状态到配置文件
setInterval(() => {
if (this.auth && this.isLoggedIn) {
this.syncTokensToConfig();
}
}, 5 * 60 * 1000); // 5分钟
console.log('Token同步定时任务已启动');
}
/**
* 初始化配置文件
*/
initConfig() {
Fse.ensureDirSync(CONFIG_FILE_DIR);
if (!Fse.existsSync(CONFIG_FILE)) {
Fse.writeJSONSync(CONFIG_FILE, defaultConfig);
}
}
/**
* 读取配置
*/
readConfig() {
try {
const config = Fse.readJsonSync(CONFIG_FILE);
// 合并默认配置
return { ...defaultConfig, ...config };
} catch (error) {
console.error('读取配置文件失败:', error.message);
return { ...defaultConfig };
}
}
/**
* 保存配置
*/
saveConfig() {
try {
Fse.writeJsonSync(CONFIG_FILE, this.config);
console.log('配置已保存');
} catch (error) {
console.error('保存配置失败:', error.message);
}
}
/**
* 获取登录URL
*/
getLoginUrl() {
const loginData = this.auth.getLoginUrl();
this.config.code_verifier = loginData.code_verifier;
this.saveConfig();
return {
login_url: loginData.login_url,
code_verifier: loginData.code_verifier
};
}
/**
* 处理登录回调
*/
async handleLoginCallback(code) {
try {
console.log('正在处理登录回调...');
if (!this.config.code_verifier) {
throw new Error('缺少 code_verifier,请重新获取登录URL');
}
// 使用新的认证模块进行登录
const result = await this.auth.getAccessToken(code, this.config.code_verifier);
if (result.success) {
// 保存登录信息
this.config.refresh_token = result.refresh_token;
this.config.access_token = result.access_token;
this.config.user = result.user;
// 清理临时数据
delete this.config.code_verifier;
this.saveConfig();
this.isLoggedIn = true;
console.log(`登录成功!用户: ${result.user.account}`);
return {
success: true,
user: result.user
};
} else {
throw new Error(result.error);
}
} catch (error) {
console.error('登录失败:', error.message);
return {
success: false,
error: error.message
};
}
}
/**
* 重新登录(使用保存的 refresh_token
*/
async relogin() {
try {
if (!this.config.refresh_token) {
throw new Error('没有保存的登录信息');
}
console.log('正在使用保存的登录信息重新登录...');
const result = await this.auth.refreshAccessToken(this.config.refresh_token);
if (result.success) {
// 更新配置
this.config.access_token = result.access_token;
this.config.refresh_token = result.refresh_token;
// 如果刷新令牌响应中包含用户信息,则更新
if (result.user) {
this.config.user = result.user;
}
// 同步到auth实例
this.auth.syncTokens(
result.access_token,
result.refresh_token,
result.user
);
this.saveConfig();
this.isLoggedIn = true;
console.log('重新登录成功!');
return { success: true };
} else {
throw new Error(result.error);
}
} catch (error) {
console.error('重新登录失败:', error.message);
// 清除无效的登录信息
this.config.refresh_token = null;
this.config.access_token = null;
this.config.user = null;
this.saveConfig();
this.isLoggedIn = false;
return {
success: false,
error: error.message
};
}
}
/**
* 登出
*/
logout() {
this.auth.logout();
this.config.refresh_token = null;
this.config.access_token = null;
this.config.user = null;
this.isLoggedIn = false;
this.saveConfig();
console.log('已登出');
return { success: true };
}
/**
* 获取登录状态
*/
getLoginStatus() {
const status = this.auth.getStatus();
return {
isLoggedIn: status.isLoggedIn,
username: this.config.user?.account,
user_id: this.config.user?.id
};
}
/**
* 设置下载路径
*/
setDownloadPath(path) {
this.config.download.path = path;
this.saveConfig();
console.log(`下载路径已设置为: ${path}`);
return { success: true };
}
/**
* 获取配置信息
*/
getConfig() {
return {
download: this.config.download,
proxy: this.config.proxy,
isLoggedIn: this.isLoggedIn
};
}
/**
* 设置代理
*/
setProxy(proxy) {
this.config.proxy = proxy;
this.auth.setProxy(proxy);
this.saveConfig();
console.log(`代理已设置为: ${proxy}`);
return { success: true };
}
/**
* 获取认证实例
*/
getAuth() {
return this.auth;
}
/**
* 同步token状态到配置
*/
syncTokensToConfig() {
if (this.auth) {
this.config.access_token = this.auth.accessToken;
this.config.refresh_token = this.auth.refreshToken;
this.config.user = this.auth.user;
this.saveConfig();
}
}
/**
* 获取下载服务实例
*/
getDownloadService() {
return this.downloadService;
}
}
module.exports = PixivBackend;