Removed old project logo url fields
This commit is contained in:
parent
d32cd0a849
commit
8e7c20fffa
|
@ -1,23 +1,16 @@
|
||||||
package admintools
|
package admintools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.handmade.network/hmn/hmn/src/assets"
|
|
||||||
"git.handmade.network/hmn/hmn/src/auth"
|
"git.handmade.network/hmn/hmn/src/auth"
|
||||||
"git.handmade.network/hmn/hmn/src/db"
|
"git.handmade.network/hmn/hmn/src/db"
|
||||||
"git.handmade.network/hmn/hmn/src/email"
|
"git.handmade.network/hmn/hmn/src/email"
|
||||||
"git.handmade.network/hmn/hmn/src/hmndata"
|
|
||||||
"git.handmade.network/hmn/hmn/src/logging"
|
"git.handmade.network/hmn/hmn/src/logging"
|
||||||
"git.handmade.network/hmn/hmn/src/models"
|
"git.handmade.network/hmn/hmn/src/models"
|
||||||
"git.handmade.network/hmn/hmn/src/oops"
|
"git.handmade.network/hmn/hmn/src/oops"
|
||||||
|
@ -360,140 +353,5 @@ func init() {
|
||||||
moveThreadsToSubforumCommand.MarkFlagRequired("subforum_slug")
|
moveThreadsToSubforumCommand.MarkFlagRequired("subforum_slug")
|
||||||
adminCommand.AddCommand(moveThreadsToSubforumCommand)
|
adminCommand.AddCommand(moveThreadsToSubforumCommand)
|
||||||
|
|
||||||
uploadProjectLogos := &cobra.Command{
|
|
||||||
Use: "uploadprojectlogos",
|
|
||||||
Short: "Uploads project imagefiles to S3 and replaces them with assets",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
ctx := context.Background()
|
|
||||||
conn := db.NewConnPool(1, 1)
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
allProjects, err := db.Query(ctx, conn, models.Project{}, `SELECT $columns FROM handmade_project`)
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, "Failed to fetch projects from db"))
|
|
||||||
}
|
|
||||||
|
|
||||||
var fixupProjects []*models.Project
|
|
||||||
numImages := 0
|
|
||||||
for _, project := range allProjects {
|
|
||||||
p := project.(*models.Project)
|
|
||||||
if p.LogoLight != "" || p.LogoDark != "" {
|
|
||||||
fixupProjects = append(fixupProjects, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.LogoLight != "" {
|
|
||||||
numImages += 1
|
|
||||||
}
|
|
||||||
if p.LogoDark != "" {
|
|
||||||
numImages += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("%d images to upload\n", numImages)
|
|
||||||
|
|
||||||
uploadImage := func(ctx context.Context, conn db.ConnOrTx, filepath string, owner *models.User) *models.Asset {
|
|
||||||
filepath = "./public/media/" + filepath
|
|
||||||
contents, err := os.ReadFile(filepath)
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, fmt.Sprintf("Failed to read file: %s", filepath)))
|
|
||||||
}
|
|
||||||
width := 0
|
|
||||||
height := 0
|
|
||||||
mime := ""
|
|
||||||
fileExtensionOverrides := []string{".svg"}
|
|
||||||
fileExt := strings.ToLower(path.Ext(filepath))
|
|
||||||
tryDecode := true
|
|
||||||
for _, ext := range fileExtensionOverrides {
|
|
||||||
if fileExt == ext {
|
|
||||||
tryDecode = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tryDecode {
|
|
||||||
config, _, err := image.DecodeConfig(bytes.NewReader(contents))
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, fmt.Sprintf("Failed to decode file: %s", filepath)))
|
|
||||||
}
|
|
||||||
width = config.Width
|
|
||||||
height = config.Height
|
|
||||||
mime = http.DetectContentType(contents)
|
|
||||||
} else {
|
|
||||||
if fileExt == ".svg" {
|
|
||||||
mime = "image/svg+xml"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filename := path.Base(filepath)
|
|
||||||
|
|
||||||
asset, err := assets.Create(ctx, conn, assets.CreateInput{
|
|
||||||
Content: contents,
|
|
||||||
Filename: filename,
|
|
||||||
ContentType: mime,
|
|
||||||
UploaderID: &owner.ID,
|
|
||||||
Width: width,
|
|
||||||
Height: height,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, "Failed to create asset"))
|
|
||||||
}
|
|
||||||
|
|
||||||
return asset
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range fixupProjects {
|
|
||||||
owners, err := hmndata.FetchProjectOwners(ctx, conn, p.ID)
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, "Failed to fetch project owners"))
|
|
||||||
}
|
|
||||||
if len(owners) == 0 {
|
|
||||||
fmt.Printf("PROBLEM!! Project %d (%s) doesn't have owners!!\n", p.ID, p.Name)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if p.LogoLight != "" {
|
|
||||||
lightAsset := uploadImage(ctx, conn, p.LogoLight, owners[0])
|
|
||||||
_, err := conn.Exec(ctx,
|
|
||||||
`
|
|
||||||
UPDATE handmade_project
|
|
||||||
SET
|
|
||||||
logolight_asset_id = $2,
|
|
||||||
logolight = NULL
|
|
||||||
WHERE
|
|
||||||
id = $1
|
|
||||||
`,
|
|
||||||
p.ID,
|
|
||||||
lightAsset.ID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, "Failed to update project"))
|
|
||||||
}
|
|
||||||
numImages -= 1
|
|
||||||
fmt.Printf(".")
|
|
||||||
}
|
|
||||||
if p.LogoDark != "" {
|
|
||||||
darkAsset := uploadImage(ctx, conn, p.LogoDark, owners[0])
|
|
||||||
_, err := conn.Exec(ctx,
|
|
||||||
`
|
|
||||||
UPDATE handmade_project
|
|
||||||
SET
|
|
||||||
logodark_asset_id = $2,
|
|
||||||
logodark = NULL
|
|
||||||
WHERE
|
|
||||||
id = $1
|
|
||||||
`,
|
|
||||||
p.ID,
|
|
||||||
darkAsset.ID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(oops.New(err, "Failed to update project"))
|
|
||||||
}
|
|
||||||
numImages -= 1
|
|
||||||
fmt.Printf(".")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("\nDone! %d images not patched for some reason.\n\n", numImages)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
adminCommand.AddCommand(uploadProjectLogos)
|
|
||||||
|
|
||||||
addProjectCommands(adminCommand)
|
addProjectCommands(adminCommand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.handmade.network/hmn/hmn/src/migration/types"
|
||||||
|
"github.com/jackc/pgx/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registerMigration(RemoveProjectLogoUrls{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveProjectLogoUrls struct{}
|
||||||
|
|
||||||
|
func (m RemoveProjectLogoUrls) Version() types.MigrationVersion {
|
||||||
|
return types.MigrationVersion(time.Date(2022, 2, 13, 20, 1, 55, 0, time.UTC))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveProjectLogoUrls) Name() string {
|
||||||
|
return "RemoveProjectLogoUrls"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveProjectLogoUrls) Description() string {
|
||||||
|
return "Remove project logo url fields as we're now using assets"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveProjectLogoUrls) Up(ctx context.Context, tx pgx.Tx) error {
|
||||||
|
_, err := tx.Exec(ctx,
|
||||||
|
`
|
||||||
|
ALTER TABLE handmade_project
|
||||||
|
DROP COLUMN logolight,
|
||||||
|
DROP COLUMN logodark;
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveProjectLogoUrls) Down(ctx context.Context, tx pgx.Tx) error {
|
||||||
|
_, err := tx.Exec(ctx,
|
||||||
|
`
|
||||||
|
ALTER TABLE handmade_project
|
||||||
|
ADD COLUMN logolight character varying(100),
|
||||||
|
ADD COLUMN logodark character varying(100);
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -72,9 +72,6 @@ type Project struct {
|
||||||
Color1 string `db:"color_1"`
|
Color1 string `db:"color_1"`
|
||||||
Color2 string `db:"color_2"`
|
Color2 string `db:"color_2"`
|
||||||
|
|
||||||
LogoLight string `db:"logolight"`
|
|
||||||
LogoDark string `db:"logodark"`
|
|
||||||
|
|
||||||
Personal bool `db:"personal"`
|
Personal bool `db:"personal"`
|
||||||
Hidden bool `db:"hidden"`
|
Hidden bool `db:"hidden"`
|
||||||
Featured bool `db:"featured"`
|
Featured bool `db:"featured"`
|
||||||
|
|
|
@ -64,16 +64,13 @@ func ProjectLogoUrl(p *models.Project, lightAsset *models.Asset, darkAsset *mode
|
||||||
if theme == "dark" {
|
if theme == "dark" {
|
||||||
if darkAsset != nil {
|
if darkAsset != nil {
|
||||||
return hmnurl.BuildS3Asset(darkAsset.S3Key)
|
return hmnurl.BuildS3Asset(darkAsset.S3Key)
|
||||||
} else {
|
|
||||||
return hmnurl.BuildUserFile(p.LogoDark)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if lightAsset != nil {
|
if lightAsset != nil {
|
||||||
return hmnurl.BuildS3Asset(lightAsset.S3Key)
|
return hmnurl.BuildS3Asset(lightAsset.S3Key)
|
||||||
} else {
|
|
||||||
return hmnurl.BuildUserFile(p.LogoLight)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectToTemplate(
|
func ProjectToTemplate(
|
||||||
|
|
|
@ -58,7 +58,7 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
||||||
|
|
||||||
ReportIssueMailto: "team@handmade.network",
|
ReportIssueMailto: "team@handmade.network",
|
||||||
|
|
||||||
OpenGraphItems: buildDefaultOpenGraphItems(&project, title),
|
OpenGraphItems: buildDefaultOpenGraphItems(&project, c.CurrentProjectLogoUrl, title),
|
||||||
|
|
||||||
IsProjectPage: !project.IsHMN(),
|
IsProjectPage: !project.IsHMN(),
|
||||||
Header: templates.Header{
|
Header: templates.Header{
|
||||||
|
@ -114,14 +114,14 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
||||||
return baseData
|
return baseData
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildDefaultOpenGraphItems(project *models.Project, title string) []templates.OpenGraphItem {
|
func buildDefaultOpenGraphItems(project *models.Project, projectLogoUrl string, title string) []templates.OpenGraphItem {
|
||||||
if title == "" {
|
if title == "" {
|
||||||
title = "Handmade Network"
|
title = "Handmade Network"
|
||||||
}
|
}
|
||||||
|
|
||||||
image := hmnurl.BuildPublic("logo.png", false)
|
image := hmnurl.BuildPublic("logo.png", false)
|
||||||
if !project.IsHMN() {
|
if !project.IsHMN() {
|
||||||
image = hmnurl.BuildUserFile(project.LogoLight)
|
image = projectLogoUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
return []templates.OpenGraphItem{
|
return []templates.OpenGraphItem{
|
||||||
|
|
|
@ -161,6 +161,7 @@ type RequestContext struct {
|
||||||
|
|
||||||
Conn *pgxpool.Pool
|
Conn *pgxpool.Pool
|
||||||
CurrentProject *models.Project
|
CurrentProject *models.Project
|
||||||
|
CurrentProjectLogoUrl string
|
||||||
CurrentUser *models.User
|
CurrentUser *models.User
|
||||||
CurrentSession *models.Session
|
CurrentSession *models.Session
|
||||||
Theme string
|
Theme string
|
||||||
|
|
|
@ -476,6 +476,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) {
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.CurrentProject = &dbProject.Project
|
c.CurrentProject = &dbProject.Project
|
||||||
|
c.CurrentProjectLogoUrl = templates.ProjectLogoUrl(&dbProject.Project, dbProject.LogoLightAsset, dbProject.LogoDarkAsset, c.Theme)
|
||||||
owners = dbProject.Owners
|
owners = dbProject.Owners
|
||||||
} else {
|
} else {
|
||||||
if errors.Is(err, db.NotFound) {
|
if errors.Is(err, db.NotFound) {
|
||||||
|
@ -495,6 +496,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) {
|
||||||
panic(oops.New(err, "failed to fetch HMN project"))
|
panic(oops.New(err, "failed to fetch HMN project"))
|
||||||
}
|
}
|
||||||
c.CurrentProject = &dbProject.Project
|
c.CurrentProject = &dbProject.Project
|
||||||
|
c.CurrentProjectLogoUrl = templates.ProjectLogoUrl(&dbProject.Project, dbProject.LogoLightAsset, dbProject.LogoDarkAsset, c.Theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.CurrentProject == nil {
|
if c.CurrentProject == nil {
|
||||||
|
|
Loading…
Reference in New Issue