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

Commit

Permalink
feat(importer): import from valine.
Browse files Browse the repository at this point in the history
Signed-off-by: qwqcode <[email protected]>
  • Loading branch information
qwqcode committed Oct 26, 2021
1 parent fa2c760 commit bce0598
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 12 deletions.
16 changes: 16 additions & 0 deletions lib/importer/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package importer

var ExampleImporter = &_ExampleImporter{
ImporterInfo: ImporterInfo{
Name: "example",
Desc: "从 Example 导入数据",
Note: "",
},
}

type _ExampleImporter struct {
ImporterInfo
}

func (imp *_ExampleImporter) Run(basic *BasicParams, payload []string) {
}
24 changes: 14 additions & 10 deletions lib/importer/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Map = map[string]interface{}
var Supports = []interface{}{
TypechoImporter,
WordPressImporter,
ValineImporter,
}

func RunByName(dataType string, payload []string) {
Expand All @@ -41,12 +42,15 @@ func RunByName(dataType string, payload []string) {
}

fmt.Print("\n")
PrintTable([]table.Row{
tableData := []table.Row{
{"数据搬家 - 导入"},
{strings.ToUpper(name)},
{desc},
{note},
})
}
if note != "" {
tableData = append(tableData, table.Row{note})
}
PrintTable(tableData)
fmt.Print("\n")

//t1 := time.Now()
Expand Down Expand Up @@ -120,29 +124,29 @@ func GetArrayParamsFrom(payload []string, key string) []string {
}

type BasicParams struct {
TargetSiteName string `json:"target_site_name"`
TargetSiteUrl string `json:"target_site_url"`
TargetSiteName string
TargetSiteUrl string
}

func GetBasicParamsFrom(payload []string) *BasicParams {
basic := BasicParams{}
GetParamsFrom(payload).To(map[string]*string{
"target_site_name": &basic.TargetSiteName,
"target_site_url": &basic.TargetSiteUrl,
"ts_name": &basic.TargetSiteName,
"ts_url": &basic.TargetSiteUrl,
})

return &basic
}

func RequiredBasicTargetSite(basic *BasicParams) {
if basic.TargetSiteName == "" {
logrus.Fatal("请附带参数 `target_site_name:<站点名称>`")
logrus.Fatal("请附带参数 `ts_name:<目标站点名称>`")
}
if basic.TargetSiteUrl == "" {
logrus.Fatal("请附带参数 `target_site_url:<站点根目录 URL>`")
logrus.Fatal("请附带参数 `ts_url:<目标站点根目录 URL>`")
}
if !lib.ValidateURL(basic.TargetSiteUrl) {
logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 必须为 URL 格式")
logrus.Fatal("参数 `ts_url:<目标站点根目录 URL>` 必须为 URL 格式")
}
}

Expand Down
194 changes: 194 additions & 0 deletions lib/importer/valine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package importer

import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/ArtalkJS/ArtalkGo/lib"
"github.com/ArtalkJS/ArtalkGo/model"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/sirupsen/logrus"
)

var ValineImporter = &_ValineImporter{
ImporterInfo: ImporterInfo{
Name: "valine",
Desc: "从 Valine 导入数据",
Note: "",
},
}

type _ValineImporter struct {
ImporterInfo
TargetSite model.Site
}

func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) {
RequiredBasicTargetSite(basic)

imp.TargetSite = SiteReady(basic)

// 读取文件
var jsonFile string
GetParamsFrom(payload).To(map[string]*string{
"json_file": &jsonFile,
})

if jsonFile == "" {
logrus.Fatal("请附带参数 `json_file:<Valine 导出的 JSON 文件路径>`")
}
if _, err := os.Stat(jsonFile); errors.Is(err, os.ErrNotExist) {
logrus.Fatal("文件不存在,请检查参数 `json_file` 传入路径是否正确")
}

buf, err := ioutil.ReadFile(jsonFile)
if err != nil {
logrus.Fatal("json 文件打开失败:", err)
}
jsonStr := string(buf)

// 解析 JSON
comments, err := ParseValineCommentJSON(jsonStr)
if err != nil {
logrus.Fatal("json 解析失败:", err)
}

// 汇总
fmt.Print("# 请过目:\n\n")

// 第一条评论
if len(comments) > 0 {
fmt.Printf("[第一条评论]\n\n"+
" %#v\n\n", comments[0])
}

PrintTable([]table.Row{
{"目标站点名", basic.TargetSiteName},
{"目标站点 URL", basic.TargetSiteUrl},
{"评论数量", len(comments)},
})

fmt.Print("\n")

// 确认开始
if !Confirm("确认开始导入吗?") {
os.Exit(0)
}

// 准备导入评论
fmt.Print("\n")

ImportValineComments(basic, comments)
}

func ParseValineCommentJSON(jsonStr string) ([]ValineComment, error) {
var list []ValineComment
err := json.Unmarshal([]byte(jsonStr), &list)
if err != nil {
return []ValineComment{}, err
}

return list, nil
}

func ImportValineComments(basic *BasicParams, comments []ValineComment) {
siteName := basic.TargetSiteName

// 查找父评论
idDict := map[string]int{}
id := 1

idChanges := map[uint]uint{}

for _, c := range comments {
idDict[c.ObjectId] = id
id++
}

for _, c := range comments {
// PageKey
tSiteUrl := basic.TargetSiteUrl
tSiteUrl = strings.TrimSuffix(tSiteUrl, "/") + "/"
pageKey := tSiteUrl + strings.TrimPrefix(lib.GetUrlWithoutDomain(c.Url), "/")

// 创建 user
user := model.FindCreateUser(c.Nick, c.Mail)
page := model.FindCreatePage(pageKey, "", siteName)

if c.Link != "" {
user.Link = c.Link
}
model.UpdateUser(&user)

// 创建新 comment 实例
nComment := model.Comment{
Content: c.Comment,

PageKey: page.Key,
SiteName: basic.TargetSiteName,

UserID: user.ID,
UA: c.UA,
IP: c.IP,

Rid: uint(idDict[c.Rid]),

IsCollapsed: false,
IsPending: false,
}

// 日期恢复
createdVal := fmt.Sprintf("%v", c.CreatedAt)
updatedVal := fmt.Sprintf("%v", c.UpdatedAt)
nComment.CreatedAt = ParseDate(createdVal)
nComment.UpdatedAt = ParseDate(updatedVal)

// 保存到数据库
err := lib.DB.Create(&nComment).Error
if err != nil {
logrus.Error(fmt.Sprintf("评论源 ID:%s 保存失败", c.ObjectId))
continue
}

idChanges[uint(idDict[c.ObjectId])] = nComment.ID
}

// reply id 重建
for _, newId := range idChanges {
nComment := model.FindComment(newId, siteName)
if nComment.Rid == 0 {
continue
}
if newId, isExist := idChanges[nComment.Rid]; isExist {
nComment.Rid = newId
err := lib.DB.Save(&nComment).Error
if err != nil {
logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err)
}
}
}

fmt.Print("\n")
logrus.Info("RID 重构完毕")
}

type ValineComment struct {
ObjectId string `json:"objectId"`
Nick string `json:"nick"`
IP string `json:"ip"`
Mail string `json:"mail"`
MailMd5 string `json:"mailMd5"`
IsSpam string `json:"isSpam"`
UA string `json:"ua"`
Link string `json:"link"`
Pid string `json:"pid"`
Rid string `json:"rid"`
Comment string `json:"comment"`
Url string `json:"url"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
4 changes: 2 additions & 2 deletions lib/importer/wordpress.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package importer

var WordPressImporter = &_TypechoImporter{
var WordPressImporter = &_WordPressImporter{
ImporterInfo: ImporterInfo{
Name: "wordpress",
Desc: "从 WordPress 导入数据",
Expand All @@ -12,5 +12,5 @@ type _WordPressImporter struct {
ImporterInfo
}

func (i _WordPressImporter) Run(basic *BasicParams, payload []string) {
func (imp *_WordPressImporter) Run(basic *BasicParams, payload []string) {
}
7 changes: 7 additions & 0 deletions lib/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/mail"
"net/url"
"os"
"regexp"
"strings"

"github.com/jeremywohl/flatten"
Expand Down Expand Up @@ -77,6 +78,12 @@ func AddQueryToURL(urlStr string, queryMap map[string]string) string {
return u.String()
}

// "https://artalk.js.org/guide/describe.html" => "guide/describe.html"
func GetUrlWithoutDomain(urlStr string) string {
r := regexp.MustCompile(`^http[s]?:\/\/.+?\/+`)
return r.ReplaceAllString(urlStr, "")
}

// ContainsStr returns true if an str is present in a iteratee.
func ContainsStr(s []string, v string) bool {
for _, vv := range s {
Expand Down

0 comments on commit bce0598

Please sign in to comment.