Post-Migrator/services/migration/migrate-posts.go

342 lines
11 KiB
Go
Raw Normal View History

2024-05-17 18:49:55 +00:00
package migration
import (
"database/sql"
"federated.computer/wp-sync-slowtwitch/services/slowtwitch"
"federated.computer/wp-sync-slowtwitch/services/wordpress"
"fmt"
"slices"
2024-05-20 01:35:53 +00:00
"strconv"
2024-05-17 18:49:55 +00:00
"strings"
)
type MigratePosts struct {
SlowtwitchDatabase *sql.DB
ResultsDatabase *sql.DB
WordpressBaseUrl string
WordpressUser string
WordpressPassword string
}
2024-05-21 21:15:43 +00:00
func (migration MigratePosts) Execute() []PostResult {
2024-05-17 18:49:55 +00:00
slowtwitchPostIds, err := slowtwitch.GetAllPostIds(migration.SlowtwitchDatabase)
if err != nil {
panic("Could not migrate posts: " + err.Error())
2024-05-17 18:49:55 +00:00
}
migratedPostIds, err := GetAllMigratedPostIds(migration.ResultsDatabase)
if err != nil {
panic("Could not migrate posts:" + err.Error())
2024-05-17 18:49:55 +00:00
}
2024-05-19 21:00:33 +00:00
//get wordpress tag data, there are only 3
tags := []string{"swim", "bike", "run"}
wpTagData, wpTagErr := wordpress.GetTags(tags, migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword)
if wpTagErr != nil {
panic("Could not migrate posts due to tags not found:" + wpTagErr.Error())
2024-05-19 21:00:33 +00:00
}
2024-05-17 18:49:55 +00:00
slowtwitchPostIdsForMigration := getPostIdsThatNeedMigration(slowtwitchPostIds, migratedPostIds)
2024-05-21 21:15:43 +00:00
var postResults []PostResult
2024-05-17 18:49:55 +00:00
for _, postId := range slowtwitchPostIdsForMigration {
errorMessage := ""
//migrate
2024-05-21 17:08:47 +00:00
postBase, postBaseErr := slowtwitch.GetPostBase(postId, migration.SlowtwitchDatabase)
if postBaseErr != nil {
errorMessage = errorMessage + postBaseErr.Error()
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
continue
}
2024-05-17 18:49:55 +00:00
createWordpressPost := wordpress.CreatePost{
Title: postBase.Title,
Excerpt: postBase.Description,
2024-05-20 01:35:53 +00:00
Status: "publish",
2024-05-17 18:49:55 +00:00
}
if postBase.DatePublished.Valid {
2024-05-20 01:35:53 +00:00
t := postBase.DatePublished.Time
timeString := fmt.Sprintf("%d-%02d-%02dT%02d:%02d:%02d",
t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())
createWordpressPost.Date = timeString
2024-05-17 18:49:55 +00:00
} else {
errorMessage = errorMessage + "Invalid Date Published"
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
2024-05-17 18:49:55 +00:00
continue
}
2024-05-19 21:00:33 +00:00
for _, tag := range wpTagData {
if postBase.Bike == true && tag.Name == "bike" {
createWordpressPost.Tags = append(createWordpressPost.Tags, tag.Id)
}
if postBase.Swim == true && tag.Name == "swim" {
createWordpressPost.Tags = append(createWordpressPost.Tags, tag.Id)
}
if postBase.Run == true && tag.Name == "run" {
createWordpressPost.Tags = append(createWordpressPost.Tags, tag.Id)
}
}
2024-05-17 18:49:55 +00:00
var wordPressCategoryIds []int
var firstCategoryResult CategoryResult
for _, slowtwitchCategoryId := range postBase.CategoryIds {
categoryResult, err := GetSlowtwitchCategoryResult(slowtwitchCategoryId, migration.ResultsDatabase)
if err != nil {
errorMessage = errorMessage + err.Error()
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
2024-05-17 18:49:55 +00:00
continue
}
wordPressCategoryIds = append(wordPressCategoryIds, categoryResult.WordpressId)
firstCategoryResult = categoryResult
}
if len(wordPressCategoryIds) == 0 {
errorMessage = "This post has no categories and is broken on the production site."
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
continue
}
2024-05-17 18:49:55 +00:00
createWordpressPost.Categories = wordPressCategoryIds
//Get Author ID
2024-05-21 17:08:47 +00:00
editor, findEditorErr := GetEditor(postBase.Author, migration.ResultsDatabase)
2024-05-17 18:49:55 +00:00
2024-05-21 17:08:47 +00:00
if findEditorErr != nil {
errorMessage = errorMessage + findEditorErr.Error()
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
2024-05-17 18:49:55 +00:00
continue
}
createWordpressPost.Author = editor.WordpressId
//Get old link
oldLink := strings.ReplaceAll(firstCategoryResult.OldUrl, "index.html", "") + slowtwitch.ConvertPostTitleToPath(postBase.Title, postBase.Id)
linkStatus := slowtwitch.GetPageStatus(oldLink)
if linkStatus == 404 {
errorMessage = errorMessage + "Page not found on Slowtwitch"
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
2024-05-17 18:49:55 +00:00
continue
}
2024-05-19 21:00:33 +00:00
2024-05-17 18:49:55 +00:00
//Get page, parse out post data and images
//Upload images to wordpress, swap out with new image urls
//Submit
2024-05-21 17:08:47 +00:00
imagePaths, html, retreiveHtmlErr := slowtwitch.GetImagesAndPostHtml(oldLink)
if retreiveHtmlErr != nil {
errorMessage = errorMessage + retreiveHtmlErr.Error()
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
2024-05-19 21:00:33 +00:00
continue
}
2024-05-21 17:08:47 +00:00
//Create images from the image paths
2024-05-19 21:00:33 +00:00
var imageResults []ImageResult
for i, imagePath := range imagePaths {
2024-05-21 17:08:47 +00:00
//construct URL
2024-05-19 21:00:33 +00:00
imageUrl := "https://www.slowtwitch.com" + imagePath
createWordpressImage := wordpress.CreateImage{
Url: imageUrl,
}
2024-05-21 17:08:47 +00:00
//submit image
wordpressImage, wordpressImageErr := createWordpressImage.Execute(migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword)
2024-05-19 21:00:33 +00:00
2024-05-21 17:08:47 +00:00
if wordpressImageErr != nil {
errorMessage = errorMessage + wordpressImageErr.Error()
createImageFailureResult(imageUrl, migration.ResultsDatabase)
2024-05-19 21:00:33 +00:00
continue
}
//first photo is the featured photo
if i == 0 {
createWordpressPost.FeaturedMedia = wordpressImage.Id
}
//begin process of recording result
imageResult := ImageResult{
OldUrl: imageUrl,
NewUrl: wordpressImage.Link,
WordpressId: wordpressImage.Id,
IsSuccess: true,
}
imageResults = append(imageResults, imageResult)
//replace old links with new in post html
strings.ReplaceAll(html, imageUrl, wordpressImage.Link)
//create redirect
2024-05-21 17:08:47 +00:00
imageRedirect := wordpress.CreateRedirect{
2024-05-19 21:00:33 +00:00
Title: postBase.Title + "image-" + string((i + 1)),
Url: imagePath,
MatchType: "page",
ActionType: "url",
ActionCode: 301,
GroupId: 1,
ActionData: wordpress.ActionData{
Url: "/" + wordpressImage.Slug,
},
}
2024-05-21 17:08:47 +00:00
_, imageRedirectErr := imageRedirect.Execute(migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword)
if imageRedirectErr != nil {
fmt.Println("Failed to create image redirect:", imageUrl, ":", imageRedirectErr.Error())
}
2024-05-19 21:00:33 +00:00
}
2024-05-19 21:00:33 +00:00
createWordpressPost.Content = html
2024-05-21 17:08:47 +00:00
post, createWordpressPostErr := createWordpressPost.Execute(migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword)
if createWordpressPostErr != nil {
errorMessage = errorMessage + createWordpressPostErr.Error()
createPostFailureResult(postId, errorMessage, migration.ResultsDatabase)
2024-05-19 21:00:33 +00:00
continue
}
//set up post result here to create
//truncate error message for db
if len(errorMessage) > 1450 {
errorMessage = errorMessage[:1450]
}
2024-05-19 21:00:33 +00:00
postResult := PostResult{
SlowtwitchId: postId,
WordpressId: post.Id,
OldUrl: oldLink,
OldUrlStatus: linkStatus,
NewUrl: post.Link,
IsSuccess: true,
ErrorMessage: errorMessage,
}
2024-05-17 18:49:55 +00:00
2024-05-21 17:08:47 +00:00
postResultId, createPostResultErr := CreatePostResult(postResult, migration.ResultsDatabase)
if createPostResultErr != nil {
fmt.Println("Could not record post result for Slowtwitch post:" + strconv.Itoa(postId) + createPostResultErr.Error())
2024-05-19 21:00:33 +00:00
}
for _, imageResult := range imageResults {
imageResult.PostId = postResultId
2024-05-21 17:08:47 +00:00
createImageResultErr := CreateImageResult(imageResult, migration.ResultsDatabase)
if createImageResultErr != nil {
2024-05-19 21:00:33 +00:00
fmt.Println("Error recording image result")
}
}
2024-05-20 01:35:53 +00:00
oldPath := strings.ReplaceAll(oldLink, "https://www.slowtwitch.com", "")
postRedirect := wordpress.CreateRedirect{
Title: "Article Redirect" + postBase.Title,
Url: oldPath,
2024-05-20 01:35:53 +00:00
MatchType: "page",
ActionType: "url",
ActionCode: 301,
GroupId: 1,
ActionData: wordpress.ActionData{
Url: "/" + strings.ReplaceAll(postResult.NewUrl, migration.WordpressBaseUrl, ""),
},
}
2024-05-21 17:08:47 +00:00
_, postRedirectErr := postRedirect.Execute(migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword)
if postRedirectErr != nil {
fmt.Println("Error creating redirect for", postId, ":"+postRedirectErr.Error())
2024-05-20 01:35:53 +00:00
}
fmt.Println("Successfully created post and result for", postId)
2024-05-21 21:15:43 +00:00
updateAcfImages(imageResults, post.Id, migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword)
postResults = append(postResults, postResult)
2024-05-17 18:49:55 +00:00
}
2024-05-21 21:15:43 +00:00
// Update related posts once work is done
for _, postResult := range postResults {
if postResult.IsSuccess {
var relatedWordpressIds []int
relatedSlowtwitchIds, slowtwitchIdsErr := slowtwitch.GetRelatedArticleIds(postResult.SlowtwitchId, migration.SlowtwitchDatabase)
if slowtwitchIdsErr != nil {
continue
}
for _, slowtwitchRelatedId := range relatedSlowtwitchIds {
wordpressRelatedId, wordpressIdErr := GetWordpressPostIdBySlowtwitchPostId(slowtwitchRelatedId, migration.ResultsDatabase)
if wordpressIdErr != nil {
continue
}
relatedSlowtwitchIds = append(relatedWordpressIds, wordpressRelatedId)
}
if len(relatedWordpressIds) > 0 {
updateWordpressRelatedPosts := wordpress.UpdateAcfRelatedPosts{
Acf: wordpress.AcfRelatedPosts{
PostIds: relatedWordpressIds,
},
}
updateRelatedPostErr := updateWordpressRelatedPosts.Execute(migration.WordpressBaseUrl, migration.WordpressUser, migration.WordpressPassword, postResult.WordpressId)
if updateRelatedPostErr != nil {
fmt.Println("Error updating wordpressRelatedPosts", updateRelatedPostErr.Error())
}
}
}
2024-05-21 21:15:43 +00:00
}
return postResults
2024-05-17 18:49:55 +00:00
}
func getPostIdsThatNeedMigration(slowtwitchPostIds, migratedPostIds []int) []int {
var output []int
for _, slowtwitchPostId := range slowtwitchPostIds {
hasId := slices.Contains(migratedPostIds, slowtwitchPostId)
if hasId == false {
output = append(output, slowtwitchPostId)
}
}
return output
}
func createPostFailureResult(slowtwitchId int, errorMessage string, migrationDb *sql.DB) {
fmt.Println("Error creating post: ", slowtwitchId, ":", errorMessage)
postResult := PostResult{
SlowtwitchId: slowtwitchId,
WordpressId: 0,
OldUrl: "",
OldUrlStatus: 0,
NewUrl: "",
IsSuccess: false,
ErrorMessage: errorMessage,
}
_, err := CreatePostResult(postResult, migrationDb)
if err != nil {
fmt.Println("Failed to create failure result: ", err)
}
}
func createImageFailureResult(url string, resultsDatabase *sql.DB) {
fmt.Println("Error creating image failure result: ", url)
imageResult := ImageResult{
OldUrl: url,
NewUrl: "",
WordpressId: 0,
IsSuccess: false,
}
err := CreateImageResult(imageResult, resultsDatabase)
if err != nil {
fmt.Println("Failed to create failure result: ", err)
}
}
2024-05-21 21:15:43 +00:00
func getSuccessfulWordpressImageIds(imageResults []ImageResult) []int {
var output []int
for _, imageResult := range imageResults {
output = append(output, imageResult.WordpressId)
}
return output
}
func updateAcfImages(imageResults []ImageResult, postId int, baseUrl, user, pass string) {
if len(imageResults) > 0 {
wordpressImageIds := getSuccessfulWordpressImageIds(imageResults)
updateAcfImages := wordpress.UpdateAcfImages{
Acf: wordpress.AcfImages{
PostImages: wordpressImageIds,
},
}
acfImagesErr := updateAcfImages.Execute(baseUrl, user, pass, postId)
if acfImagesErr != nil {
fmt.Println("Error updating acf images for post", postId, ":", acfImagesErr.Error())
}
}
}