210 linhas
4.9 KiB
Go
210 linhas
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
|
|
"git.kirsle.net/apps/gophertype/pkg"
|
|
"git.kirsle.net/apps/gophertype/pkg/console"
|
|
_ "git.kirsle.net/apps/gophertype/pkg/controllers"
|
|
"git.kirsle.net/apps/gophertype/pkg/models"
|
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
|
jsondb "github.com/kirsle/blog/jsondb"
|
|
mComments "github.com/kirsle/blog/models/comments"
|
|
mPosts "github.com/kirsle/blog/models/posts"
|
|
)
|
|
|
|
// Command-line flags.
|
|
var (
|
|
optSourceRoot string
|
|
optRoot string
|
|
|
|
// Database option flags.
|
|
optSQLite string
|
|
optPostgres string
|
|
optMySQL string
|
|
|
|
// Chosen DB options.
|
|
dbDriver string
|
|
dbPath string
|
|
)
|
|
|
|
// Other global variables
|
|
var (
|
|
JsonDB *jsondb.DB
|
|
)
|
|
|
|
func init() {
|
|
flag.StringVar(&optSourceRoot, "srcroot", "", "User root from old kirsle/blog website")
|
|
flag.StringVar(&optRoot, "root", "", "User root for GopherType")
|
|
|
|
// Database driver. Choose one.
|
|
flag.StringVar(&optSQLite, "sqlite3", "", "Use SQLite database, default 'database.sqlite'")
|
|
flag.StringVar(&optPostgres, "postgres", "",
|
|
"Use Postgres database, format: "+
|
|
"host=myhost port=myport user=gorm dbname=gorm password=mypassword")
|
|
flag.StringVar(&optMySQL, "mysql", "",
|
|
"Use MySQL database, format: "+
|
|
"user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
|
|
}
|
|
|
|
func main() {
|
|
console.SetDebug(false)
|
|
flag.Parse()
|
|
|
|
// Validate the choice of database.
|
|
if optSQLite != "" {
|
|
dbDriver = "sqlite3"
|
|
dbPath = optSQLite
|
|
} else if optPostgres != "" {
|
|
dbDriver = "postgres"
|
|
dbPath = optPostgres
|
|
} else if optMySQL != "" {
|
|
dbDriver = "mysql"
|
|
dbPath = optMySQL
|
|
} else {
|
|
fmt.Print(
|
|
"Specify a DB driver for Gophertype, similar to the gophertype command.",
|
|
)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Validate the roots are given.
|
|
if optSourceRoot == "" {
|
|
fmt.Print(
|
|
"Missing -srcroot parameter: this should be the User Root from the legacy kirsle/blog site.",
|
|
)
|
|
os.Exit(1)
|
|
}
|
|
if optRoot == "" {
|
|
fmt.Print(
|
|
"Missing required -root parameter: this is the User Root for Gophertype",
|
|
)
|
|
}
|
|
|
|
// Initialize the old JsonDB.
|
|
|
|
app := gophertype.NewSite(optRoot)
|
|
app.UseDB(dbDriver, dbPath)
|
|
|
|
initJsonDB()
|
|
doMigrate()
|
|
}
|
|
|
|
// Initialize the old kirsle/blog JsonDB.
|
|
func initJsonDB() {
|
|
JsonDB = jsondb.New(filepath.Join(optSourceRoot, ".private"))
|
|
mPosts.DB = JsonDB
|
|
mComments.DB = JsonDB
|
|
}
|
|
|
|
// doMigrate is the head of the migrate functions.
|
|
func doMigrate() {
|
|
migratePosts()
|
|
migrateComments()
|
|
}
|
|
|
|
// migratePosts migrates blog posts over.
|
|
func migratePosts() {
|
|
console.Warn("BEGIN: Migrating blog posts")
|
|
idx, err := mPosts.GetIndex()
|
|
if err != nil {
|
|
panic("migratePosts: GetIndex: " + err.Error())
|
|
}
|
|
|
|
// Sort the IDs to make it pretty.
|
|
var sortedIds = []int{}
|
|
for id := range idx.Posts {
|
|
sortedIds = append(sortedIds, id)
|
|
}
|
|
sort.Ints(sortedIds)
|
|
|
|
for _, id := range sortedIds {
|
|
post, err := mPosts.Load(id)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("migratePosts: error loading legacy post ID %d: %s", id, err))
|
|
}
|
|
|
|
console.Info("Post ID %d: %s", id, post.Title)
|
|
|
|
// Create the post in Gophertype.
|
|
p := models.Post{
|
|
Title: post.Title,
|
|
Fragment: post.Fragment,
|
|
ContentType: post.ContentType,
|
|
AuthorID: uint(post.AuthorID),
|
|
Body: post.Body,
|
|
Privacy: post.Privacy,
|
|
Sticky: post.Sticky,
|
|
EnableComments: post.EnableComments,
|
|
}
|
|
p.ID = uint(post.ID)
|
|
p.CreatedAt = post.Created
|
|
p.UpdatedAt = post.Updated
|
|
|
|
// Convert tags.
|
|
for _, tag := range post.Tags {
|
|
p.Tags = append(p.Tags, models.TaggedPost{
|
|
Tag: tag,
|
|
})
|
|
}
|
|
|
|
err = p.Save()
|
|
if err != nil {
|
|
console.Error("Error saving post %d: %s", p.ID, err)
|
|
}
|
|
}
|
|
|
|
console.Warn("FINISH: Migrating blog posts")
|
|
}
|
|
|
|
// migrateComments migrates comments over.
|
|
func migrateComments() {
|
|
console.Warn("BEGIN: Migrating comments")
|
|
|
|
// Find all the comment threads.
|
|
files, err := JsonDB.List("comments/threads")
|
|
if err != nil {
|
|
panic("Error listing comments: " + err.Error())
|
|
}
|
|
for _, file := range files {
|
|
document := filepath.Base(file)
|
|
thread, err := mComments.Load(document)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("Error loading comment thread %s: %s", file, err))
|
|
}
|
|
|
|
for _, comment := range thread.Comments {
|
|
// Migrate to the new model.
|
|
com := models.Comment{
|
|
Thread: thread.ID,
|
|
UserID: uint(comment.UserID),
|
|
Name: comment.Name,
|
|
Email: comment.Email,
|
|
Avatar: comment.Avatar,
|
|
Body: comment.Body,
|
|
EditToken: comment.EditToken,
|
|
DeleteToken: comment.DeleteToken,
|
|
}
|
|
com.CreatedAt = comment.Created
|
|
com.UpdatedAt = comment.Updated
|
|
|
|
// Special case for guestbook page.
|
|
if thread.ID == "guestbook" {
|
|
com.OriginURL = "/guestbook"
|
|
}
|
|
|
|
if err := com.Save(); err != nil {
|
|
console.Error("Error saving comment: %s", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
console.Warn("FINISH: Migrating comments")
|
|
}
|