This repository has been archived by the owner on Feb 28, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cmd): Add workdir parameter & gen cmd.
Signed-off-by: qwqcode <[email protected]>
- Loading branch information
Showing
10 changed files
with
373 additions
and
250 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
"strings" | ||
"time" | ||
|
||
"github.com/ArtalkJS/ArtalkGo/config" | ||
"github.com/ArtalkJS/ArtalkGo/lib" | ||
"github.com/ArtalkJS/ArtalkGo/lib/email" | ||
"github.com/ArtalkJS/ArtalkGo/model" | ||
"github.com/nikoksr/notify" | ||
"github.com/nikoksr/notify/service/dingding" | ||
"github.com/nikoksr/notify/service/line" | ||
"github.com/nikoksr/notify/service/slack" | ||
"github.com/nikoksr/notify/service/telegram" | ||
"github.com/rifflock/lfshook" | ||
"github.com/sirupsen/logrus" | ||
prefixed "github.com/x-cray/logrus-prefixed-formatter" | ||
"gorm.io/gorm" | ||
) | ||
|
||
// 装载核心功能 | ||
func loadCore() { | ||
initConfig() | ||
initLog() | ||
initDB() | ||
syncConfWithDB() | ||
initCache() | ||
email.InitQueue() // 初始化邮件队列 | ||
initNotify() | ||
} | ||
|
||
// 1. 初始化配置 | ||
func initConfig() { | ||
config.Init(cfgFile, workDir) | ||
|
||
// 检查 app_key 是否设置 | ||
if strings.TrimSpace(config.Instance.AppKey) == "" { | ||
logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") | ||
} | ||
|
||
// 设置时区 | ||
if strings.TrimSpace(config.Instance.TimeZone) == "" { | ||
logrus.Fatal("请检查配置文件,并设置 timezone") | ||
} | ||
denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) | ||
time.Local = denverLoc | ||
} | ||
|
||
// 2. 初始化日志 | ||
func initLog() { | ||
if !config.Instance.Log.Enabled { | ||
return | ||
} | ||
|
||
// 命令行输出格式 | ||
stdFormatter := &prefixed.TextFormatter{ | ||
DisableTimestamp: true, | ||
ForceFormatting: true, | ||
ForceColors: true, | ||
DisableColors: false, | ||
} | ||
|
||
// 文件输出格式 | ||
fileFormatter := &prefixed.TextFormatter{ | ||
FullTimestamp: true, | ||
TimestampFormat: "2006-01-02.15:04:05.000000", | ||
ForceFormatting: true, | ||
ForceColors: false, | ||
DisableColors: true, | ||
} | ||
|
||
// logrus.SetLevel(logrus.DebugLevel) | ||
logrus.SetFormatter(stdFormatter) | ||
logrus.SetOutput(os.Stdout) | ||
|
||
if config.Instance.Debug { | ||
logrus.SetLevel(logrus.DebugLevel) | ||
} | ||
|
||
if config.Instance.Log.Filename != "" { | ||
// 文件保存 | ||
pathMap := lfshook.PathMap{ | ||
logrus.InfoLevel: config.Instance.Log.Filename, | ||
logrus.DebugLevel: config.Instance.Log.Filename, | ||
logrus.ErrorLevel: config.Instance.Log.Filename, | ||
} | ||
logrus.AddHook(lfshook.NewHook( | ||
pathMap, | ||
fileFormatter, | ||
)) | ||
} | ||
} | ||
|
||
// 3. 初始化数据库 | ||
func initDB() { | ||
var db *gorm.DB | ||
db, err := lib.OpenDB(config.DBType(config.Instance.DB.Type), config.Instance.DB.Dsn) | ||
if err != nil { | ||
logrus.Error("数据库初始化发生错误 ", err) | ||
os.Exit(1) | ||
} | ||
|
||
lib.DB = db | ||
|
||
// Migrate the schema | ||
lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, | ||
&model.Comment{}, &model.Notify{}, &model.Vote{}, &model.PV{}) // 注意表的创建顺序,因为有关联字段 | ||
} | ||
|
||
// 4. 同步配置文件与数据库 | ||
func syncConfWithDB() { | ||
// 初始化默认站点 | ||
siteDefault := strings.TrimSpace(config.Instance.SiteDefault) | ||
if siteDefault == "" { | ||
logrus.Error("请设置 SiteDefault 默认站点,不能为空") | ||
os.Exit(1) | ||
} | ||
model.FindCreateSite(siteDefault) | ||
|
||
// 导入配置文件的管理员用户 | ||
for _, admin := range config.Instance.AdminUsers { | ||
user := model.FindUser(admin.Name, admin.Email) | ||
if user.IsEmpty() { | ||
// create | ||
user = model.User{ | ||
Name: admin.Name, | ||
Email: admin.Email, | ||
Link: admin.Link, | ||
Password: admin.Password, | ||
BadgeName: admin.BadgeName, | ||
BadgeColor: admin.BadgeColor, | ||
IsAdmin: true, | ||
IsInConf: true, | ||
} | ||
lib.DB.Create(&user) | ||
} else { | ||
// update | ||
user.Name = admin.Name | ||
user.Email = admin.Email | ||
user.Link = admin.Link | ||
user.Password = admin.Password | ||
user.BadgeName = admin.BadgeName | ||
user.BadgeColor = admin.BadgeColor | ||
user.IsAdmin = true | ||
user.IsInConf = true | ||
lib.DB.Save(&user) | ||
} | ||
} | ||
|
||
// 清理配置文件中不存在的用户 | ||
var dbAdminUsers []model.User | ||
lib.DB.Model(&model.User{}).Where(&model.User{IsInConf: true}).Find(&dbAdminUsers) | ||
for _, dbU := range dbAdminUsers { | ||
isUserExist := func() bool { | ||
for _, confU := range config.Instance.AdminUsers { | ||
// 忽略大小写比较 | ||
if strings.EqualFold(confU.Name, dbU.Name) && strings.EqualFold(confU.Email, dbU.Email) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
if !isUserExist() { | ||
lib.DB.Unscoped().Delete(&dbU) | ||
} | ||
} | ||
} | ||
|
||
// 5. 初始化缓存 | ||
func initCache() { | ||
err := lib.OpenCache() | ||
if err != nil { | ||
logrus.Error("缓存初始化发生错误 ", err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
// 6. 初始化 Notify | ||
func initNotify() { | ||
// Telegram | ||
tgConf := config.Instance.Notify.Telegram | ||
if tgConf.Enabled { | ||
telegramService, _ := telegram.New(tgConf.ApiToken) | ||
telegramService.AddReceivers(tgConf.Receivers...) | ||
notify.UseServices(telegramService) | ||
} | ||
|
||
// 钉钉 | ||
dingTalkConf := config.Instance.Notify.DingTalk | ||
if dingTalkConf.Enabled { | ||
dingTalkService := dingding.New(&dingding.Config{Token: dingTalkConf.Token, Secret: dingTalkConf.Secret}) | ||
notify.UseServices(dingTalkService) | ||
} | ||
|
||
// Slack | ||
slackConf := config.Instance.Notify.Slack | ||
if slackConf.Enabled { | ||
slackService := slack.New(slackConf.OauthToken) | ||
slackService.AddReceivers(slackConf.Receivers...) | ||
notify.UseServices(slackService) | ||
} | ||
|
||
// LINE | ||
LINEConf := config.Instance.Notify.LINE | ||
if LINEConf.Enabled { | ||
lineService, _ := line.New(config.Instance.Notify.LINE.ChannelSecret, config.Instance.Notify.LINE.ChannelAccessToken) | ||
lineService.AddReceivers(LINEConf.Receivers...) | ||
notify.UseServices(lineService) | ||
} | ||
} |
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,90 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"math/rand" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/ArtalkJS/ArtalkGo/pkged" | ||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var genCmd = &cobra.Command{ | ||
Use: "gen <类型> <目标路径>", | ||
Short: "生成一些内容", | ||
Long: "生成一些内容\n例如:artalk-go gen artalk-go.example.yml ./artalk-go.yml", | ||
Args: cobra.RangeArgs(1, 2), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
// 工作目录 | ||
if workDir != "" { | ||
if err := os.Chdir(workDir); err != nil { | ||
logrus.Fatal("工作目录切换错误 ", err) | ||
} | ||
} | ||
|
||
// 参数 | ||
genType := args[0] | ||
genPath := filepath.Base(genType) | ||
if len(args) >= 2 { | ||
genPath = args[1] | ||
} | ||
|
||
file, err := pkged.Open("/" + strings.TrimPrefix(genType, "/")) | ||
if err != nil { | ||
logrus.Fatal("无效的内置资源: "+genType+" ", err) | ||
} | ||
|
||
buf, err := ioutil.ReadAll(file) | ||
if err != nil { | ||
logrus.Fatal("读取内置资源: "+genType+" 失败 ", err) | ||
} | ||
|
||
// 自动生成 app_key | ||
if strings.Contains(filepath.Base(genType), "artalk-go.example.yml") { | ||
str := string(buf) | ||
appKey := RandStringRunes(16) | ||
str = strings.Replace(str, `app_key: ""`, fmt.Sprintf(`app_key: "%s"`, appKey), 1) | ||
buf = []byte(str) | ||
} | ||
|
||
absPath, err := filepath.Abs(genPath) | ||
if err != nil { | ||
logrus.Fatal(err) | ||
} | ||
|
||
_, err = os.Stat(absPath) | ||
if err == nil { | ||
logrus.Fatal("已存在文件: " + absPath) | ||
} | ||
|
||
dst, err := os.Create(absPath) | ||
if err != nil { | ||
logrus.Fatal("创建目标文件失败 ", err) | ||
} | ||
defer dst.Close() | ||
|
||
if _, err = dst.Write(buf); err != nil { | ||
logrus.Fatal("写入目标文件失败 ", err) | ||
} | ||
|
||
logrus.Info("创建文件: " + absPath) | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(genCmd) | ||
} | ||
|
||
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*") | ||
|
||
func RandStringRunes(n int) string { | ||
b := make([]rune, n) | ||
for i := range b { | ||
b[i] = letterRunes[rand.Intn(len(letterRunes))] | ||
} | ||
return string(b) | ||
} |
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
Oops, something went wrong.