mirror of
https://github.com/eiblog/eiblog.git
synced 2026-02-08 15:52:25 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
666161d37e | ||
|
|
11b22da339 | ||
|
|
bd9a45078b | ||
|
|
629ad782c4 | ||
|
|
5e63f5e69d | ||
|
|
33afbd351d | ||
|
|
eaeeaaafb9 | ||
|
|
ae3fb35435 | ||
|
|
c1d73f1a45 |
23
CHANGELOG.md
23
CHANGELOG.md
@@ -2,6 +2,29 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
### [3.0.7](https://github.com/eiblog/eiblog/compare/v3.0.6...v3.0.7) (2025-07-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* feed not generate ([11b22da](https://github.com/eiblog/eiblog/commit/11b22da339c542eb6d697cb3ac7bc78a401c6420))
|
||||||
|
|
||||||
|
### [3.0.6](https://github.com/eiblog/eiblog/compare/v3.0.5...v3.0.6) (2025-07-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* feed & sitemap not generate ([629ad78](https://github.com/eiblog/eiblog/commit/629ad782c45fae7af9efdf99513bafdf87e7758c))
|
||||||
|
|
||||||
|
### [3.0.5](https://github.com/eiblog/eiblog/compare/v3.0.4...v3.0.5) (2025-07-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* admin login session ([c1d73f1](https://github.com/eiblog/eiblog/commit/c1d73f1a453af62d15c25a79c382d9cefd8a3d2e))
|
||||||
|
* mongodb uri error ([33afbd3](https://github.com/eiblog/eiblog/commit/33afbd351d2b41f9edf36959908c3f183745d903))
|
||||||
|
* RUN_MODE error ([eaeeaaa](https://github.com/eiblog/eiblog/commit/eaeeaaafb98a4aa0a42dba74b411b1d361faf1d5))
|
||||||
|
|
||||||
### [3.0.4](https://github.com/eiblog/eiblog/compare/v3.0.3...v3.0.4) (2025-07-25)
|
### [3.0.4](https://github.com/eiblog/eiblog/compare/v3.0.3...v3.0.4) (2025-07-25)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/eiblog/eiblog/cmd/backup/config"
|
"github.com/eiblog/eiblog/cmd/backup/config"
|
||||||
"github.com/eiblog/eiblog/pkg/connector/db"
|
pdb "github.com/eiblog/eiblog/pkg/connector/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MongoStorage 备份恢复器
|
// MongoStorage 备份恢复器
|
||||||
@@ -46,11 +46,11 @@ func (r MongoStorage) Restore(path string) error {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// drop database
|
// drop database
|
||||||
mdb, err := db.NewMDB(config.Conf.Database)
|
database, err := pdb.NewMDB(ctx, config.Conf.Database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = mdb.Drop(ctx)
|
err = database.Drop(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,18 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/eiblog/eiblog/cmd/eiblog/config"
|
||||||
|
pdb "github.com/eiblog/eiblog/pkg/connector/db"
|
||||||
"github.com/eiblog/eiblog/pkg/model"
|
"github.com/eiblog/eiblog/pkg/model"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// example:
|
// example:
|
||||||
// driver: mongodb
|
// driver: mongodb
|
||||||
// source: mongodb://localhost:27017
|
// source: mongodb://localhost:27017/eiblog
|
||||||
|
|
||||||
const (
|
const (
|
||||||
mongoDBName = "eiblog"
|
mongoDBName = "eiblog"
|
||||||
@@ -31,44 +32,39 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type mongodb struct {
|
type mongodb struct {
|
||||||
*mongo.Client
|
*mongo.Database
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init init mongodb client
|
// Init init mongodb client
|
||||||
func (db *mongodb) Init(name, source string) (Store, error) {
|
func (db *mongodb) Init(name, source string) (Store, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
opts := options.Client().ApplyURI(source)
|
database, err := pdb.NewMDB(ctx, config.Conf.Database)
|
||||||
client, err := mongo.Connect(ctx, opts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = client.Ping(ctx, readpref.Primary())
|
db.Database = database
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
db.Client = client
|
|
||||||
// create index
|
// create index
|
||||||
indexModel := mongo.IndexModel{
|
indexModel := mongo.IndexModel{
|
||||||
Keys: bson.D{bson.E{Key: "username", Value: 1}},
|
Keys: bson.D{bson.E{Key: "username", Value: 1}},
|
||||||
Options: options.Index().SetUnique(true).SetSparse(true),
|
Options: options.Index().SetUnique(true).SetSparse(true),
|
||||||
}
|
}
|
||||||
db.Database(mongoDBName).Collection(collectionAccount).
|
db.Database.Collection(collectionAccount).
|
||||||
Indexes().
|
Indexes().
|
||||||
CreateOne(context.Background(), indexModel)
|
CreateOne(context.Background(), indexModel)
|
||||||
indexModel = mongo.IndexModel{
|
indexModel = mongo.IndexModel{
|
||||||
Keys: bson.D{bson.E{Key: "slug", Value: 1}},
|
Keys: bson.D{bson.E{Key: "slug", Value: 1}},
|
||||||
Options: options.Index().SetUnique(true).SetSparse(true),
|
Options: options.Index().SetUnique(true).SetSparse(true),
|
||||||
}
|
}
|
||||||
db.Database(mongoDBName).Collection(collectionArticle).
|
db.Database.Collection(collectionArticle).
|
||||||
Indexes().
|
Indexes().
|
||||||
CreateOne(context.Background(), indexModel)
|
CreateOne(context.Background(), indexModel)
|
||||||
indexModel = mongo.IndexModel{
|
indexModel = mongo.IndexModel{
|
||||||
Keys: bson.D{bson.E{Key: "slug", Value: 1}},
|
Keys: bson.D{bson.E{Key: "slug", Value: 1}},
|
||||||
Options: options.Index().SetUnique(true).SetSparse(true),
|
Options: options.Index().SetUnique(true).SetSparse(true),
|
||||||
}
|
}
|
||||||
db.Database(mongoDBName).Collection(collectionSerie).
|
db.Database.Collection(collectionSerie).
|
||||||
Indexes().
|
Indexes().
|
||||||
CreateOne(context.Background(), indexModel)
|
CreateOne(context.Background(), indexModel)
|
||||||
return db, nil
|
return db, nil
|
||||||
@@ -78,7 +74,7 @@ func (db *mongodb) Init(name, source string) (Store, error) {
|
|||||||
func (db *mongodb) LoadInsertBlogger(ctx context.Context,
|
func (db *mongodb) LoadInsertBlogger(ctx context.Context,
|
||||||
blogger *model.Blogger) (created bool, err error) {
|
blogger *model.Blogger) (created bool, err error) {
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionBlogger)
|
collection := db.Database.Collection(collectionBlogger)
|
||||||
|
|
||||||
filter := bson.M{}
|
filter := bson.M{}
|
||||||
result := collection.FindOne(ctx, filter)
|
result := collection.FindOne(ctx, filter)
|
||||||
@@ -99,7 +95,7 @@ func (db *mongodb) LoadInsertBlogger(ctx context.Context,
|
|||||||
func (db *mongodb) UpdateBlogger(ctx context.Context,
|
func (db *mongodb) UpdateBlogger(ctx context.Context,
|
||||||
fields map[string]interface{}) error {
|
fields map[string]interface{}) error {
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionBlogger)
|
collection := db.Database.Collection(collectionBlogger)
|
||||||
|
|
||||||
filter := bson.M{}
|
filter := bson.M{}
|
||||||
params := bson.M{}
|
params := bson.M{}
|
||||||
@@ -115,7 +111,7 @@ func (db *mongodb) UpdateBlogger(ctx context.Context,
|
|||||||
func (db *mongodb) LoadInsertAccount(ctx context.Context,
|
func (db *mongodb) LoadInsertAccount(ctx context.Context,
|
||||||
acct *model.Account) (created bool, err error) {
|
acct *model.Account) (created bool, err error) {
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionAccount)
|
collection := db.Database.Collection(collectionAccount)
|
||||||
|
|
||||||
filter := bson.M{"username": acct.Username}
|
filter := bson.M{"username": acct.Username}
|
||||||
result := collection.FindOne(ctx, filter)
|
result := collection.FindOne(ctx, filter)
|
||||||
@@ -136,7 +132,7 @@ func (db *mongodb) LoadInsertAccount(ctx context.Context,
|
|||||||
func (db *mongodb) UpdateAccount(ctx context.Context, name string,
|
func (db *mongodb) UpdateAccount(ctx context.Context, name string,
|
||||||
fields map[string]interface{}) error {
|
fields map[string]interface{}) error {
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionAccount)
|
collection := db.Database.Collection(collectionAccount)
|
||||||
|
|
||||||
filter := bson.M{"username": name}
|
filter := bson.M{"username": name}
|
||||||
params := bson.M{}
|
params := bson.M{}
|
||||||
@@ -150,7 +146,7 @@ func (db *mongodb) UpdateAccount(ctx context.Context, name string,
|
|||||||
|
|
||||||
// InsertSerie 创建专题
|
// InsertSerie 创建专题
|
||||||
func (db *mongodb) InsertSerie(ctx context.Context, serie *model.Serie) error {
|
func (db *mongodb) InsertSerie(ctx context.Context, serie *model.Serie) error {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionSerie)
|
collection := db.Database.Collection(collectionSerie)
|
||||||
|
|
||||||
serie.ID = db.nextValue(ctx, counterNameSerie)
|
serie.ID = db.nextValue(ctx, counterNameSerie)
|
||||||
_, err := collection.InsertOne(ctx, serie)
|
_, err := collection.InsertOne(ctx, serie)
|
||||||
@@ -159,7 +155,7 @@ func (db *mongodb) InsertSerie(ctx context.Context, serie *model.Serie) error {
|
|||||||
|
|
||||||
// RemoveSerie 删除专题
|
// RemoveSerie 删除专题
|
||||||
func (db *mongodb) RemoveSerie(ctx context.Context, id int) error {
|
func (db *mongodb) RemoveSerie(ctx context.Context, id int) error {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionSerie)
|
collection := db.Database.Collection(collectionSerie)
|
||||||
|
|
||||||
filter := bson.M{"id": id}
|
filter := bson.M{"id": id}
|
||||||
_, err := collection.DeleteOne(ctx, filter)
|
_, err := collection.DeleteOne(ctx, filter)
|
||||||
@@ -170,7 +166,7 @@ func (db *mongodb) RemoveSerie(ctx context.Context, id int) error {
|
|||||||
func (db *mongodb) UpdateSerie(ctx context.Context, id int,
|
func (db *mongodb) UpdateSerie(ctx context.Context, id int,
|
||||||
fields map[string]interface{}) error {
|
fields map[string]interface{}) error {
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionSerie)
|
collection := db.Database.Collection(collectionSerie)
|
||||||
|
|
||||||
filter := bson.M{"id": id}
|
filter := bson.M{"id": id}
|
||||||
params := bson.M{}
|
params := bson.M{}
|
||||||
@@ -184,7 +180,7 @@ func (db *mongodb) UpdateSerie(ctx context.Context, id int,
|
|||||||
|
|
||||||
// LoadAllSerie 查询所有专题
|
// LoadAllSerie 查询所有专题
|
||||||
func (db *mongodb) LoadAllSerie(ctx context.Context) (model.SortedSeries, error) {
|
func (db *mongodb) LoadAllSerie(ctx context.Context) (model.SortedSeries, error) {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionSerie)
|
collection := db.Database.Collection(collectionSerie)
|
||||||
|
|
||||||
opts := options.Find().SetSort(bson.M{"id": -1})
|
opts := options.Find().SetSort(bson.M{"id": -1})
|
||||||
filter := bson.M{}
|
filter := bson.M{}
|
||||||
@@ -218,14 +214,14 @@ func (db *mongodb) InsertArticle(ctx context.Context, article *model.Article, st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionArticle)
|
collection := db.Database.Collection(collectionArticle)
|
||||||
_, err := collection.InsertOne(ctx, article)
|
_, err := collection.InsertOne(ctx, article)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveArticle 硬删除文章
|
// RemoveArticle 硬删除文章
|
||||||
func (db *mongodb) RemoveArticle(ctx context.Context, id int) error {
|
func (db *mongodb) RemoveArticle(ctx context.Context, id int) error {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionArticle)
|
collection := db.Database.Collection(collectionArticle)
|
||||||
|
|
||||||
filter := bson.M{"id": id}
|
filter := bson.M{"id": id}
|
||||||
_, err := collection.DeleteOne(ctx, filter)
|
_, err := collection.DeleteOne(ctx, filter)
|
||||||
@@ -234,7 +230,7 @@ func (db *mongodb) RemoveArticle(ctx context.Context, id int) error {
|
|||||||
|
|
||||||
// CleanArticles 清理回收站文章
|
// CleanArticles 清理回收站文章
|
||||||
func (db *mongodb) CleanArticles(ctx context.Context, exp time.Time) error {
|
func (db *mongodb) CleanArticles(ctx context.Context, exp time.Time) error {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionArticle)
|
collection := db.Database.Collection(collectionArticle)
|
||||||
|
|
||||||
// 超过两天自动删除
|
// 超过两天自动删除
|
||||||
filter := bson.M{"deleted_at": bson.M{"$gt": time.Time{}, "$lt": exp}}
|
filter := bson.M{"deleted_at": bson.M{"$gt": time.Time{}, "$lt": exp}}
|
||||||
@@ -246,7 +242,7 @@ func (db *mongodb) CleanArticles(ctx context.Context, exp time.Time) error {
|
|||||||
func (db *mongodb) UpdateArticle(ctx context.Context, id int,
|
func (db *mongodb) UpdateArticle(ctx context.Context, id int,
|
||||||
fields map[string]interface{}) error {
|
fields map[string]interface{}) error {
|
||||||
|
|
||||||
collection := db.Database(mongoDBName).Collection(collectionArticle)
|
collection := db.Database.Collection(collectionArticle)
|
||||||
|
|
||||||
filter := bson.M{"id": id}
|
filter := bson.M{"id": id}
|
||||||
params := bson.M{}
|
params := bson.M{}
|
||||||
@@ -260,7 +256,7 @@ func (db *mongodb) UpdateArticle(ctx context.Context, id int,
|
|||||||
|
|
||||||
// LoadArticle 查找文章
|
// LoadArticle 查找文章
|
||||||
func (db *mongodb) LoadArticle(ctx context.Context, id int) (*model.Article, error) {
|
func (db *mongodb) LoadArticle(ctx context.Context, id int) (*model.Article, error) {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionArticle)
|
collection := db.Database.Collection(collectionArticle)
|
||||||
|
|
||||||
filter := bson.M{"id": id}
|
filter := bson.M{"id": id}
|
||||||
result := collection.FindOne(ctx, filter)
|
result := collection.FindOne(ctx, filter)
|
||||||
@@ -276,7 +272,7 @@ func (db *mongodb) LoadArticle(ctx context.Context, id int) (*model.Article, err
|
|||||||
// LoadArticleList 获取文章列表
|
// LoadArticleList 获取文章列表
|
||||||
func (db *mongodb) LoadArticleList(ctx context.Context, search SearchArticles) (
|
func (db *mongodb) LoadArticleList(ctx context.Context, search SearchArticles) (
|
||||||
model.SortedArticles, int, error) {
|
model.SortedArticles, int, error) {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionArticle)
|
collection := db.Database.Collection(collectionArticle)
|
||||||
|
|
||||||
filter := bson.M{}
|
filter := bson.M{}
|
||||||
for k, v := range search.Fields {
|
for k, v := range search.Fields {
|
||||||
@@ -334,7 +330,7 @@ type counter struct {
|
|||||||
|
|
||||||
// nextValue counter value
|
// nextValue counter value
|
||||||
func (db *mongodb) nextValue(ctx context.Context, name string) int {
|
func (db *mongodb) nextValue(ctx context.Context, name string) int {
|
||||||
collection := db.Database(mongoDBName).Collection(collectionCounter)
|
collection := db.Database.Collection(collectionCounter)
|
||||||
|
|
||||||
opts := options.FindOneAndUpdate().SetUpsert(true).
|
opts := options.FindOneAndUpdate().SetUpsert(true).
|
||||||
SetReturnDocument(options.After)
|
SetReturnDocument(options.After)
|
||||||
|
|||||||
@@ -25,79 +25,8 @@ func startTimer() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error("startTimer.generateCrossdomain: ", err)
|
logrus.Error("startTimer.generateCrossdomain: ", err)
|
||||||
}
|
}
|
||||||
|
// 定时刷新
|
||||||
ticker := time.NewTicker(time.Hour)
|
refreshFeedAndSitemap()
|
||||||
for now := range ticker.C {
|
|
||||||
// generate feed & sitemap
|
|
||||||
if now.Hour()%4 == 0 {
|
|
||||||
err = generateFeed()
|
|
||||||
if err != nil {
|
|
||||||
logrus.Error("startTimer.generateFeed: ", err)
|
|
||||||
}
|
|
||||||
err = generateSitemap()
|
|
||||||
if err != nil {
|
|
||||||
logrus.Error("startTimer.generateSitemap: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clean expired articles
|
|
||||||
exp := now.Add(-48 * time.Hour)
|
|
||||||
err := Store.CleanArticles(context.Background(), exp)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Error("startTimer.CleanArticles: ", err)
|
|
||||||
}
|
|
||||||
// fetch disqus count
|
|
||||||
if now.Hour()%5 == 0 {
|
|
||||||
err = DisqusClient.PostsCount(Ei.ArticlesMap)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Error("startTimer.PostsCount: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateFeed 定时刷新feed
|
|
||||||
func generateFeed() error {
|
|
||||||
tpl := XMLTemplate.Lookup("feedTpl.xml")
|
|
||||||
if tpl == nil {
|
|
||||||
return errors.New("not found: feedTpl.xml")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, articles := Ei.PageArticleFE(1, 20)
|
|
||||||
params := map[string]interface{}{
|
|
||||||
"Title": Ei.Blogger.BTitle,
|
|
||||||
"SubTitle": Ei.Blogger.SubTitle,
|
|
||||||
"Host": config.Conf.Host,
|
|
||||||
"FeedrURL": config.Conf.FeedRPC.FeedrURL,
|
|
||||||
"BuildDate": time.Now().Format(time.RFC1123Z),
|
|
||||||
"Articles": articles,
|
|
||||||
}
|
|
||||||
path := filepath.Join(config.EtcDir, "assets", "feed.xml")
|
|
||||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
return tpl.Execute(f, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateSitemap 定时刷新sitemap
|
|
||||||
func generateSitemap() error {
|
|
||||||
tpl := XMLTemplate.Lookup("sitemapTpl.xml")
|
|
||||||
if tpl == nil {
|
|
||||||
return errors.New("not found: sitemapTpl.xml")
|
|
||||||
}
|
|
||||||
|
|
||||||
params := map[string]interface{}{
|
|
||||||
"Articles": Ei.Articles,
|
|
||||||
"Host": config.Conf.Host,
|
|
||||||
}
|
|
||||||
path := filepath.Join(config.EtcDir, "assets", "sitemap.xml")
|
|
||||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
return tpl.Execute(f, params)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateOpensearch 生成opensearch.xml
|
// generateOpensearch 生成opensearch.xml
|
||||||
@@ -158,3 +87,75 @@ func generateCrossdomain() error {
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
return tpl.Execute(f, params)
|
return tpl.Execute(f, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refreshFeedAndSitemap 定时刷新feed和sitemap
|
||||||
|
func refreshFeedAndSitemap() {
|
||||||
|
defer time.AfterFunc(time.Hour*4, refreshFeedAndSitemap)
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
// generate feed & sitemap
|
||||||
|
err := generateFeed()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("startTimer.generateFeed: ", err)
|
||||||
|
}
|
||||||
|
err = generateSitemap()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("startTimer.generateSitemap: ", err)
|
||||||
|
}
|
||||||
|
// clean expired articles
|
||||||
|
exp := now.Add(-48 * time.Hour)
|
||||||
|
err = Store.CleanArticles(context.Background(), exp)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("startTimer.CleanArticles: ", err)
|
||||||
|
}
|
||||||
|
// fetch disqus count
|
||||||
|
err = DisqusClient.PostsCount(Ei.ArticlesMap)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("startTimer.PostsCount: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateFeed 定时刷新feed
|
||||||
|
func generateFeed() error {
|
||||||
|
tpl := XMLTemplate.Lookup("feedTpl.xml")
|
||||||
|
if tpl == nil {
|
||||||
|
return errors.New("not found: feedTpl.xml")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, articles := Ei.PageArticleFE(1, 20)
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"Title": Ei.Blogger.BTitle,
|
||||||
|
"SubTitle": Ei.Blogger.SubTitle,
|
||||||
|
"Host": config.Conf.Host,
|
||||||
|
"FeedrURL": config.Conf.FeedRPC.FeedrURL,
|
||||||
|
"BuildDate": time.Now().Format(time.RFC1123Z),
|
||||||
|
"Articles": articles,
|
||||||
|
}
|
||||||
|
path := filepath.Join(config.EtcDir, "assets", "feed.xml")
|
||||||
|
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return tpl.Execute(f, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateSitemap 定时刷新sitemap
|
||||||
|
func generateSitemap() error {
|
||||||
|
tpl := XMLTemplate.Lookup("sitemapTpl.xml")
|
||||||
|
if tpl == nil {
|
||||||
|
return errors.New("not found: sitemapTpl.xml")
|
||||||
|
}
|
||||||
|
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"Articles": Ei.Articles,
|
||||||
|
"Host": config.Conf.Host,
|
||||||
|
}
|
||||||
|
path := filepath.Join(config.EtcDir, "assets", "sitemap.xml")
|
||||||
|
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return tpl.Execute(f, params)
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
"github.com/eiblog/eiblog/cmd/eiblog/handler/file"
|
"github.com/eiblog/eiblog/cmd/eiblog/handler/file"
|
||||||
"github.com/eiblog/eiblog/cmd/eiblog/handler/pages"
|
"github.com/eiblog/eiblog/cmd/eiblog/handler/pages"
|
||||||
"github.com/eiblog/eiblog/cmd/eiblog/handler/swag"
|
"github.com/eiblog/eiblog/cmd/eiblog/handler/swag"
|
||||||
|
|
||||||
"github.com/eiblog/eiblog/pkg/middleware"
|
"github.com/eiblog/eiblog/pkg/middleware"
|
||||||
|
"github.com/eiblog/eiblog/tools"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -36,7 +36,7 @@ func runHTTPServer(endRun chan error) {
|
|||||||
middleware.SessionOpts{
|
middleware.SessionOpts{
|
||||||
Name: "su",
|
Name: "su",
|
||||||
Secure: config.Conf.RunMode.IsReleaseMode(),
|
Secure: config.Conf.RunMode.IsReleaseMode(),
|
||||||
Secret: []byte("ZGlzvcmUoMTAsICI="),
|
Secret: tools.CryptoRand(16),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// swag
|
// swag
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
mongodb:
|
mongodb:
|
||||||
image: mongo:3.2
|
image: mongo:3.6
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/mgodb:/data/db
|
- ${PWD}/mgodb:/data/db
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
RunModeLocal RunMode = "local" // 本地环境
|
RunModeLocal RunMode = "local" // 本地环境
|
||||||
RunModeDev RunMode = "dev" // 开发环境
|
RunModeDev RunMode = "dev" // 开发环境
|
||||||
RunModeProd RunMode = "pro" // 生产环境
|
RunModeProd RunMode = "prod" // 生产环境
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunMode 运行模式
|
// RunMode 运行模式
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/eiblog/eiblog/pkg/config"
|
"github.com/eiblog/eiblog/pkg/config"
|
||||||
|
|
||||||
@@ -16,7 +15,7 @@ import (
|
|||||||
// NewMDB new mongodb
|
// NewMDB new mongodb
|
||||||
// https://docs.mongodb.com/manual/reference/connection-string/
|
// https://docs.mongodb.com/manual/reference/connection-string/
|
||||||
// mongodb://db0.example.com,db1.example.com,db2.example.com/dbname?replicaSet=myRepl&w=majority&wtimeoutMS=5000
|
// mongodb://db0.example.com,db1.example.com,db2.example.com/dbname?replicaSet=myRepl&w=majority&wtimeoutMS=5000
|
||||||
func NewMDB(opts config.Database) (*mongo.Database, error) {
|
func NewMDB(ctx context.Context, opts config.Database) (*mongo.Database, error) {
|
||||||
if opts.Driver != "mongodb" {
|
if opts.Driver != "mongodb" {
|
||||||
return nil, errors.New("db: driver must be mongodb, but " + opts.Driver)
|
return nil, errors.New("db: driver must be mongodb, but " + opts.Driver)
|
||||||
}
|
}
|
||||||
@@ -29,8 +28,6 @@ func NewMDB(opts config.Database) (*mongo.Database, error) {
|
|||||||
return nil, errors.New("db: please specify a database")
|
return nil, errors.New("db: please specify a database")
|
||||||
}
|
}
|
||||||
database = database[1:]
|
database = database[1:]
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// remove database
|
// remove database
|
||||||
u.Path = ""
|
u.Path = ""
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package tools
|
package tools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -128,3 +129,14 @@ func IgnoreHTMLTag(src string) string {
|
|||||||
// 去除换行符
|
// 去除换行符
|
||||||
return regexpEnter.ReplaceAllString(src, "")
|
return regexpEnter.ReplaceAllString(src, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CryptoRand random with crypto/rand
|
||||||
|
func CryptoRand(byteLen int) []byte {
|
||||||
|
buf := make([]byte, byteLen)
|
||||||
|
|
||||||
|
_, err := rand.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("rand: error reading random bytes: %s", err))
|
||||||
|
}
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user