support custom webdav directory

This commit is contained in:
pompurin404 2024-10-11 11:27:08 +08:00
parent e7ba8e7739
commit 2f1eabcdc9
No known key found for this signature in database
4 changed files with 50 additions and 13 deletions

View File

@ -1,4 +1,9 @@
### New Features
- 支持自定义 WebDAV 备份目录名称
### Bug Fixes ### Bug Fixes
- 修复 macOS 自动更新失败的问题 - 修复 macOS 自动更新失败的问题
- 修复订阅点击无法切换的问题
- 修复某些 Windows 管理员权限依然无法启动的问题 - 修复某些 Windows 管理员权限依然无法启动的问题

View File

@ -15,7 +15,12 @@ import {
export async function webdavBackup(): Promise<boolean> { export async function webdavBackup(): Promise<boolean> {
const { createClient } = await import('webdav/dist/node/index.js') const { createClient } = await import('webdav/dist/node/index.js')
const { webdavUrl = '', webdavUsername = '', webdavPassword = '' } = await getAppConfig() const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'mihomo-party'
} = await getAppConfig()
const zip = new AdmZip() const zip = new AdmZip()
zip.addLocalFile(appConfigPath()) zip.addLocalFile(appConfigPath())
@ -34,36 +39,46 @@ export async function webdavBackup(): Promise<boolean> {
password: webdavPassword password: webdavPassword
}) })
try { try {
await client.createDirectory('mihomo-party') await client.createDirectory(webdavDir)
} catch { } catch {
// ignore // ignore
} }
return await client.putFileContents(`mihomo-party/${zipFileName}`, zip.toBuffer()) return await client.putFileContents(`${webdavDir}/${zipFileName}`, zip.toBuffer())
} }
export async function webdavRestore(filename: string): Promise<void> { export async function webdavRestore(filename: string): Promise<void> {
const { createClient } = await import('webdav/dist/node/index.js') const { createClient } = await import('webdav/dist/node/index.js')
const { webdavUrl = '', webdavUsername = '', webdavPassword = '' } = await getAppConfig() const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'mihomo-party'
} = await getAppConfig()
const client = createClient(webdavUrl, { const client = createClient(webdavUrl, {
username: webdavUsername, username: webdavUsername,
password: webdavPassword password: webdavPassword
}) })
const zipData = await client.getFileContents(`mihomo-party/${filename}`) const zipData = await client.getFileContents(`${webdavDir}/${filename}`)
const zip = new AdmZip(zipData as Buffer) const zip = new AdmZip(zipData as Buffer)
zip.extractAllTo(dataDir(), true) zip.extractAllTo(dataDir(), true)
} }
export async function listWebdavBackups(): Promise<string[]> { export async function listWebdavBackups(): Promise<string[]> {
const { createClient } = await import('webdav/dist/node/index.js') const { createClient } = await import('webdav/dist/node/index.js')
const { webdavUrl = '', webdavUsername = '', webdavPassword = '' } = await getAppConfig() const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'mihomo-party'
} = await getAppConfig()
const client = createClient(webdavUrl, { const client = createClient(webdavUrl, {
username: webdavUsername, username: webdavUsername,
password: webdavPassword password: webdavPassword
}) })
const files = await client.getDirectoryContents('mihomo-party', { glob: '*.zip' }) const files = await client.getDirectoryContents(webdavDir, { glob: '*.zip' })
if (Array.isArray(files)) { if (Array.isArray(files)) {
return files.map((file) => file.basename) return files.map((file) => file.basename)
} else { } else {
@ -73,11 +88,16 @@ export async function listWebdavBackups(): Promise<string[]> {
export async function webdavDelete(filename: string): Promise<void> { export async function webdavDelete(filename: string): Promise<void> {
const { createClient } = await import('webdav/dist/node/index.js') const { createClient } = await import('webdav/dist/node/index.js')
const { webdavUrl = '', webdavUsername = '', webdavPassword = '' } = await getAppConfig() const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'mihomo-party'
} = await getAppConfig()
const client = createClient(webdavUrl, { const client = createClient(webdavUrl, {
username: webdavUsername, username: webdavUsername,
password: webdavPassword password: webdavPassword
}) })
await client.deleteFile(`mihomo-party/${filename}`) await client.deleteFile(`${webdavDir}/${filename}`)
} }

View File

@ -9,15 +9,15 @@ import { useAppConfig } from '@renderer/hooks/use-app-config'
const WebdavConfig: React.FC = () => { const WebdavConfig: React.FC = () => {
const { appConfig, patchAppConfig } = useAppConfig() const { appConfig, patchAppConfig } = useAppConfig()
const { webdavUrl, webdavUsername, webdavPassword } = appConfig || {} const { webdavUrl, webdavUsername, webdavPassword, webdavDir = 'mihomo-party' } = appConfig || {}
const [backuping, setBackuping] = useState(false) const [backuping, setBackuping] = useState(false)
const [restoring, setRestoring] = useState(false) const [restoring, setRestoring] = useState(false)
const [filenames, setFilenames] = useState<string[]>([]) const [filenames, setFilenames] = useState<string[]>([])
const [restoreOpen, setRestoreOpen] = useState(false) const [restoreOpen, setRestoreOpen] = useState(false)
const [webdav, setWebdav] = useState({ webdavUrl, webdavUsername, webdavPassword }) const [webdav, setWebdav] = useState({ webdavUrl, webdavUsername, webdavPassword, webdavDir })
const setWebdavDebounce = debounce(({ webdavUrl, webdavUsername, webdavPassword }) => { const setWebdavDebounce = debounce(({ webdavUrl, webdavUsername, webdavPassword, webdavDir }) => {
patchAppConfig({ webdavUrl, webdavUsername, webdavPassword }) patchAppConfig({ webdavUrl, webdavUsername, webdavPassword, webdavDir })
}, 500) }, 500)
const handleBackup = async (): Promise<void> => { const handleBackup = async (): Promise<void> => {
setBackuping(true) setBackuping(true)
@ -60,6 +60,17 @@ const WebdavConfig: React.FC = () => {
}} }}
/> />
</SettingItem> </SettingItem>
<SettingItem title="WebDAV 备份目录" divider>
<Input
size="sm"
className="w-[60%]"
value={webdav.webdavDir}
onValueChange={(v) => {
setWebdav({ ...webdav, webdavDir: v })
setWebdavDebounce({ ...webdav, webdavDir: v })
}}
/>
</SettingItem>
<SettingItem title="WebDAV 用户名" divider> <SettingItem title="WebDAV 用户名" divider>
<Input <Input
size="sm" size="sm"

View File

@ -260,6 +260,7 @@ interface IAppConfig {
useDockIcon?: boolean useDockIcon?: boolean
showTraffic?: boolean showTraffic?: boolean
webdavUrl?: string webdavUrl?: string
webdavDir?: string
webdavUsername?: string webdavUsername?: string
webdavPassword?: string webdavPassword?: string
useNameserverPolicy: boolean useNameserverPolicy: boolean