Skip to content

Commit

Permalink
feat: Implement legacy post handling and conversion for backward comp…
Browse files Browse the repository at this point in the history
…atibility
  • Loading branch information
Laisky committed Nov 13, 2024
1 parent 1d0438b commit 0799900
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 11 deletions.
120 changes: 120 additions & 0 deletions internal/web/blog/model/posts.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,126 @@ type Post struct {
ArweaveId []ArweaveHistoryItem `bson:"arweave_id" json:"arweave_id"`
}

type legacyOid struct {
Oid string `json:"$oid"`
}

func (o legacyOid) ObjectId() (primitive.ObjectID, error) {
return primitive.ObjectIDFromHex(o.Oid)
}

type legacyTime struct {
Date string `json:"$date"`
}

func (t legacyTime) Time() (time.Time, error) {
return time.Parse(time.RFC3339, t.Date)
}

type legacyI18N struct {
UpdateAt legacyTime `bson:"update_at" json:"update_at"`
EnUs PostI18NLanguage `bson:"en_us" json:"en_us"`
}

func (i legacyI18N) I18N() (PostI18N, error) {
updateAt, err := i.UpdateAt.Time()
if err != nil {
return PostI18N{}, err
}

return PostI18N{
UpdateAt: updateAt,
EnUs: i.EnUs,
}, nil
}

// LegacyPost The old article history JSON was generated by Python,
// and the generated keys and structure are inconsistent with the new Go code,
// so the structure is redefined here to facilitate the conversion of the old data to the new data.
type LegacyPost struct {
// ID unique identifier for the post
ID legacyOid `bson:"_id,omitempty" json:"_id"`
// CreatedAt time when the post was created
CreatedAt legacyTime `bson:"post_created_at" json:"post_created_at"`
// ModifiedAt time when the post was last modified
ModifiedAt legacyTime `bson:"post_modified_gmt" json:"post_modified_gmt"`
// Title title of the post
Title string `bson:"post_title" json:"post_title"`
// Type type of the post
Type string `bson:"post_type" json:"post_type"`
// Status status of the post
Status string `bson:"post_status" json:"post_status"`
// Name name of the post
Name string `bson:"post_name" json:"post_name"`
// Content content of the post
Content string `bson:"post_content" json:"post_content"`
// Markdown markdown content of the post
Markdown string `bson:"post_markdown" json:"post_markdown"`
// Author author of the post
Author legacyOid `bson:"post_author,omitempty" json:"post_author"`
// Menu menu of the post
Menu string `bson:"post_menu" json:"post_menu"`
// Password password of the post
Password string `bson:"post_password" json:"-"`
// Category category of the post
Category legacyOid `bson:"category,omitempty" json:"category"`
// Tags tags of the post
Tags []string `bson:"post_tags" json:"post_tags"`
// Hidden whether the post is hidden or not
Hidden bool `bson:"hidden" json:"hidden"`
// I18N internationalization of the post
I18N legacyI18N `bson:"i18n" json:"i18n"`
// Language language of the post content or markdown
Language string `bson:"-" json:"language"`
// ArweaveId arweave id of the post
ArweaveId []ArweaveHistoryItem `bson:"arweave_id" json:"arweave_id"`
}

func (lp LegacyPost) Post() (p *Post, err error) {
p = new(Post)
if p.I18N, err = lp.I18N.I18N(); err != nil {
return nil, err
}

if p.CreatedAt, err = lp.CreatedAt.Time(); err != nil {
return nil, err
}

if p.ModifiedAt, err = lp.ModifiedAt.Time(); err != nil {
return nil, err
}

p.ID, err = lp.ID.ObjectId()
if err != nil {
return nil, err
}

p.Author, err = lp.Author.ObjectId()
if err != nil {
return nil, err
}

p.Category, err = lp.Category.ObjectId()
if err != nil {
return nil, err
}

p.Title = lp.Title
p.Type = lp.Type
p.Status = lp.Status
p.Name = lp.Name
p.Content = lp.Content
p.Markdown = lp.Markdown
p.Menu = lp.Menu
p.Password = lp.Password
p.Tags = lp.Tags
p.Hidden = lp.Hidden
p.Language = lp.Language
p.ArweaveId = lp.ArweaveId

return p, nil
}

// ArweaveHistoryItem arweave history item
type ArweaveHistoryItem struct {
Time time.Time `bson:"time" json:"time"`
Expand Down
43 changes: 32 additions & 11 deletions internal/web/blog/service/posts.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ func (s *Blog) LoadPostInfo(ctx context.Context) (*dto.PostInfo, error) {
}, nil
}

func makeReader(cnt []byte) (reader io.Reader, err error) {
if bytes.HasPrefix(cnt, []byte("gz::")) {
cnt = cnt[4:]

reader, err = gzip.NewReader(bytes.NewReader(cnt))
if err != nil {
return nil, errors.Wrap(err, "new gzip reader")
}
} else {
reader = bytes.NewBuffer(cnt)
}

return reader, nil
}

// LoadPostHistory load post history by arweave file id
func (s *Blog) LoadPostHistory(ctx context.Context, fileID string, language models.Language) (*model.Post, error) {
logger := gmw.GetLogger(ctx)
Expand Down Expand Up @@ -172,21 +187,27 @@ func (s *Blog) LoadPostHistory(ctx context.Context, fileID string, language mode
return nil, errors.Wrap(err, "read all")
}

var reader io.Reader
if bytes.HasPrefix(cnt, []byte("gz::")) {
cnt = cnt[4:]

reader, err = gzip.NewReader(bytes.NewReader(cnt))
if err != nil {
return nil, errors.Wrap(err, "new gzip reader")
}
} else {
reader = bytes.NewReader(cnt)
reader, err := makeReader(cnt)
if err != nil {
return nil, errors.Wrap(err, "get reader")
}

post := new(model.Post)
if err = json.NewDecoder(reader).Decode(post); err != nil {
return nil, errors.Wrap(err, "decode post")
// try legacy struct
reader, err := makeReader(cnt)
if err != nil {
return nil, errors.Wrap(err, "get reader")
}

legacyPost := new(model.LegacyPost)
if err2 := json.NewDecoder(reader).Decode(legacyPost); err2 != nil {
return nil, errors.Wrap(errors.Join(err, err2), "cannot decode post by legacy struct")
}

if post, err = legacyPost.Post(); err != nil {
return nil, errors.Wrap(err, "convert legacy to current post format")
}
}

if language != models.LanguageZhCn && post.I18N.EnUs.PostContent != "" {
Expand Down

0 comments on commit 0799900

Please sign in to comment.