-
-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
219 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// istanbul ignore file | ||
import Command from 'common-bin'; | ||
import { promises as fsp } from 'fs'; | ||
import { basename, join } from 'path'; | ||
import { createLogger } from '@surgio/logger'; | ||
import BlackSSLProvider from '../provider/BlackSSLProvider'; | ||
import ClashProvider from '../provider/ClashProvider'; | ||
import CustomProvider from '../provider/CustomProvider'; | ||
import ShadowsocksJsonSubscribeProvider from '../provider/ShadowsocksJsonSubscribeProvider'; | ||
import ShadowsocksrSubscribeProvider from '../provider/ShadowsocksrSubscribeProvider'; | ||
import ShadowsocksSubscribeProvider from '../provider/ShadowsocksSubscribeProvider'; | ||
import V2rayNSubscribeProvider from '../provider/V2rayNSubscribeProvider'; | ||
|
||
import { CommandConfig } from '../types'; | ||
import { | ||
loadConfig | ||
} from '../utils/config'; | ||
import getProvider from '../utils/get-provider'; | ||
import { errorHandler } from '../utils/error-helper'; | ||
import { formatSubscriptionUserInfo } from '../utils/subscription'; | ||
|
||
const logger = createLogger({ | ||
service: 'surgio:SubscriptionsCommand', | ||
}); | ||
type PossibleProviderType = BlackSSLProvider & ShadowsocksJsonSubscribeProvider & ShadowsocksSubscribeProvider & CustomProvider & V2rayNSubscribeProvider & ShadowsocksrSubscribeProvider & ClashProvider; | ||
|
||
class SubscriptionsCommand extends Command { | ||
private options: object; | ||
private config: CommandConfig; | ||
|
||
constructor(rawArgv) { | ||
super(rawArgv); | ||
this.usage = '使用方法: surgio subscriptions'; | ||
this.options = { | ||
c: { | ||
alias: 'config', | ||
demandOption: false, | ||
describe: 'Surgio 配置文件', | ||
default: './surgio.conf.js', | ||
type: 'string', | ||
}, | ||
}; | ||
} | ||
|
||
public async run(ctx): Promise<void> { | ||
this.config = loadConfig(ctx.cwd, ctx.argv.config); | ||
|
||
const providerList = await this.listProviders(); | ||
|
||
for (const provider of providerList) { | ||
if (provider.getSubscriptionUserInfo) { | ||
const userInfo = await provider.getSubscriptionUserInfo(); | ||
|
||
if (userInfo) { | ||
const format = formatSubscriptionUserInfo(userInfo); | ||
console.log('🤟 %s 已用流量:%s 剩余流量:%s 有效期至:%s', provider.name, format.used, format.left, format.expire); | ||
} else { | ||
console.log('⚠️ 无法查询 %s 的流量信息', provider.name); | ||
} | ||
} else { | ||
console.log('⚠️ 无法查询 %s 的流量信息', provider.name); | ||
} | ||
} | ||
} | ||
|
||
public get description(): string { | ||
return '查询订阅流量'; | ||
} | ||
|
||
public errorHandler(err): void { | ||
errorHandler.call(this, err); | ||
} | ||
|
||
private async listProviders(): Promise<ReadonlyArray<PossibleProviderType>> { | ||
const files = await fsp.readdir(this.config.providerDir, { | ||
encoding: 'utf8', | ||
}); | ||
const providerList: PossibleProviderType[] = []; | ||
|
||
async function readProvider(path): Promise<PossibleProviderType> { | ||
let provider; | ||
|
||
try { | ||
const providerName = basename(path, '.js'); | ||
|
||
logger.debug('read %s %s', providerName, path); | ||
provider = getProvider(providerName, require(path)); | ||
} catch (err) { | ||
logger.debug(`${path} 不是一个合法的模块`); | ||
return undefined; | ||
} | ||
|
||
if (!provider?.type) { | ||
logger.debug(`${path} 不是一个 Provider`); | ||
return undefined; | ||
} | ||
|
||
logger.debug('got provider %j', provider); | ||
return provider; | ||
} | ||
|
||
for (const file of files) { | ||
const result = await readProvider(join(this.config.providerDir, file)); | ||
if (result) { | ||
providerList.push(result); | ||
} | ||
} | ||
|
||
return providerList; | ||
} | ||
} | ||
|
||
export = SubscriptionsCommand; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import filesize from 'filesize'; | ||
import { format, formatDistanceToNow } from 'date-fns'; | ||
|
||
import { SubscriptionUserinfo } from '../types'; | ||
|
||
export const parseSubscriptionUserInfo = (str: string): SubscriptionUserinfo => { | ||
const res = { | ||
upload: 0, | ||
download: 0, | ||
total: 0, | ||
expire: 0, | ||
}; | ||
|
||
str.split(';').forEach(item => { | ||
const pair = item.split('='); | ||
const value = Number(pair[1].trim()); | ||
|
||
if (!Number.isNaN(value)) { | ||
res[pair[0].trim()] = Number(pair[1].trim()) | ||
} | ||
}); | ||
|
||
return res; | ||
}; | ||
|
||
export const formatSubscriptionUserInfo = (userInfo: SubscriptionUserinfo): { | ||
readonly upload: string; | ||
readonly download: string; | ||
readonly used: string; | ||
readonly left: string; | ||
readonly total: string; | ||
readonly expire: string; | ||
} => { | ||
return { | ||
upload: filesize(userInfo.upload), | ||
download: filesize(userInfo.download), | ||
used: filesize(userInfo.upload + userInfo.download), | ||
left: filesize(userInfo.total - userInfo.upload - userInfo.download), | ||
total: filesize(userInfo.total), | ||
expire: userInfo.expire | ||
? `${format(Date.now() + userInfo.expire, 'yyyy-MM-dd')} (${formatDistanceToNow(Date.now() + userInfo.expire)})` | ||
: '无数据', | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters