Skip to content

Commit

Permalink
✨ 腾讯云触发器
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Jan 26, 2022
1 parent af5bd71 commit a706827
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 42 deletions.
25 changes: 18 additions & 7 deletions src/pkg/sdk/tencent_cloud/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ export interface Api {
version: string
}

export interface Response {
Error?: {
Code: string
Message: string
}
RequestId: string
}

export interface JsonResponse<T> {
Response: T
}

export class Client {
config: ClientConfig;
api: Api
Expand All @@ -31,8 +43,8 @@ export class Client {
this.api = api;
}

protected request(action: string, req: AnyMap): Promise<AnyMap> {
return new Promise(resolve => {
protected request<T=Response>(action: string, req: AnyMap): Promise<JsonResponse<T>> {
return new Promise((resolve) => {

const algorithm = 'TC3-HMAC-SHA256'
const now = new Date();
Expand Down Expand Up @@ -69,21 +81,20 @@ export class Client {
const handler = async () => {
const headers: AnyMap = {
'X-TC-Action': action,
'X-TC-Region': this.config.region,
'X-TC-Timestamp': unixTime(),
'X-TC-Version': this.api.version,
'X-TC-Language': 'zh-CN',
'Authorization': Authorization,
'Content-Type': 'application/json; charset=utf-8'
};
if (!this.config.region) {
delete headers['X-TC-Region'];
if (this.config.region) {
headers['X-TC-Region'] = this.config.region;
}
const resp = await axios.post('https://' + this.api.url, payload, {
headers: headers,
responseType: 'json',
});

resolve(<AnyMap>resp.data);
resolve(<JsonResponse<T>>resp.data);
}
void handler();
});
Expand Down
35 changes: 27 additions & 8 deletions src/pkg/sdk/tencent_cloud/scf.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Client, ClientConfig } from './client';
import { Client, ClientConfig, Response } from './client';

export interface CreateFunctionRequest {
FunctionName: string,
Expand All @@ -8,28 +8,47 @@ export interface CreateFunctionRequest {
},
Handler?: string
Type?: 'Event'
Runtime?: 'Python2.7' | 'Python3.6' | 'Nodejs10.15' | 'Nodejs12.16' | ' Php5' | ' Php7' | 'Go1' | 'Java8' | 'CustomRuntime'
Runtime?: 'Python2.7' | 'Python3.6' | 'Nodejs10.15' | 'Nodejs12.16' | 'Php5' | 'Php7' | 'Go1' | 'Java8' | 'CustomRuntime'
Description?: string
InstallDependency?: 'TRUE' | 'FALSE'
}

export interface CreateTriggerRequest {
FunctionName: string,
TriggerName: string
Type: 'timer'
TriggerDesc?: string
}

export interface GetFunctionRequest {
FunctionName: string
}

export interface GetFunctionResponse extends Response {
FunctionName: string
}

export class ScfClient extends Client {

constructor(client: ClientConfig) {
let url = 'scf';
if (client.region != '') {
url += '.' + client.region;
}
url += '.tencentcloudapi.com';
super(client, {
url: url,
url: 'scf.tencentcloudapi.com',
service: 'scf',
version: '2018-04-16',
});
}

GetFunction(req: GetFunctionRequest) {
return this.request<GetFunctionResponse>('GetFunction', req);
}

// 创建新的函数
CreateFunction(req: CreateFunctionRequest) {
return this.request('CreateFunction', req);
}

CreateTrigger(req: CreateTriggerRequest) {
return this.request('CreateTrigger', req);
}

}
2 changes: 1 addition & 1 deletion src/pkg/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function isFirefox() {
}

export function SendLogger(level: LOGGER_LEVEL, origin: string, msg: string, title = '', scriptId?: number) {
top!.postMessage(
top?.postMessage(
{
action: Logger,
data: {
Expand Down
85 changes: 75 additions & 10 deletions src/views/components/BgCloud.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
</v-icon>
</template>
<template v-slot:default="dialog">
<v-snackbar
v-model="snackbar"
timeout="5000"
multi-line
:color="snackbarColor"
>
{{ snackbarText }}
<template v-slot:action="{ attrs }">
<v-btn text v-bind="attrs" @click="snackbar = false"> 关闭 </v-btn>
</template>
</v-snackbar>
<v-card>
<v-toolbar color="primary" dark>
<v-toolbar-title>上传至云端执行</v-toolbar-title>
Expand All @@ -17,6 +28,9 @@
</v-toolbar-items>
</v-toolbar>
<div style="padding: 10px; box-sizing: border-box">
<a href="https://docs.scriptcat.org/dev/cloudcat.html" target="_blank"
>云端执行文档</a
>
<v-input :v-model="exportConfig.uuid" disabled> </v-input>
<v-select
label="上传至"
Expand All @@ -41,6 +55,7 @@
<v-text-field
v-if="exportConfig.param"
v-model="exportConfig.param.secretKey"
type="password"
label="SecretKey"
>
</v-text-field>
Expand All @@ -53,6 +68,7 @@
item-value="key"
hint="地域请查看 https://cloud.tencent.com/document/product/583/17237"
persistent-hint
return-object
single-line
></v-select>
</div>
Expand Down Expand Up @@ -87,6 +103,9 @@
<div v-else-if="exportConfig.dest == 'remote'"></div>
</div>
<v-card-actions class="justify-end">
<v-btn text color="error" @click="clear">{{
btnText[exportConfig.dest] || "清除配置"
}}</v-btn>
<v-btn text color="success" @click="submit">{{
btnText[exportConfig.dest] || "提交"
}}</v-btn>
Expand Down Expand Up @@ -122,7 +141,7 @@ import { ScfClient } from '@App/pkg/sdk/tencent_cloud/scf';
interface TencentCloud {
secretId: string;
secretKey: string;
region: { key: string; value: string };
region: string;
regionList: { key: string; value: string }[];
}
Expand All @@ -132,6 +151,10 @@ export default class BgCloud extends Vue {
icons = { mdiCloudUpload, mdiClose };
snackbar = false;
snackbarText = '';
snackbarColor = 'red';
@Prop()
script!: Script;
exportConfig: Export = {
Expand Down Expand Up @@ -160,9 +183,8 @@ export default class BgCloud extends Vue {
param: <TencentCloud>{
secretId: '',
secretKey: '',
region: { value: '就近地域接入', key: '' },
region: 'ap-shanghai',
regionList: [
{ value: '就近地域接入', key: '' },
{ value: '华东地区(上海)', key: 'ap-shanghai' },
{ value: '华北地区(北京)', key: 'ap-beijing' },
{ value: '西南地区(成都)', key: 'ap-chengdu' },
Expand Down Expand Up @@ -235,6 +257,17 @@ export default class BgCloud extends Vue {
}
}
async clear() {
let e = await this.exportModel.findOne({
scriptId: this.script.id,
dest: this.exportDest.key,
});
if (e) {
await this.exportModel.delete(e.id);
}
void this.onChangeDest();
}
submit() {
this.exportConfig.dest = <EXPORT_DEST>this.exportDest.key;
switch (this.exportDest.key) {
Expand All @@ -249,32 +282,64 @@ export default class BgCloud extends Vue {
}
async tencent() {
const param = <TencentCloud>this.exportDest.param;
let crontab =
this.script.metadata['crontab'] && this.script.metadata['crontab'][0];
if (!crontab) {
this.message('未检测到@crontab声明暂时只支持定时脚本');
return;
}
const param = <TencentCloud>this.exportConfig.param;
const clientConfig: ClientConfig = {
credential: {
secretId: param.secretId,
secretKey: param.secretKey,
},
region: param.region.key,
region: param.region,
profile: {
httpProfile: {
reqMethod: 'POST', // 请求方法
reqTimeout: 30, // 请求超时时间,默认60s
reqMethod: 'POST',
reqTimeout: 30,
},
},
};
const cli = new ScfClient(clientConfig);
let zip = await this.pack();
void zip.generateAsync({ type: 'base64' }).then((content) => {
void cli.CreateFunction({
FunctionName: 'test',
void zip.generateAsync({ type: 'base64' }).then(async (content) => {
const resp = await cli.CreateFunction({
FunctionName: this.script.uuid,
Code: {
ZipFile: content,
},
Handler: 'utils.run',
Type: 'Event',
Runtime: 'Nodejs12.16',
Description:
this.script.name +
' ' +
(this.script.metadata['description'] &&
this.script.metadata['description'][0]),
InstallDependency: 'TRUE',
});
if (resp.Response.Error) {
this.message(
'上传失败! ' +
resp.Response.Error.Code +
': ' +
resp.Response.Error.Message
);
return;
}
this.message('上传成功!请前往云函数控制台查看详情!', 'success');
});
}
message(text: string, color = 'red') {
this.snackbar = true;
this.snackbarText = text;
this.snackbarColor = color;
}
async local() {
let zip = await this.pack();
void zip.generateAsync({ type: 'blob' }).then((content) => {
Expand Down
50 changes: 50 additions & 0 deletions src/views/pages/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,53 @@ export function parseStorageValue(str: string): any {
return str;
}
}


// 处理once的crontab表达式,将once之前的时间替换成最小值运行.
export function parseOnceCrontab(crontab: string): string {
const ss = crontab.split(' ');
switch (ss.length) {
case 5:
ss.unshift('0');
break;
case 6:
break;
default:
return '';
}
const cron: string[] = [];
for (let i = 0; i < ss.length; i++) {
if (ss[i] == 'once') {
cron.push('*');
// 将之前的时间替换为最小值
let n = i - 1;
for (; n >= 0; n--) {
if (cron[n][0] == '*') {
// 为*替换为当前位最小值
switch (n) {
// 秒 分 时
case 0:
case 1:
case 2:
cron[n] = '0'
break
// 日 月
case 3:
case 4:
cron[n] = '1'
break
}
} else if (cron[n].indexOf('-') !== -1) {
// 为一个范围,替换为范围内最小值
cron[n] = cron[n].split('-')[0];
} else if (cron[n].indexOf(',') !== -1) {
// 取第一个分割
cron[n] = cron[n].split(',')[0];
}
}
} else {
cron.push(ss[i]);
}
}
return cron.join(' ');
}
Loading

0 comments on commit a706827

Please sign in to comment.