Skip to content
This repository has been archived by the owner on Feb 28, 2023. It is now read-only.

Commit

Permalink
feat(cmd): Add workdir parameter & gen cmd.
Browse files Browse the repository at this point in the history
Signed-off-by: qwqcode <[email protected]>
  • Loading branch information
qwqcode committed Apr 15, 2022
1 parent 5d5bc6d commit 996b762
Show file tree
Hide file tree
Showing 10 changed files with 373 additions and 250 deletions.
213 changes: 213 additions & 0 deletions cmd/core.go
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)
}
}
2 changes: 2 additions & 0 deletions cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ var exportCmd = &cobra.Command{
- 文档:https://artalk.js.org/guide/transfer.html
`,
Run: func(cmd *cobra.Command, args []string) {
loadCore() // 装载核心

jsonStr, err := artransfer.ExportArtransString()
if err != nil {
logrus.Fatal(err)
Expand Down
90 changes: 90 additions & 0 deletions cmd/gen.go
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)
}
6 changes: 4 additions & 2 deletions cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ var importCmd = &cobra.Command{
- 例如:artalk-go import typecho [参数]
- 文档:https://artalk.js.org/guide/transfer.html
`,
Args: cobra.MinimumNArgs(1),
ArgAliases: artransfer.GetSupportNames(),
Run: func(cmd *cobra.Command, args []string) {
loadCore() // 装载核心

parcelFile := args[0]
if _, err := os.Stat(parcelFile); errors.Is(err, os.ErrNotExist) {
logrus.Fatal("`数据行囊` 文件不存在,请检查路径是否正确")
Expand All @@ -36,8 +40,6 @@ var importCmd = &cobra.Command{

logrus.Info("导入结束")
},
Args: cobra.MinimumNArgs(1),
ArgAliases: artransfer.GetSupportNames(),
}

func init() {
Expand Down
Loading

0 comments on commit 996b762

Please sign in to comment.