feat(site): implement site status management and update related components

This commit is contained in:
Jacky 2025-04-14 02:11:53 +00:00
parent 402de5d987
commit 502b656bc5
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
12 changed files with 93 additions and 99 deletions

View file

@ -28,11 +28,6 @@ func GetSite(c *gin.Context) {
return return
} }
enabled := true
if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) {
enabled = false
}
g := query.ChatGPTLog g := query.ChatGPTLog
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
@ -63,15 +58,15 @@ func GetSite(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, Site{ c.JSON(http.StatusOK, site.Site{
ModifiedAt: file.ModTime(), ModifiedAt: file.ModTime(),
Site: siteModel, Site: siteModel,
Enabled: enabled,
Name: name, Name: name,
Config: string(origContent), Config: string(origContent),
AutoCert: certModel.AutoCert == model.AutoCertEnabled, AutoCert: certModel.AutoCert == model.AutoCertEnabled,
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
Filepath: path, Filepath: path,
Status: site.GetSiteStatus(name),
}) })
return return
} }
@ -96,10 +91,9 @@ func GetSite(c *gin.Context) {
} }
} }
c.JSON(http.StatusOK, Site{ c.JSON(http.StatusOK, site.Site{
Site: siteModel, Site: siteModel,
ModifiedAt: file.ModTime(), ModifiedAt: file.ModTime(),
Enabled: enabled,
Name: name, Name: name,
Config: nginxConfig.FmtCode(), Config: nginxConfig.FmtCode(),
Tokenized: nginxConfig, Tokenized: nginxConfig,
@ -107,6 +101,7 @@ func GetSite(c *gin.Context) {
CertInfo: certInfoMap, CertInfo: certInfoMap,
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
Filepath: path, Filepath: path,
Status: site.GetSiteStatus(name),
}) })
} }

View file

@ -3,15 +3,16 @@ import type { ModelBase } from '@/api/curd'
import type { EnvGroup } from '@/api/env_group' import type { EnvGroup } from '@/api/env_group'
import type { NgxConfig } from '@/api/ngx' import type { NgxConfig } from '@/api/ngx'
import type { ChatComplicationMessage } from '@/api/openai' import type { ChatComplicationMessage } from '@/api/openai'
import type { PrivateKeyType } from '@/constants' import type { ConfigStatus, PrivateKeyType } from '@/constants'
import Curd from '@/api/curd' import Curd from '@/api/curd'
import http from '@/lib/http' import http from '@/lib/http'
export type SiteStatus = ConfigStatus.Enabled | ConfigStatus.Disabled | ConfigStatus.Maintenance
export interface Site extends ModelBase { export interface Site extends ModelBase {
modified_at: string modified_at: string
path: string path: string
advanced: boolean advanced: boolean
enabled: boolean
name: string name: string
filepath: string filepath: string
config: string config: string
@ -23,7 +24,7 @@ export interface Site extends ModelBase {
env_group?: EnvGroup env_group?: EnvGroup
sync_node_ids: number[] sync_node_ids: number[]
urls?: string[] urls?: string[]
status: string status: SiteStatus
} }
export interface AutoCertRequest { export interface AutoCertRequest {

View file

@ -1,6 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Cert, CertificateInfo } from '@/api/cert' import type { Cert, CertificateInfo } from '@/api/cert'
import type { NgxDirective } from '@/api/ngx' import type { NgxDirective } from '@/api/ngx'
import type { SiteStatus } from '@/api/site'
import { ConfigStatus } from '@/constants'
import CertInfo from '@/views/site/cert/CertInfo.vue' import CertInfo from '@/views/site/cert/CertInfo.vue'
import ChangeCert from '@/views/site/cert/components/ChangeCert/ChangeCert.vue' import ChangeCert from '@/views/site/cert/components/ChangeCert/ChangeCert.vue'
import IssueCert from '@/views/site/cert/IssueCert.vue' import IssueCert from '@/views/site/cert/IssueCert.vue'
@ -9,7 +11,7 @@ const props = defineProps<{
configName: string configName: string
currentServerIndex: number currentServerIndex: number
certInfo?: CertificateInfo[] certInfo?: CertificateInfo[]
siteEnabled: boolean siteStatus: SiteStatus
}>() }>()
const current_server_directives = defineModel<NgxDirective[]>('current_server_directives') const current_server_directives = defineModel<NgxDirective[]>('current_server_directives')
@ -96,7 +98,7 @@ function handleCertChange(certs: Cert[]) {
<ChangeCert @change="handleCertChange" /> <ChangeCert @change="handleCertChange" />
<IssueCert <IssueCert
v-if="siteEnabled" v-if="siteStatus === ConfigStatus.Enabled || siteStatus === ConfigStatus.Maintenance"
v-model:enabled="enabled" v-model:enabled="enabled"
:config-name="configName" :config-name="configName"
/> />

View file

@ -1,28 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SiteStatus } from '@/api/site'
import site from '@/api/site' import site from '@/api/site'
import { ConfigStatus } from '@/constants' import { ConfigStatus } from '@/constants'
import { message, Modal } from 'ant-design-vue' import { message, Modal } from 'ant-design-vue'
/**
* Component props interface
*/
interface Props {
/**
* The name of the site configuration
*/
siteName: string
/**
* Whether the site is enabled
*/
enabled: boolean
}
// Define props with TypeScript // Define props with TypeScript
const props = defineProps<Props>() const props = defineProps<{
siteName: string
}>()
// Define event for status change notification // Define event for status change notification
const emit = defineEmits<{ const emit = defineEmits<{
statusChanged: [{ status: string, enabled: boolean }] statusChanged: [{ status: SiteStatus }]
}>() }>()
// Use defineModel for v-model binding // Use defineModel for v-model binding
@ -32,73 +21,59 @@ const status = defineModel<string>({
const [modal, ContextHolder] = Modal.useModal() const [modal, ContextHolder] = Modal.useModal()
/** // Enable the site
* Enable the site
*/
function enable() { function enable() {
site.enable(props.siteName).then(() => { site.enable(props.siteName).then(() => {
message.success($gettext('Enabled successfully')) message.success($gettext('Enabled successfully'))
status.value = ConfigStatus.Enabled status.value = ConfigStatus.Enabled
emit('statusChanged', { emit('statusChanged', {
status: ConfigStatus.Enabled, status: ConfigStatus.Enabled,
enabled: true,
}) })
}).catch(r => { }).catch(r => {
message.error($gettext('Failed to enable %{msg}', { msg: r.message ?? '' }), 10) message.error($gettext('Failed to enable %{msg}', { msg: r.message ?? '' }), 10)
}) })
} }
/** // Disable the site
* Disable the site
*/
function disable() { function disable() {
site.disable(props.siteName).then(() => { site.disable(props.siteName).then(() => {
message.success($gettext('Disabled successfully')) message.success($gettext('Disabled successfully'))
status.value = ConfigStatus.Disabled status.value = ConfigStatus.Disabled
emit('statusChanged', { emit('statusChanged', {
status: ConfigStatus.Disabled, status: ConfigStatus.Disabled,
enabled: false,
}) })
}).catch(r => { }).catch(r => {
message.error($gettext('Failed to disable %{msg}', { msg: r.message ?? '' })) message.error($gettext('Failed to disable %{msg}', { msg: r.message ?? '' }))
}) })
} }
/** // Enable maintenance mode for the site
* Enable maintenance mode for the site
*/
function enableMaintenance() { function enableMaintenance() {
site.enableMaintenance(props.siteName).then(() => { site.enableMaintenance(props.siteName).then(() => {
message.success($gettext('Maintenance mode enabled successfully')) message.success($gettext('Maintenance mode enabled successfully'))
status.value = ConfigStatus.Maintenance status.value = ConfigStatus.Maintenance
emit('statusChanged', { emit('statusChanged', {
status: ConfigStatus.Maintenance, status: ConfigStatus.Maintenance,
enabled: true,
}) })
}).catch(r => { }).catch(r => {
message.error($gettext('Failed to enable maintenance mode %{msg}', { msg: r.message ?? '' })) message.error($gettext('Failed to enable maintenance mode %{msg}', { msg: r.message ?? '' }))
}) })
} }
/** // Disable maintenance mode for the site
* Disable maintenance mode for the site
*/
function disableMaintenance() { function disableMaintenance() {
site.enable(props.siteName).then(() => { site.enable(props.siteName).then(() => {
message.success($gettext('Maintenance mode disabled successfully')) message.success($gettext('Maintenance mode disabled successfully'))
status.value = ConfigStatus.Enabled status.value = ConfigStatus.Enabled
emit('statusChanged', { emit('statusChanged', {
status: ConfigStatus.Enabled, status: ConfigStatus.Enabled,
enabled: true,
}) })
}).catch(r => { }).catch(r => {
message.error($gettext('Failed to disable maintenance mode %{msg}', { msg: r.message ?? '' })) message.error($gettext('Failed to disable maintenance mode %{msg}', { msg: r.message ?? '' }))
}) })
} }
/** // Handle status change from segmented control
* Handle status change from segmented control
*/
function onChangeStatus(value: string | number) { function onChangeStatus(value: string | number) {
const statusValue = value as string const statusValue = value as string
if (statusValue === status.value) { if (statusValue === status.value) {
@ -148,7 +123,7 @@ function onChangeStatus(value: string | number) {
<div class="site-status-segmented"> <div class="site-status-segmented">
<ContextHolder /> <ContextHolder />
<ASegmented <ASegmented
v-model:value="status" :value="status"
:options="[ :options="[
{ {
value: ConfigStatus.Enabled, value: ConfigStatus.Enabled,

View file

@ -1,27 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CertificateInfo } from '@/api/cert' import type { CertificateInfo } from '@/api/cert'
import type { NgxConfig, NgxDirective } from '@/api/ngx' import type { NgxConfig, NgxDirective } from '@/api/ngx'
import type { SiteStatus } from '@/api/site'
import type { CheckedType } from '@/types' import type { CheckedType } from '@/types'
import type { ComputedRef } from 'vue' import type { ComputedRef } from 'vue'
import template from '@/api/template' import template from '@/api/template'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue' import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
import { ConfigStatus } from '@/constants'
import NginxStatusAlert from '@/views/site/ngx_conf/NginxStatusAlert.vue' import NginxStatusAlert from '@/views/site/ngx_conf/NginxStatusAlert.vue'
import NgxServer from '@/views/site/ngx_conf/NgxServer.vue' import NgxServer from '@/views/site/ngx_conf/NgxServer.vue'
import NgxUpstream from '@/views/site/ngx_conf/NgxUpstream.vue' import NgxUpstream from '@/views/site/ngx_conf/NgxUpstream.vue'
import { Modal } from 'ant-design-vue' import { Modal } from 'ant-design-vue'
const props = withDefaults(defineProps<{ withDefaults(defineProps<{
autoCert?: boolean status?: SiteStatus
enabled?: boolean
certInfo?: Record<number, CertificateInfo[]> certInfo?: Record<number, CertificateInfo[]>
context?: 'http' | 'stream' context?: 'http' | 'stream'
}>(), { }>(), {
autoCert: false, status: ConfigStatus.Enabled,
enabled: false,
context: 'http', context: 'http',
}) })
const emit = defineEmits(['callback', 'update:autoCert']) const autoCert = defineModel<boolean>('autoCert')
const save_config = inject('save_config') as () => Promise<void> const save_config = inject('save_config') as () => Promise<void>
@ -158,15 +158,6 @@ const support_ssl = computed(() => {
return false return false
}) })
const autoCertRef = computed({
get() {
return props.autoCert
},
set(value) {
emit('update:autoCert', value)
},
})
provide('directivesMap', directivesMap) provide('directivesMap', directivesMap)
const activeKey = ref(['3']) const activeKey = ref(['3'])
@ -211,9 +202,9 @@ const activeKey = ref(['3'])
header="Server" header="Server"
> >
<NgxServer <NgxServer
v-model:auto-cert="autoCertRef" v-model:auto-cert="autoCert"
:enabled :status
:cert-info="certInfo" :cert-info
:context :context
/> />
</ACollapsePanel> </ACollapsePanel>

View file

@ -1,6 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CertificateInfo } from '@/api/cert' import type { CertificateInfo } from '@/api/cert'
import type { NgxConfig, NgxDirective } from '@/api/ngx' import type { NgxConfig, NgxDirective } from '@/api/ngx'
import type { SiteStatus } from '@/api/site'
import { ConfigStatus } from '@/constants'
import Cert from '@/views/site/cert/Cert.vue' import Cert from '@/views/site/cert/Cert.vue'
import ConfigTemplate from '@/views/site/ngx_conf/config_template/ConfigTemplate.vue' import ConfigTemplate from '@/views/site/ngx_conf/config_template/ConfigTemplate.vue'
import DirectiveEditor from '@/views/site/ngx_conf/directive/DirectiveEditor.vue' import DirectiveEditor from '@/views/site/ngx_conf/directive/DirectiveEditor.vue'
@ -10,13 +12,14 @@ import { MoreOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { Modal } from 'ant-design-vue' import { Modal } from 'ant-design-vue'
withDefaults(defineProps<{ withDefaults(defineProps<{
enabled: boolean
certInfo?: { certInfo?: {
[key: number]: CertificateInfo[] [key: number]: CertificateInfo[]
} }
context?: 'http' | 'stream' context?: 'http' | 'stream'
status?: SiteStatus
}>(), { }>(), {
context: 'http', context: 'http',
status: ConfigStatus.Enabled,
}) })
const [modal, ContextHolder] = Modal.useModal() const [modal, ContextHolder] = Modal.useModal()
@ -125,7 +128,7 @@ provide('ngx_directives', ngx_directives)
v-model:enabled="autoCert" v-model:enabled="autoCert"
v-model:current_server_directives="ngx_config.servers[current_server_index].directives" v-model:current_server_directives="ngx_config.servers[current_server_index].directives"
class="mb-4" class="mb-4"
:site-enabled="enabled" :site-status="status"
:config-name="ngx_config.name" :config-name="ngx_config.name"
:cert-info="certInfo?.[k]" :cert-info="certInfo?.[k]"
:current-server-index="current_server_index" :current-server-index="current_server_index"

View file

@ -1,39 +1,30 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ChatComplicationMessage } from '@/api/openai' import type { ChatComplicationMessage } from '@/api/openai'
import type { Site } from '@/api/site' import type { Site, SiteStatus } from '@/api/site'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import envGroup from '@/api/env_group' import envGroup from '@/api/env_group'
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue' import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
import NodeSelector from '@/components/NodeSelector/NodeSelector.vue' import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
import StdSelector from '@/components/StdDesign/StdDataEntry/components/StdSelector.vue' import StdSelector from '@/components/StdDesign/StdDataEntry/components/StdSelector.vue'
import { ConfigStatus } from '@/constants'
import { formatDateTime } from '@/lib/helper' import { formatDateTime } from '@/lib/helper'
import { useSettingsStore } from '@/pinia' import { useSettingsStore } from '@/pinia'
import envGroupColumns from '@/views/environments/group/columns' import envGroupColumns from '@/views/environments/group/columns'
import SiteStatusSegmented from '@/views/site/components/SiteStatusSegmented.vue'
import ConfigName from '@/views/site/site_edit/components/ConfigName.vue' import ConfigName from '@/views/site/site_edit/components/ConfigName.vue'
import SiteStatusSegmented from '@/views/site/site_edit/components/SiteStatusSegmented.vue'
import { InfoCircleOutlined } from '@ant-design/icons-vue' import { InfoCircleOutlined } from '@ant-design/icons-vue'
const settings = useSettingsStore() const settings = useSettingsStore()
const configText = inject('configText') as Ref<string> const configText = inject('configText') as Ref<string>
const enabled = inject('enabled') as Ref<boolean>
const name = inject('name') as ComputedRef<string> const name = inject('name') as ComputedRef<string>
const filepath = inject('filepath') as Ref<string> const filepath = inject('filepath') as Ref<string>
const historyChatgptRecord = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]> const historyChatgptRecord = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]>
const data = inject('data') as Ref<Site> const data = inject('data') as Ref<Site>
const activeKey = ref(['1', '2', '3']) const activeKey = ref(['1', '2', '3'])
const siteStatus = computed(() => {
if (!data.value?.status) {
return enabled.value ? ConfigStatus.Enabled : ConfigStatus.Disabled
}
return data.value.status
})
function handleStatusChanged(event: { status: string, enabled: boolean }) { function handleStatusChanged(event: { status: SiteStatus }) {
data.value.status = event.status data.value.status = event.status
enabled.value = event.enabled
} }
</script> </script>
@ -54,9 +45,8 @@ function handleStatusChanged(event: { status: string, enabled: boolean }) {
<AForm layout="vertical"> <AForm layout="vertical">
<AFormItem :label="$gettext('Status')"> <AFormItem :label="$gettext('Status')">
<SiteStatusSegmented <SiteStatusSegmented
v-model="siteStatus" v-model="data.status"
:site-name="name" :site-name="name"
:enabled="enabled"
@status-changed="handleStatusChanged" @status-changed="handleStatusChanged"
/> />
</AFormItem> </AFormItem>

View file

@ -2,7 +2,6 @@
import type { CertificateInfo } from '@/api/cert' import type { CertificateInfo } from '@/api/cert'
import type { NgxConfig } from '@/api/ngx' import type { NgxConfig } from '@/api/ngx'
import type { ChatComplicationMessage } from '@/api/openai' import type { ChatComplicationMessage } from '@/api/openai'
import type { Site } from '@/api/site' import type { Site } from '@/api/site'
import type { CheckedType } from '@/types' import type { CheckedType } from '@/types'
import config from '@/api/config' import config from '@/api/config'
@ -11,6 +10,7 @@ import site from '@/api/site'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue' import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
import { ConfigHistory } from '@/components/ConfigHistory' import { ConfigHistory } from '@/components/ConfigHistory'
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue' import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
import { ConfigStatus } from '@/constants'
import NgxConfigEditor from '@/views/site/ngx_conf/NgxConfigEditor.vue' import NgxConfigEditor from '@/views/site/ngx_conf/NgxConfigEditor.vue'
import RightSettings from '@/views/site/site_edit/RightSettings.vue' import RightSettings from '@/views/site/site_edit/RightSettings.vue'
import { HistoryOutlined } from '@ant-design/icons-vue' import { HistoryOutlined } from '@ant-design/icons-vue'
@ -30,7 +30,6 @@ const ngx_config: NgxConfig = reactive({
const certInfoMap: Ref<Record<number, CertificateInfo[]>> = ref({}) const certInfoMap: Ref<Record<number, CertificateInfo[]>> = ref({})
const autoCert = ref(false) const autoCert = ref(false)
const enabled = ref(false)
const filepath = ref('') const filepath = ref('')
const configText = ref('') const configText = ref('')
const advanceModeRef = ref(false) const advanceModeRef = ref(false)
@ -64,7 +63,6 @@ async function handleResponse(r: Site) {
filename.value = r.name filename.value = r.name
filepath.value = r.filepath filepath.value = r.filepath
configText.value = r.config configText.value = r.config
enabled.value = r.enabled
autoCert.value = r.auto_cert autoCert.value = r.auto_cert
historyChatgptRecord.value = r.chatgpt_messages historyChatgptRecord.value = r.chatgpt_messages
data.value = r data.value = r
@ -168,7 +166,6 @@ provide('save_config', save)
provide('configText', configText) provide('configText', configText)
provide('ngx_config', ngx_config) provide('ngx_config', ngx_config)
provide('history_chatgpt_record', historyChatgptRecord) provide('history_chatgpt_record', historyChatgptRecord)
provide('enabled', enabled)
provide('name', name) provide('name', name)
provide('filepath', filepath) provide('filepath', filepath)
provide('data', data) provide('data', data)
@ -187,17 +184,23 @@ provide('data', data)
<template #title> <template #title>
<span style="margin-right: 10px">{{ $gettext('Edit %{n}', { n: name }) }}</span> <span style="margin-right: 10px">{{ $gettext('Edit %{n}', { n: name }) }}</span>
<ATag <ATag
v-if="enabled" v-if="data.status === ConfigStatus.Enabled"
color="blue" color="blue"
> >
{{ $gettext('Enabled') }} {{ $gettext('Enabled') }}
</ATag> </ATag>
<ATag <ATag
v-else v-else-if="data.status === ConfigStatus.Disabled"
color="orange" color="red"
> >
{{ $gettext('Disabled') }} {{ $gettext('Disabled') }}
</ATag> </ATag>
<ATag
v-else-if="data.status === ConfigStatus.Maintenance"
color="orange"
>
{{ $gettext('Maintenance') }}
</ATag>
</template> </template>
<template #extra> <template #extra>
<ASpace> <ASpace>
@ -260,7 +263,7 @@ provide('data', data)
<NgxConfigEditor <NgxConfigEditor
v-model:auto-cert="autoCert" v-model:auto-cert="autoCert"
:cert-info="certInfoMap" :cert-info="certInfoMap"
:enabled="enabled" :status="data.status"
@callback="save" @callback="save"
/> />
</div> </div>

View file

@ -1,3 +1,4 @@
import type { SiteStatus } from '@/api/site'
import type { import type {
CustomRender, CustomRender,
} from '@/components/StdDesign/StdDataDisplay/StdTableTransformer' } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
@ -10,7 +11,7 @@ import {
import { input, select, selector } from '@/components/StdDesign/StdDataEntry' import { input, select, selector } from '@/components/StdDesign/StdDataEntry'
import { ConfigStatus } from '@/constants' import { ConfigStatus } from '@/constants'
import envGroupColumns from '@/views/environments/group/columns' import envGroupColumns from '@/views/environments/group/columns'
import SiteStatusSegmented from '@/views/site/site_edit/components/SiteStatusSegmented.vue' import SiteStatusSegmented from '@/views/site/components/SiteStatusSegmented.vue'
import { Tag } from 'ant-design-vue' import { Tag } from 'ant-design-vue'
const columns: Column[] = [{ const columns: Column[] = [{
@ -98,9 +99,8 @@ const columns: Column[] = [{
// This will be handled by the component internal events // This will be handled by the component internal events
record.status = val record.status = val
}, },
'onStatusChanged': ({ status, enabled }: { status: string, enabled: boolean }) => { 'onStatusChanged': ({ status }: { status: SiteStatus }) => {
record.status = status record.status = status
record.enabled = enabled
}, },
}) })
}, },

View file

@ -10,6 +10,7 @@ import (
"github.com/tufanbarisyildirim/gonginx/config" "github.com/tufanbarisyildirim/gonginx/config"
"github.com/tufanbarisyildirim/gonginx/dumper" "github.com/tufanbarisyildirim/gonginx/dumper"
"github.com/tufanbarisyildirim/gonginx/parser" "github.com/tufanbarisyildirim/gonginx/parser"
"github.com/uozi-tech/cosy/logger"
) )
type ProxyCacheConfig struct { type ProxyCacheConfig struct {
@ -189,7 +190,10 @@ func updateOrRemoveProxyCachePath(block config.IBlock, directives []config.IDire
// First parameter is the path (required) // First parameter is the path (required)
if proxyCache.Path != "" { if proxyCache.Path != "" {
params = append(params, config.Parameter{Value: proxyCache.Path}) params = append(params, config.Parameter{Value: proxyCache.Path})
_ = os.MkdirAll(proxyCache.Path, 0755) err := os.MkdirAll(proxyCache.Path, 0755)
if err != nil {
logger.Error("failed to create proxy cache path", err)
}
} else { } else {
// No path specified, can't add the directive // No path specified, can't add the directive
return return

21
internal/site/status.go Normal file
View file

@ -0,0 +1,21 @@
package site
import (
"github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx"
)
// GetSiteStatus returns the status of the site
func GetSiteStatus(name string) SiteStatus {
enabledFilePath := nginx.GetConfPath("sites-enabled", name)
if helper.FileExists(enabledFilePath) {
return SiteStatusEnabled
}
mantainanceFilePath := nginx.GetConfPath("sites-enabled", name+MaintenanceSuffix)
if helper.FileExists(mantainanceFilePath) {
return SiteStatusMaintenance
}
return SiteStatusDisabled
}

View file

@ -1,18 +1,27 @@
package sites package site
import ( import (
"time"
"github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"time" )
type SiteStatus string
const (
SiteStatusEnabled SiteStatus = "enabled"
SiteStatusDisabled SiteStatus = "disabled"
SiteStatusMaintenance SiteStatus = "maintenance"
) )
type Site struct { type Site struct {
*model.Site *model.Site
Name string `json:"name"` Name string `json:"name"`
ModifiedAt time.Time `json:"modified_at"` ModifiedAt time.Time `json:"modified_at"`
Enabled bool `json:"enabled"` Status SiteStatus `json:"status"`
Config string `json:"config"` Config string `json:"config"`
AutoCert bool `json:"auto_cert"` AutoCert bool `json:"auto_cert"`
ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`