mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-15 19:22:31 +08:00
support sync runtime config to github gist
This commit is contained in:
parent
80f22e719a
commit
4c238e1bdf
|
@ -1,6 +1,7 @@
|
|||
### Features
|
||||
|
||||
- 支持在特定WiFi SSID下直连
|
||||
- 支持同步运行时配置到GitHub Gist
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import { promisify } from 'util'
|
|||
import { mainWindow } from '..'
|
||||
import path from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import { uploadRuntimeConfig } from '../resolve/gistApi'
|
||||
|
||||
chokidar.watch(path.join(mihomoCoreDir(), 'meta-update'), {}).on('unlinkDir', async () => {
|
||||
try {
|
||||
|
@ -137,6 +138,7 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
|
|||
if (data.toString().includes('Start initial Compatible provider default')) {
|
||||
try {
|
||||
mainWindow?.webContents.send('coreRestart')
|
||||
await uploadRuntimeConfig()
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
|
99
src/main/resolve/gistApi.ts
Normal file
99
src/main/resolve/gistApi.ts
Normal file
|
@ -0,0 +1,99 @@
|
|||
import axios from 'axios'
|
||||
import { getAppConfig, getControledMihomoConfig } from '../config'
|
||||
import { getRuntimeConfigStr } from '../core/factory'
|
||||
|
||||
interface GistInfo {
|
||||
id: string
|
||||
description: string
|
||||
files: Record<string, { filename: string; raw_url: string }>
|
||||
}
|
||||
|
||||
async function listGists(token: string): Promise<GistInfo[]> {
|
||||
const { 'mixed-port': port = 7890 } = await getControledMihomoConfig()
|
||||
const res = await axios.get('https://api.github.com/gists', {
|
||||
headers: {
|
||||
Accept: 'application/vnd.github+json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
},
|
||||
proxy: {
|
||||
protocol: 'http',
|
||||
host: '127.0.0.1',
|
||||
port
|
||||
}
|
||||
})
|
||||
return res.data as GistInfo[]
|
||||
}
|
||||
|
||||
async function createGist(token: string, content: string): Promise<void> {
|
||||
const { 'mixed-port': port = 7890 } = await getControledMihomoConfig()
|
||||
return await axios.post(
|
||||
'https://api.github.com/gists',
|
||||
{
|
||||
description: 'Auto Synced Mihomo Party Runtime Config',
|
||||
public: false,
|
||||
files: { 'mihomo-party.yaml': { content } }
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/vnd.github+json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
},
|
||||
proxy: {
|
||||
protocol: 'http',
|
||||
host: '127.0.0.1',
|
||||
port
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async function updateGist(token: string, id: string, content: string): Promise<void> {
|
||||
const { 'mixed-port': port = 7890 } = await getControledMihomoConfig()
|
||||
return await axios.patch(
|
||||
`https://api.github.com/gists/${id}`,
|
||||
{
|
||||
description: 'Auto Synced Mihomo Party Runtime Config',
|
||||
files: { 'mihomo-party.yaml': { content } }
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/vnd.github+json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
},
|
||||
proxy: {
|
||||
protocol: 'http',
|
||||
host: '127.0.0.1',
|
||||
port
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export async function getGistUrl(): Promise<string> {
|
||||
const { githubToken } = await getAppConfig()
|
||||
if (!githubToken) return ''
|
||||
const gists = await listGists(githubToken)
|
||||
const gist = gists.find((gist) => gist.description === 'Auto Synced Mihomo Party Runtime Config')
|
||||
if (gist) {
|
||||
return gist.files['mihomo-party.yaml'].raw_url
|
||||
} else {
|
||||
throw new Error('Gist not found')
|
||||
}
|
||||
}
|
||||
|
||||
export async function uploadRuntimeConfig(): Promise<void> {
|
||||
const { githubToken } = await getAppConfig()
|
||||
if (!githubToken) return
|
||||
const gists = await listGists(githubToken)
|
||||
console.log(gists)
|
||||
const gist = gists.find((gist) => gist.description === 'Auto Synced Mihomo Party Runtime Config')
|
||||
const config = await getRuntimeConfigStr()
|
||||
if (gist) {
|
||||
await updateGist(githubToken, gist.id, config)
|
||||
} else {
|
||||
await createGist(githubToken, config)
|
||||
}
|
||||
}
|
|
@ -77,6 +77,7 @@ import { subStoreCollections, subStoreSubs } from '../core/subStoreApi'
|
|||
import { logDir } from './dirs'
|
||||
import path from 'path'
|
||||
import v8 from 'v8'
|
||||
import { getGistUrl } from '../resolve/gistApi'
|
||||
|
||||
function ipcErrorWrapper<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
fn: (...args: any[]) => Promise<T> // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
@ -188,6 +189,7 @@ export function registerIpcMainHandlers(): void {
|
|||
ipcMain.handle('subStoreFrontendPort', () => subStoreFrontendPort)
|
||||
ipcMain.handle('subStoreSubs', () => ipcErrorWrapper(subStoreSubs)())
|
||||
ipcMain.handle('subStoreCollections', () => ipcErrorWrapper(subStoreCollections)())
|
||||
ipcMain.handle('getGistUrl', ipcErrorWrapper(getGistUrl))
|
||||
ipcMain.handle('setNativeTheme', (_e, theme) => {
|
||||
setNativeTheme(theme)
|
||||
})
|
||||
|
|
|
@ -4,8 +4,9 @@ import SettingItem from '../base/base-setting-item'
|
|||
import { Button, Input, Select, SelectItem, Switch } from '@nextui-org/react'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import debounce from '@renderer/utils/debounce'
|
||||
import { patchControledMihomoConfig, restartCore } from '@renderer/utils/ipc'
|
||||
import { getGistUrl, patchControledMihomoConfig, restartCore } from '@renderer/utils/ipc'
|
||||
import { MdDeleteForever } from 'react-icons/md'
|
||||
import { BiCopy } from 'react-icons/bi'
|
||||
|
||||
const MihomoConfig: React.FC = () => {
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
|
@ -13,6 +14,7 @@ const MihomoConfig: React.FC = () => {
|
|||
controlDns = true,
|
||||
controlSniff = true,
|
||||
delayTestTimeout,
|
||||
githubToken = '',
|
||||
autoCloseConnection = true,
|
||||
pauseSSID = [],
|
||||
delayTestUrl,
|
||||
|
@ -66,6 +68,41 @@ const MihomoConfig: React.FC = () => {
|
|||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem
|
||||
title="同步运行时配置到 Gist"
|
||||
actions={
|
||||
<Button
|
||||
title="复制 Gist URL"
|
||||
isIconOnly
|
||||
size="sm"
|
||||
variant="light"
|
||||
onPress={async () => {
|
||||
try {
|
||||
const url = await getGistUrl()
|
||||
if (url !== '') {
|
||||
await navigator.clipboard.writeText(url)
|
||||
}
|
||||
} catch (e) {
|
||||
alert(e)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<BiCopy className="text-lg" />
|
||||
</Button>
|
||||
}
|
||||
divider
|
||||
>
|
||||
<Input
|
||||
type="password"
|
||||
size="sm"
|
||||
className="w-[60%]"
|
||||
value={githubToken}
|
||||
placeholder="GitHub Token"
|
||||
onValueChange={(v) => {
|
||||
patchAppConfig({ githubToken: v })
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem title="代理节点展示列数" divider>
|
||||
<Select
|
||||
className="w-[150px]"
|
||||
|
|
|
@ -295,6 +295,10 @@ export async function setNativeTheme(theme: 'system' | 'light' | 'dark'): Promis
|
|||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setNativeTheme', theme))
|
||||
}
|
||||
|
||||
export async function getGistUrl(): Promise<string> {
|
||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('getGistUrl'))
|
||||
}
|
||||
|
||||
export async function startSubStoreServer(): Promise<void> {
|
||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('startSubStoreServer'))
|
||||
}
|
||||
|
|
1
src/shared/types.d.ts
vendored
1
src/shared/types.d.ts
vendored
|
@ -224,6 +224,7 @@ interface IAppConfig {
|
|||
substoreCardStatus?: CardStatus
|
||||
sysproxyCardStatus?: CardStatus
|
||||
tunCardStatus?: CardStatus
|
||||
githubToken?: string
|
||||
useSubStore: boolean
|
||||
subStoreBackendSyncCron?: string
|
||||
subStoreBackendDownloadCron?: string
|
||||
|
|
Loading…
Reference in New Issue
Block a user