mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-05-08 16:10:09 +00:00
update mcp tools
This commit is contained in:
@@ -2,4 +2,5 @@ export const ROOT_DIR = '.infio_json_db'
|
||||
export const COMMAND_DIR = 'commands'
|
||||
export const CHAT_DIR = 'chats'
|
||||
export const CUSTOM_MODE_DIR = 'custom_modes'
|
||||
export const CONVERT_DATA_DIR = 'convert_data'
|
||||
export const INITIAL_MIGRATION_MARKER = '.initial_migration_completed'
|
||||
|
||||
185
src/database/json/convert-data/ConvertDataManager.ts
Normal file
185
src/database/json/convert-data/ConvertDataManager.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
import { createHash } from 'crypto'
|
||||
|
||||
import { App } from 'obsidian'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
|
||||
import { AbstractJsonRepository } from '../base'
|
||||
import { CONVERT_DATA_DIR, ROOT_DIR } from '../constants'
|
||||
|
||||
import {
|
||||
CONVERT_DATA_SCHEMA_VERSION,
|
||||
ConvertData,
|
||||
ConvertDataMetadata,
|
||||
ConvertType
|
||||
} from './types'
|
||||
|
||||
export class ConvertDataManager extends AbstractJsonRepository<
|
||||
ConvertData,
|
||||
ConvertDataMetadata
|
||||
> {
|
||||
constructor(app: App) {
|
||||
super(app, `${ROOT_DIR}/${CONVERT_DATA_DIR}`)
|
||||
}
|
||||
|
||||
protected parseFileName(fileName: string): ConvertDataMetadata | null {
|
||||
// Check if filename is a valid MD5 hash (32 hex characters)
|
||||
const match = fileName.match(
|
||||
new RegExp(`^([a-f0-9]{32})\\.json$`),
|
||||
)
|
||||
if (!match) return null
|
||||
|
||||
return {
|
||||
id: match[1],
|
||||
md5Hash: match[1],
|
||||
name: '',
|
||||
type: '',
|
||||
source: '',
|
||||
createdAt: 0,
|
||||
updatedAt: 0,
|
||||
schemaVersion: 0,
|
||||
}
|
||||
}
|
||||
|
||||
protected generateFileName(data: ConvertData): string {
|
||||
// Format: {md5Hash}.json
|
||||
return `${data.md5Hash}.json`
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成源的MD5哈希值
|
||||
*/
|
||||
public static generateSourceHash(source: string): string {
|
||||
return createHash('md5').update(source).digest('hex')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建转换数据记录
|
||||
*/
|
||||
public async createConvertData(
|
||||
convertData: Omit<
|
||||
ConvertData,
|
||||
'id' | 'md5Hash' | 'createdAt' | 'updatedAt' | 'schemaVersion'
|
||||
>,
|
||||
): Promise<ConvertData> {
|
||||
const md5Hash = ConvertDataManager.generateSourceHash(convertData.source)
|
||||
const now = Date.now()
|
||||
|
||||
const newConvertData: ConvertData = {
|
||||
id: uuidv4(),
|
||||
md5Hash,
|
||||
...convertData,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
schemaVersion: CONVERT_DATA_SCHEMA_VERSION,
|
||||
}
|
||||
|
||||
await this.create(newConvertData)
|
||||
return newConvertData
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据源查找转换数据
|
||||
*/
|
||||
public async findBySource(source: string): Promise<ConvertData | null> {
|
||||
const md5Hash = ConvertDataManager.generateSourceHash(source)
|
||||
return this.findByHash(md5Hash)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据MD5哈希查找转换数据
|
||||
*/
|
||||
public async findByHash(md5Hash: string): Promise<ConvertData | null> {
|
||||
const fileName = `${md5Hash}.json`
|
||||
|
||||
try {
|
||||
return await this.read(fileName)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查找转换数据
|
||||
*/
|
||||
public async findById(id: string): Promise<ConvertData | null> {
|
||||
const allMetadata = await this.listMetadata()
|
||||
const targetMetadata = allMetadata.find((meta) => meta?.id === id)
|
||||
|
||||
if (!targetMetadata) return null
|
||||
|
||||
const fileName = `${targetMetadata.md5Hash}.json`
|
||||
|
||||
try {
|
||||
return await this.read(fileName)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新转换数据
|
||||
*/
|
||||
public async updateConvertData(
|
||||
id: string,
|
||||
updates: Partial<
|
||||
Omit<ConvertData, 'id' | 'md5Hash' | 'createdAt' | 'updatedAt' | 'schemaVersion'>
|
||||
>,
|
||||
): Promise<ConvertData | null> {
|
||||
const convertData = await this.findById(id)
|
||||
if (!convertData) return null
|
||||
|
||||
const updatedConvertData: ConvertData = {
|
||||
...convertData,
|
||||
...updates,
|
||||
updatedAt: Date.now(),
|
||||
}
|
||||
|
||||
await this.update(convertData, updatedConvertData)
|
||||
return updatedConvertData
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除转换数据
|
||||
*/
|
||||
public async deleteConvertData(id: string): Promise<boolean> {
|
||||
const convertData = await this.findById(id)
|
||||
if (!convertData) return false
|
||||
|
||||
const fileName = this.generateFileName(convertData)
|
||||
await this.delete(fileName)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出所有转换数据
|
||||
*/
|
||||
public async listConvertData(): Promise<ConvertData[]> {
|
||||
const allMetadata = await this.listMetadata()
|
||||
const allConvertData = await Promise.all(
|
||||
allMetadata.map(async (meta) => {
|
||||
if (!meta) return null
|
||||
|
||||
const fileName = `${meta.md5Hash}.json`
|
||||
|
||||
try {
|
||||
return await this.read(fileName)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
return allConvertData
|
||||
.filter((data): data is ConvertData => data !== null)
|
||||
.sort((a, b) => b.updatedAt - a.updatedAt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型列出转换数据
|
||||
*/
|
||||
public async listByType(type: ConvertType): Promise<ConvertData[]> {
|
||||
const allData = await this.listConvertData()
|
||||
return allData.filter((data) => data.type === type)
|
||||
}
|
||||
}
|
||||
2
src/database/json/convert-data/index.ts
Normal file
2
src/database/json/convert-data/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './types'
|
||||
export * from './ConvertDataManager'
|
||||
33
src/database/json/convert-data/types.ts
Normal file
33
src/database/json/convert-data/types.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const CONVERT_DATA_SCHEMA_VERSION = 1
|
||||
|
||||
export const convertTypeSchema = z.enum(['CONVERT_VIDEO', 'CONVERT_DOCUMENT'])
|
||||
|
||||
export type ConvertType = z.infer<typeof convertTypeSchema>
|
||||
|
||||
export const convertDataSchema = z.object({
|
||||
id: z.string().uuid("Invalid ID"),
|
||||
md5Hash: z.string().min(32, "MD5 hash must be 32 characters"), // 用于查询的md5
|
||||
name: z.string().min(1, "Name is required"), // url标题或文件名称
|
||||
type: convertTypeSchema, // CONVERT_VIDEO 或 CONVERT_DOCUMENT
|
||||
source: z.string().min(1, "Source is required"), // 转换源(视频链接或文件路径)
|
||||
contentPath: z.string().optional(), // 转换后存储的md文件路径,可能被移动
|
||||
content: z.string().min(1, "Content is required"), // 转换后的markdown文本
|
||||
createdAt: z.number().int().positive(),
|
||||
updatedAt: z.number().int().positive(),
|
||||
schemaVersion: z.literal(CONVERT_DATA_SCHEMA_VERSION),
|
||||
})
|
||||
|
||||
export type ConvertData = z.infer<typeof convertDataSchema>
|
||||
|
||||
export type ConvertDataMetadata = {
|
||||
id: string
|
||||
md5Hash: string
|
||||
name: string
|
||||
type: string
|
||||
source: string
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
schemaVersion: number
|
||||
}
|
||||
Reference in New Issue
Block a user