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") }