Files
PicList/src/main/manage/manageApi.ts
2024-06-15 19:37:50 +08:00

619 lines
17 KiB
TypeScript

import { ipcMain } from 'electron'
import { EventEmitter } from 'events'
import fs from 'fs-extra'
import { get, set, unset } from 'lodash'
import { homedir } from 'os'
import path from 'path'
import windowManager from 'apis/app/window/windowManager'
import API from '~/manage/apis/api'
import ManageDB from '~/manage/datastore/db'
import { managePathChecker } from '~/manage/datastore/dbChecker'
import { isInputConfigValid, formatError } from '~/manage/utils/common'
import { ManageLogger } from '~/manage/utils/logger'
import { IWindowList } from '#/types/enum'
import { IManageApiType, IManageConfigType, IManageError, IPicBedMangeConfig } from '#/types/manage'
import { cancelDownloadLoadingFileList, refreshDownloadFileTransferList } from '#/utils/static'
export class ManageApi extends EventEmitter implements IManageApiType {
private _config!: Partial<IManageConfigType>
private db!: ManageDB
currentPicBed: string
configPath: string
baseDir!: string
logger: ManageLogger
currentPicBedConfig: IPicBedMangeConfig
constructor(currentPicBed: string = '') {
super()
this.currentPicBed = currentPicBed || 'placeholder'
this.configPath = managePathChecker()
this.initConfigPath()
this.logger = new ManageLogger(this)
this.initconfig()
this.currentPicBedConfig = this.getPicBedConfig(this.currentPicBed)
}
getMsgParam(method: string) {
return {
class: 'ManageApi',
method,
picbedName: this.currentPicBedConfig.picBedName
}
}
errorMsg(err: any, param: IStringKeyMap) {
this.logger.error(formatError(err, param))
}
createClient() {
const name = this.currentPicBedConfig.picBedName
switch (name) {
case 'aliyun':
return new API.AliyunApi(
this.currentPicBedConfig.accessKeyId,
this.currentPicBedConfig.accessKeySecret,
this.logger
)
case 'github':
return new API.GithubApi(
this.currentPicBedConfig.token,
this.currentPicBedConfig.githubUsername,
this.currentPicBedConfig.proxy,
this.logger
)
case 'imgur':
return new API.ImgurApi(
this.currentPicBedConfig.imgurUserName,
this.currentPicBedConfig.accessToken,
this.currentPicBedConfig.proxy,
this.logger
)
case 'local':
return new API.LocalApi(this.logger)
case 'qiniu':
return new API.QiniuApi(this.currentPicBedConfig.accessKey, this.currentPicBedConfig.secretKey, this.logger)
case 'smms':
return new API.SmmsApi(this.currentPicBedConfig.token, this.logger)
case 's3plist':
return new API.S3plistApi(
this.currentPicBedConfig.accessKeyId,
this.currentPicBedConfig.secretAccessKey,
this.currentPicBedConfig.endpoint,
this.currentPicBedConfig.sslEnabled,
this.currentPicBedConfig.s3ForcePathStyle,
this.currentPicBedConfig.proxy,
this.logger,
this.currentPicBedConfig.dogeCloudSupport || false,
this.currentPicBedConfig.bucketName || ''
)
case 'sftp':
return new API.SftpApi(
this.currentPicBedConfig.host,
this.currentPicBedConfig.port,
this.currentPicBedConfig.username,
this.currentPicBedConfig.password,
this.currentPicBedConfig.privateKey,
this.currentPicBedConfig.passphrase,
this.currentPicBedConfig.fileMode,
this.currentPicBedConfig.dirMode,
this.logger
)
case 'tcyun':
return new API.TcyunApi(this.currentPicBedConfig.secretId, this.currentPicBedConfig.secretKey, this.logger)
case 'upyun':
return new API.UpyunApi(
this.currentPicBedConfig.bucketName,
this.currentPicBedConfig.operator,
this.currentPicBedConfig.password,
this.logger,
this.currentPicBedConfig.antiLeechToken,
this.currentPicBedConfig.expireTime
)
case 'webdavplist':
return new API.WebdavplistApi(
this.currentPicBedConfig.endpoint,
this.currentPicBedConfig.username,
this.currentPicBedConfig.password,
this.currentPicBedConfig.sslEnabled,
this.currentPicBedConfig.proxy,
this.currentPicBedConfig.authType,
this.logger
)
default:
return {} as any
}
}
private getPicBedConfig(picBedName: string): IPicBedMangeConfig {
return this.getConfig<IPicBedMangeConfig>(`picBed.${picBedName}`)
}
private initConfigPath(): void {
if (this.configPath === '') {
this.configPath = `${homedir()}/.piclist/manage.json`
}
if (path.extname(this.configPath).toUpperCase() !== '.JSON') {
this.configPath = ''
throw Error('The configuration file only supports JSON format.')
}
this.baseDir = path.dirname(this.configPath)
const exist = fs.pathExistsSync(this.configPath)
if (!exist) {
fs.ensureFileSync(this.configPath)
}
}
private initconfig(): void {
this.db = new ManageDB(this)
this._config = this.db.read(true) as IManageConfigType
}
getConfig<T>(name?: string): T {
if (!name) {
return this._config as unknown as T
}
return get(this._config, name)
}
saveConfig(config: IStringKeyMap): void {
if (!isInputConfigValid(config)) {
this.logger.warn('the format of config is invalid, please provide object')
return
}
this.setConfig(config)
this.db.saveConfig(config)
}
removeConfig(key: string, propName: string): void {
if (!key || !propName) {
return
}
this.unsetConfig(key, propName)
this.db.unset(key, propName)
}
setConfig(config: IStringKeyMap): void {
if (!isInputConfigValid(config)) {
this.logger.warn('the format of config is invalid, please provide object')
return
}
Object.keys(config).forEach((name: string) => {
set(this._config, name, config[name])
})
}
unsetConfig(key: string, propName: string): void {
if (!key || !propName) return
unset(this.getConfig(key), propName)
}
async getBucketList(param?: IStringKeyMap | undefined): Promise<any> {
let client
const name = this.currentPicBedConfig.picBedName.replace('plist', '')
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'github':
case 'imgur':
case 's3plist':
try {
client = this.createClient()
return await client.getBucketList()
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('getBucketList'))
return []
}
case 'upyun':
return [
{
Name: this.currentPicBedConfig.bucketName,
Location: 'upyun',
CreationDate: new Date().toISOString()
}
]
case 'smms':
case 'webdavplist':
case 'local':
case 'sftp':
return [
{
Name: name,
Location: name,
CreationDate: new Date().toISOString()
}
]
default:
console.log(param)
return []
}
}
async getBucketInfo(param?: IStringKeyMap | undefined): Promise<IStringKeyMap | IManageError> {
console.log(param)
return {}
}
async getBucketDomain(param: IStringKeyMap): Promise<IStringKeyMap | IManageError> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'github':
try {
client = this.createClient() as any
return await client.getBucketDomain(param)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('getBucketDomain'))
return []
}
case 'upyun':
return [this.currentPicBedConfig.customUrl]
case 'smms':
return ['https://smms.app']
case 'imgur':
return ['https://imgur.com']
default:
return []
}
}
async createBucket(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 's3plist':
try {
client = this.createClient() as any
return await client.createBucket(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('createBucket'))
return false
}
default:
return false
}
}
async deleteBucket(param?: IStringKeyMap): Promise<boolean> {
console.log(param)
return false
}
async getOperatorList(param?: IStringKeyMap): Promise<string[] | IManageError> {
console.log(param)
return []
}
async addOperator(param?: IStringKeyMap): Promise<boolean> {
console.log(param)
return false
}
async deleteOperator(param?: IStringKeyMap): Promise<boolean> {
console.log(param)
return false
}
async getBucketAclPolicy(param?: IStringKeyMap): Promise<IStringKeyMap | IManageError> {
console.log(param)
return {}
}
async setBucketAclPolicy(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'qiniu':
try {
client = new API.QiniuApi(this.currentPicBedConfig.accessKey, this.currentPicBedConfig.secretKey, this.logger)
return await client.setBucketAclPolicy(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('setBucketAclPolicy'))
return false
}
default:
return false
}
}
async getBucketListRecursively(param?: IStringKeyMap): Promise<IStringKeyMap | IManageError> {
let client
let window
const defaultResult = {
fullList: [],
success: false,
finished: true
}
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'smms':
case 'github':
case 'imgur':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
return await client.getBucketListRecursively(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('getBucketListRecursively'))
window = windowManager.get(IWindowList.SETTING_WINDOW)!
window.webContents.send(refreshDownloadFileTransferList, defaultResult)
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
return {}
}
default:
window = windowManager.get(IWindowList.SETTING_WINDOW)!
window.webContents.send(refreshDownloadFileTransferList, defaultResult)
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
return {}
}
}
/**
* 后台更新bucket文件列表
* @param param
* @returns
*/
async getBucketListBackstage(param?: IStringKeyMap): Promise<IStringKeyMap | IManageError> {
let client
let window
const defaultResult = {
fullList: [],
success: false,
finished: true
}
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'smms':
case 'github':
case 'imgur':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
return await client.getBucketListBackstage(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('getBucketListBackstage'))
window = windowManager.get(IWindowList.SETTING_WINDOW)!
window.webContents.send('refreshFileTransferList', defaultResult)
ipcMain.removeAllListeners('cancelLoadingFileList')
return {}
}
default:
window = windowManager.get(IWindowList.SETTING_WINDOW)!
window.webContents.send('refreshFileTransferList', defaultResult)
ipcMain.removeAllListeners('cancelLoadingFileList')
return {}
}
}
/**
* 获取文件夹列表
* 结果统一进行格式化 文件夹提取到最前
* key: 完整路径
* fileName: 文件名
* formatedTime: 格式化时间
* isDir: 是否是文件夹
* fileSize: 文件大小
**/
async getBucketFileList(param?: IStringKeyMap): Promise<IStringKeyMap | IManageError> {
const defaultResponse = {
fullList: <any>[],
isTruncated: false,
nextMarker: '',
success: false
}
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'smms':
case 's3plist':
try {
client = this.createClient()
return await client.getBucketFileList(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('getBucketFileList'))
return defaultResponse
}
default:
return defaultResponse
}
}
async deleteBucketFile(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'smms':
case 'github':
case 'imgur':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
const res = await client.deleteBucketFile(param!)
return res
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('deleteBucketFile'))
return false
}
default:
return false
}
}
async deleteBucketFolder(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'github':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
return await client.deleteBucketFolder(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('deleteBucketFolder'))
return false
}
default:
return false
}
}
async renameBucketFile(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
return await client.renameBucketFile(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('renameBucketFile'))
return false
}
default:
return false
}
}
async downloadBucketFile(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'smms':
case 'github':
case 'imgur':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
const res = await client.downloadBucketFile(param!)
return res
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('downloadBucketFile'))
return false
}
default:
return false
}
}
async copyMoveBucketFile(param?: IStringKeyMap): Promise<boolean> {
console.log(param)
return false
}
async createBucketFolder(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'github':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
return await client.createBucketFolder(param!)
} catch (error) {
this.errorMsg(error, this.getMsgParam('createBucketFolder'))
return false
}
default:
return false
}
}
async uploadBucketFile(param?: IStringKeyMap): Promise<boolean> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'upyun':
case 'smms':
case 'github':
case 'imgur':
case 's3plist':
case 'webdavplist':
case 'local':
case 'sftp':
try {
client = this.createClient() as any
return await client.uploadBucketFile(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('uploadBucketFile'))
return false
}
default:
return false
}
}
async getPreSignedUrl(param?: IStringKeyMap): Promise<string> {
let client
switch (this.currentPicBedConfig.picBedName) {
case 'tcyun':
case 'aliyun':
case 'qiniu':
case 'github':
case 's3plist':
case 'webdavplist':
try {
client = this.createClient() as any
return await client.getPreSignedUrl(param!)
} catch (error: any) {
this.errorMsg(error, this.getMsgParam('getPreSignedUrl'))
return 'error'
}
default:
return 'error'
}
}
}