mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-07 05:32:52 +08:00
✨ Feature(custom): support read .env file in script system
This commit is contained in:
@@ -7,9 +7,24 @@ import { scriptsDir } from '@core/datastore/dirs'
|
|||||||
import picgo from '@core/picgo'
|
import picgo from '@core/picgo'
|
||||||
import logger from '@core/picgo/logger'
|
import logger from '@core/picgo/logger'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import dotenv from 'dotenv'
|
||||||
import fs from 'fs-extra'
|
import fs from 'fs-extra'
|
||||||
import { IPicGo } from 'piclist'
|
import { IPicGo } from 'piclist'
|
||||||
|
|
||||||
|
function getFreshEnv() {
|
||||||
|
const envPath = path.join(scriptsDir(), '.env')
|
||||||
|
|
||||||
|
if (fs.existsSync(envPath)) {
|
||||||
|
const buf = fs.readFileSync(envPath)
|
||||||
|
const config = dotenv.parse(buf)
|
||||||
|
for (const k in config) {
|
||||||
|
process.env[k] = config[k]
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
export const scriptLifecycleStages = [
|
export const scriptLifecycleStages = [
|
||||||
'onSoftwareOpen',
|
'onSoftwareOpen',
|
||||||
'onSoftwareClose',
|
'onSoftwareClose',
|
||||||
@@ -38,6 +53,7 @@ function format(data: unknown): string {
|
|||||||
|
|
||||||
export async function runScript(ctx: IPicGo, script: string, extra: Record<string, any>): Promise<any> {
|
export async function runScript(ctx: IPicGo, script: string, extra: Record<string, any>): Promise<any> {
|
||||||
try {
|
try {
|
||||||
|
const env = getFreshEnv()
|
||||||
const base64Decode = (str: string): string => Buffer.from(str, 'base64').toString('utf-8')
|
const base64Decode = (str: string): string => Buffer.from(str, 'base64').toString('utf-8')
|
||||||
const base64Encode = (data: Buffer | string): string =>
|
const base64Encode = (data: Buffer | string): string =>
|
||||||
(Buffer.isBuffer(data) ? data : Buffer.from(String(data))).toString('base64')
|
(Buffer.isBuffer(data) ? data : Buffer.from(String(data))).toString('base64')
|
||||||
@@ -62,6 +78,7 @@ export async function runScript(ctx: IPicGo, script: string, extra: Record<strin
|
|||||||
base64Encode,
|
base64Encode,
|
||||||
os,
|
os,
|
||||||
Buffer,
|
Buffer,
|
||||||
|
env,
|
||||||
}
|
}
|
||||||
vm.createContext(exposedAPI)
|
vm.createContext(exposedAPI)
|
||||||
ctx.log.info('start to run script')
|
ctx.log.info('start to run script')
|
||||||
|
|||||||
@@ -731,6 +731,7 @@
|
|||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
"disableScript": "Disable Script",
|
"disableScript": "Disable Script",
|
||||||
"duplicateScriptNameError": "Script name already exists, please use a different name",
|
"duplicateScriptNameError": "Script name already exists, please use a different name",
|
||||||
|
"editENVFile": "Edit Env File",
|
||||||
"editScript": "Edit Script",
|
"editScript": "Edit Script",
|
||||||
"emptyScriptList": "Script list is empty",
|
"emptyScriptList": "Script list is empty",
|
||||||
"enabled": "Enabled",
|
"enabled": "Enabled",
|
||||||
|
|||||||
@@ -731,6 +731,7 @@
|
|||||||
"disabled": "已禁用",
|
"disabled": "已禁用",
|
||||||
"disableScript": "禁用脚本",
|
"disableScript": "禁用脚本",
|
||||||
"duplicateScriptNameError": "脚本名称已存在,请使用不同的名称",
|
"duplicateScriptNameError": "脚本名称已存在,请使用不同的名称",
|
||||||
|
"editENVFile": "编辑环境变量",
|
||||||
"editScript": "编辑脚本",
|
"editScript": "编辑脚本",
|
||||||
"emptyScriptList": "脚本列表为空",
|
"emptyScriptList": "脚本列表为空",
|
||||||
"enabled": "已启用",
|
"enabled": "已启用",
|
||||||
|
|||||||
@@ -731,6 +731,7 @@
|
|||||||
"disabled": "已禁用",
|
"disabled": "已禁用",
|
||||||
"disableScript": "禁用腳本",
|
"disableScript": "禁用腳本",
|
||||||
"duplicateScriptNameError": "腳本名稱已存在,請使用不同的名稱",
|
"duplicateScriptNameError": "腳本名稱已存在,請使用不同的名稱",
|
||||||
|
"editENVFile": "編輯環境變量",
|
||||||
"editScript": "編輯腳本",
|
"editScript": "編輯腳本",
|
||||||
"emptyScriptList": "腳本列表為空",
|
"emptyScriptList": "腳本列表為空",
|
||||||
"enabled": "已啟用",
|
"enabled": "已啟用",
|
||||||
|
|||||||
@@ -11,6 +11,18 @@
|
|||||||
<p class="m-0 text-sm text-secondary">{{ t('pages.scripts.description') }}</p>
|
<p class="m-0 text-sm text-secondary">{{ t('pages.scripts.description') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-3 overflow-visible">
|
||||||
|
<CustomButton
|
||||||
|
type="primary"
|
||||||
|
:icon="FolderOpen"
|
||||||
|
:text="t('pages.scripts.openScriptFolder')"
|
||||||
|
@click="handleOpenScriptFolder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex w-full flex-row items-center justify-between gap-4 overflow-visible rounded-2xl border border-border-secondary px-6 py-2 shadow-md max-md:items-stretch max-md:p-5"
|
||||||
|
>
|
||||||
<div class="flex flex-wrap gap-3 overflow-visible">
|
<div class="flex flex-wrap gap-3 overflow-visible">
|
||||||
<div class="flex max-w-[220px] min-w-[180px] flex-1 flex-col gap-1">
|
<div class="flex max-w-[220px] min-w-[180px] flex-1 flex-col gap-1">
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
@@ -21,9 +33,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<CustomButton
|
<CustomButton
|
||||||
type="primary"
|
type="primary"
|
||||||
:icon="FolderOpen"
|
:icon="Edit2Icon"
|
||||||
:text="t('pages.scripts.openScriptFolder')"
|
:text="t('pages.scripts.editENVFile')"
|
||||||
@click="handleOpenScriptFolder"
|
@click="openEditPage(['.env'])"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -200,7 +212,18 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { CheckCircle2, Clock, FileCode, FolderOpen, Pencil, Play, Plus, Trash2, XIcon } from 'lucide-vue-next'
|
import {
|
||||||
|
CheckCircle2,
|
||||||
|
Clock,
|
||||||
|
Edit2Icon,
|
||||||
|
FileCode,
|
||||||
|
FolderOpen,
|
||||||
|
Pencil,
|
||||||
|
Play,
|
||||||
|
Plus,
|
||||||
|
Trash2,
|
||||||
|
XIcon,
|
||||||
|
} from 'lucide-vue-next'
|
||||||
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ export const picBedManualUrlList: IStringKeyMap = {
|
|||||||
|
|
||||||
export const defaultScriptTemplate = `
|
export const defaultScriptTemplate = `
|
||||||
// ctx 为 核心PicList实例, extra为额外参数, 其中extra.galleryItem为当前删除的相册对象
|
// ctx 为 核心PicList实例, extra为额外参数, 其中extra.galleryItem为当前删除的相册对象
|
||||||
|
// env 变量中有脚本目录下的 .env 文件内容
|
||||||
// 可用额外API: axios, crypto, fs, path, os, setTimeout, setInterval, clearTimeout, clearInterval, base64Decode, base64Encode
|
// 可用额外API: axios, crypto, fs, path, os, setTimeout, setInterval, clearTimeout, clearInterval, base64Decode, base64Encode
|
||||||
// 使用console.log或ctx.log输出的信息在软件日志文件piclist.log中可以查询到
|
// 使用console.log或ctx.log输出的信息在软件日志文件piclist.log中可以查询到
|
||||||
|
|
||||||
@@ -81,6 +82,7 @@ async function main(ctx, extra) {
|
|||||||
|
|
||||||
export const defaultScriptTemplateEn = `
|
export const defaultScriptTemplateEn = `
|
||||||
// ctx is the core PicList instance, extra is additional parameters, among which extra.galleryItem is the currently deleted album object
|
// ctx is the core PicList instance, extra is additional parameters, among which extra.galleryItem is the currently deleted album object
|
||||||
|
// env variable contains the contents of the .env file in the script directory
|
||||||
// Available additional APIs: axios, crypto, fs, path, os, setTimeout, setInterval, clearTimeout, clearInterval, base64Decode, base64Encode
|
// Available additional APIs: axios, crypto, fs, path, os, setTimeout, setInterval, clearTimeout, clearInterval, base64Decode, base64Encode
|
||||||
// Use console.log or ctx.log to output information that can be found in the software log file piclist.log
|
// Use console.log or ctx.log to output information that can be found in the software log file piclist.log
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user