refactor: refactor eiblog

This commit is contained in:
henry.chen
2025-07-16 19:45:50 +08:00
parent 0a410f09f3
commit 8fcabd5e15
67 changed files with 1282 additions and 1330 deletions

View File

@@ -4,172 +4,51 @@ package config
import (
"os"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
var (
// Conf config instance
Conf Config
// ModeDev run mode as development
ModeDev = "dev"
// ModeProd run mode as production
ModeProd = "prod"
// WorkDir workspace dir
WorkDir string
// RunMode 列表
const (
RunModeDev RunMode = "dev" // 开发环境
RunModeProd RunMode = "pro" // 生产环境
)
// Mode run mode
type Mode struct {
Name string `yaml:"name"`
EnableHTTP bool `yaml:"enablehttp"`
HTTPPort int `yaml:"httpport"`
EnableGRPC bool `yaml:"enablegrpc"`
GRPCPort int `yaml:"grpcport"`
Host string `yaml:"host"`
// RunMode 运行模式
type RunMode string
// IsReleaseMode 是否
func (mode RunMode) IsReleaseMode() bool {
return mode == RunModeProd
}
// Database sql database
type Database struct {
Driver string `yaml:"driver"`
Source string `yaml:"source"`
// IsDevMode 是否时开发模式
func (mode RunMode) IsDevMode() bool {
return mode == RunModeDev
}
// General common
type General struct {
PageNum int `yaml:"pagenum"` // 前台每页文章数量
PageSize int `yaml:"pagesize"` // 后台每页文章数量
StartID int `yaml:"startid"` // 文章启始ID
DescPrefix string `yaml:"descprefix"` // 文章描述前缀
Identifier string `yaml:"identifier"` // 文章截取标识
Length int `yaml:"length"` // 文章预览长度
Timezone string `yaml:"timezone"` // 时区
// IsRunMode 是否是runmode
func (mode RunMode) IsRunMode() bool {
return mode == RunModeDev || mode == RunModeProd
}
// Disqus comments
type Disqus struct {
ShortName string `yaml:"shortname"`
PublicKey string `yaml:"publickey"`
AccessToken string `yaml:"accesstoken"`
}
// Twitter card
type Twitter struct {
Card string `yaml:"card"`
Site string `yaml:"site"`
Image string `yaml:"image"`
Address string `yaml:"address"`
}
// Google analytics
type Google struct {
URL string `yaml:"url"`
Tid string `yaml:"tid"`
V string `yaml:"v"`
AdSense string `yaml:"adsense"`
}
// Qiniu oss
type Qiniu struct {
Bucket string `yaml:"bucket"`
Domain string `yaml:"domain"`
AccessKey string `yaml:"accesskey"`
SecretKey string `yaml:"secretkey"`
}
// FeedRPC feedr
type FeedRPC struct {
FeedrURL string `yaml:"feedrurl"`
PingRPC []string `yaml:"pingrpc"`
}
// Account info
type Account struct {
Username string `yaml:"username"` // *
Password string `yaml:"password"` // *
Email string `yaml:"email"`
PhoneNumber string `yaml:"phonenumber"`
Address string `yaml:"address"`
}
// Blogger info
type Blogger struct {
BlogName string `yaml:"blogname"`
SubTitle string `yaml:"subtitle"`
BeiAn string `yaml:"beian"`
BTitle string `yaml:"btitle"`
Copyright string `yaml:"copyright"`
}
// EiBlogApp config
type EiBlogApp struct {
Mode
StaticVersion int `yaml:"staticversion"`
HotWords []string `yaml:"hotwords"`
General General `yaml:"general"`
Disqus Disqus `yaml:"disqus"`
Google Google `yaml:"google"`
Qiniu Qiniu `yaml:"qiniu"`
Twitter Twitter `yaml:"twitter"`
FeedRPC FeedRPC `yaml:"feedrpc"`
Account Account `yaml:"account"`
Blogger Blogger `yaml:"blogger"`
}
// BackupApp config
type BackupApp struct {
Mode
BackupTo string `yaml:"backupto"`
Interval string `yaml:"interval"` // circle backup, default: 7d
Validity int `yaml:"validity"` // storage days, default: 60
Qiniu Qiniu `yaml:"qiniu"` // qiniu config
}
// Config app config
type Config struct {
RunMode string `yaml:"runmode"`
AppName string `yaml:"appname"`
Database Database `yaml:"database"`
ESHost string `yaml:"eshost"`
EiBlogApp EiBlogApp `yaml:"eiblogapp"`
BackupApp BackupApp `yaml:"backupapp"`
}
// load config file
func init() {
// compatibility linux and windows
var err error
WorkDir = workDir()
path := filepath.Join(WorkDir, "conf", "app.yml")
data, err := os.ReadFile(path)
// WalkWorkDir walk work dir
func WalkWorkDir() (string, error) {
gopath := os.Getenv("GOPATH")
workDir, err := os.Getwd()
if err != nil {
panic(err)
return "", err
}
err = yaml.Unmarshal(data, &Conf)
if err != nil {
panic(err)
}
// read run mode from env
Conf.RunMode = ModeDev
if runmode := os.Getenv("RUN_MODE"); runmode == ModeProd {
Conf.RunMode = runmode
}
// read env
readDBEnv()
}
// find work dir, try 3 times
for gopath != workDir && workDir != "/" {
dir := filepath.Join(workDir, "etc")
func readDBEnv() {
key := strings.ToUpper(Conf.AppName) + "_DB_DRIVER"
if d := os.Getenv(key); d != "" {
Conf.Database.Driver = d
}
key = strings.ToUpper(Conf.AppName) + "_DB_SOURCE"
if s := os.Getenv(key); s != "" {
Conf.Database.Source = s
_, err := os.Stat(dir)
if err == nil {
break
}
if !os.IsNotExist(err) {
return "", err
}
workDir = filepath.Dir(workDir)
}
return workDir, nil
}

View File

@@ -1,29 +0,0 @@
// +build !prod
// Package config provides ...
package config
import (
"os"
"path"
"path/filepath"
)
// workDir recognize workspace dir
var workDir = func() string {
wd, err := os.Getwd()
if err != nil {
panic(err)
}
for wd != "" {
name := filepath.Join(wd, "conf")
_, err := os.Stat(name)
if err != nil {
dir, _ := path.Split(wd)
wd = path.Clean(dir)
continue
}
return wd
}
return ""
}

124
pkg/config/enums.go Normal file
View File

@@ -0,0 +1,124 @@
package config
// APIMode 应用配置
type APIMode struct {
// 运行模式,可根据不同模式做相关判断,如日志打印等
RunMode RunMode
// 服务名称,如 eiblog, backup
Name string
// 监听地址,如 0.0.0.0:9000
Listen string
// 所属域名,如 deepzz.com
Host string
// 一般的应用都会有个密钥,可以用这个字段
Secret string
}
// Database 数据库配置
type Database struct {
// 数据库驱动,如 sqlite, mysql, postgres 等
Driver string
// 数据库连接字符串,如
// sqlite:./db.sqlite
// mysql:root:123456@tcp(127.0.0.1:3306)/eiblog?charset=utf8mb4&parseTime=True&loc=Local
Source string
}
// Disqus 评论配置
type Disqus struct {
// 短名称,如 deepzz
ShortName string
// 公共密钥 wdSgxRm9rdGAlLKFcFdToBe3GT4SibmV7Y8EjJQ0r4GWXeKtxpopMAeIeoI2dTEg
PublicKey string
// 访问令牌, 需自行创建
AccessToken string
}
// Twitter 社交配置
type Twitter struct {
// 卡片, 可选 summary, summary_large_image, player
Card string
// id号, 如 deepzz02
Site string
// 图片, 如 st.deepzz.cn/static/img/avatar.jpg
Image string
// 地址, 如 twitter.com/deepzz02
Address string
}
// Google 分析配置
type Google struct {
// url, 如 https://www.google-analytics.com/g/collect
URL string
// tid, 如 G-S085VRC5PF
Tid string
// v, 如 "2"
V string
// 如果开启广发, 配置 <script async src="xxx" crossorigin="anonymous"></script>
AdSense string
}
// Qiniu 对象存储配置
type Qiniu struct {
// bucket, 如 eiblog
Bucket string
// domain, 如 st.deepzz.cn
Domain string
// accesskey, 如 1234567890
AccessKey string
// secretkey, 如 1234567890
SecretKey string
}
// FeedRPC 订阅配置
type FeedRPC struct {
// feedrurl, 如 https://deepzz.superfeedr.com/
FeedrURL string
// pingrpc, 如 http://ping.baidu.com/ping/RPC2, http://rpc.pingomatic.com/
PingRPC []string
}
// General 博客通用配置
type General struct {
// 前台每页文章数量, 一般配置为 10
PageNum int
// 后台每页文章数量, 一般配置为 20
PageSize int
// 文章描述前缀, 一般配置为 Desc:
DescPrefix string
// 文章截取标识, 一般配置为 <!--more-->
Identifier string
// 文章预览长度, 一般配置为 400
Length int
// 时区, 一般配置为 Asia/Shanghai
Timezone string
}
// Account 账户配置
type Account struct {
// *必须配置, 后台登录用户名
Username string
// *必须配置, 后台登录密码。登录后请后台立即修改
Password string
// 邮箱, 用于显示
Email string
// 手机号, 用于显示
PhoneNumber string
// 地址, 用于显示
Address string
}
// Blogger 博客配置, 无需配置,程序默认初始化,可在后台更改
type Blogger struct {
// 博客名称, 如 deepzz
BlogName string
// 格言, 如 Rome was not built in one day.
SubTitle string
// 备案号, 不填则不显示在网站底部, 如 蜀ICP备xxxxxxxx号-1
BeiAn string
// 标题, 如 deepzz's Blog
BTitle string
// 版权, 如 本站使用「<a href="//creativecommons.org/licenses/by/4.0/">署名 4.0 国际</a>」创作共享协议,转载请注明作者及原网址。
Copyright string // 版权
}

View File

@@ -1,7 +0,0 @@
// +build prod
// Package config provides ...
package config
// workDir production use current dir
var workDir = func() string { return "" }