Add admin utilities for adding projects
This commit is contained in:
parent
7bf07c488e
commit
0184cd1625
|
@ -0,0 +1,231 @@
|
|||
package admintools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.handmade.network/hmn/hmn/src/db"
|
||||
"git.handmade.network/hmn/hmn/src/models"
|
||||
"git.handmade.network/hmn/hmn/src/parsing"
|
||||
"git.handmade.network/hmn/hmn/src/website"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func addProjectCommands(adminCommand *cobra.Command) {
|
||||
projectCommand := &cobra.Command{
|
||||
Use: "project",
|
||||
Short: "Admin commands for managing projects",
|
||||
}
|
||||
adminCommand.AddCommand(projectCommand)
|
||||
|
||||
addCreateProjectCommand(projectCommand)
|
||||
addProjectTagCommand(projectCommand)
|
||||
}
|
||||
|
||||
func addCreateProjectCommand(projectCommand *cobra.Command) {
|
||||
createProjectCommand := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a new project",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
name, _ := cmd.Flags().GetString("name")
|
||||
slug, _ := cmd.Flags().GetString("slug")
|
||||
blurb, _ := cmd.Flags().GetString("blurb")
|
||||
description, _ := cmd.Flags().GetString("description")
|
||||
personal, _ := cmd.Flags().GetBool("personal")
|
||||
userIDs, _ := cmd.Flags().GetIntSlice("userids")
|
||||
|
||||
descParsed := parsing.ParseMarkdown(description, parsing.ForumRealMarkdown)
|
||||
|
||||
ctx := context.Background()
|
||||
conn := db.NewConnPool(1, 1)
|
||||
defer conn.Close()
|
||||
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
p, err := website.FetchProject(ctx, tx, nil, models.HMNProjectID, website.ProjectsQuery{
|
||||
IncludeHidden: true,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
hmn := p.Project
|
||||
|
||||
newProjectID, err := db.QueryInt(ctx, tx,
|
||||
`
|
||||
INSERT INTO handmade_project (
|
||||
slug,
|
||||
name,
|
||||
blurb,
|
||||
description,
|
||||
color_1,
|
||||
color_2,
|
||||
featured,
|
||||
hidden,
|
||||
descparsed,
|
||||
blog_enabled,
|
||||
forum_enabled,
|
||||
all_last_updated,
|
||||
annotation_last_updated,
|
||||
blog_last_updated,
|
||||
forum_last_updated,
|
||||
lifecycle,
|
||||
date_approved,
|
||||
date_created,
|
||||
bg_flags,
|
||||
library_enabled,
|
||||
personal
|
||||
) VALUES (
|
||||
$1, -- slug
|
||||
$2, -- name
|
||||
$3, -- blurb
|
||||
$4, -- description
|
||||
$5, -- color_1
|
||||
$6, -- color_2
|
||||
FALSE, -- featured
|
||||
FALSE, -- hidden
|
||||
$7, -- descparsed
|
||||
FALSE, -- blog_enabled
|
||||
FALSE, -- forum_enabled
|
||||
NOW(), -- all_last_updated
|
||||
'epoch', -- annotation_last_updated
|
||||
'epoch', -- blog_last_updated
|
||||
'epoch', -- forum_last_updated
|
||||
$8, -- lifecycle
|
||||
NOW(), -- date_approved
|
||||
NOW(), -- date_created
|
||||
0, -- bg_flags
|
||||
FALSE, -- library_enabled
|
||||
$9 -- personal
|
||||
)
|
||||
RETURNING id
|
||||
`,
|
||||
slug,
|
||||
name,
|
||||
blurb,
|
||||
description,
|
||||
hmn.Color1,
|
||||
hmn.Color2,
|
||||
descParsed,
|
||||
models.ProjectLifecycleActive,
|
||||
personal,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, userID := range userIDs {
|
||||
_, err := tx.Exec(ctx,
|
||||
`
|
||||
INSERT INTO handmade_user_projects (user_id, project_id)
|
||||
VALUES ($1, $2)
|
||||
`,
|
||||
userID,
|
||||
newProjectID,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Created new project with id: %d\n", newProjectID)
|
||||
},
|
||||
}
|
||||
createProjectCommand.Flags().String("name", "", "")
|
||||
createProjectCommand.Flags().String("slug", "", "")
|
||||
createProjectCommand.Flags().String("blurb", "", "")
|
||||
createProjectCommand.Flags().String("description", "", "")
|
||||
createProjectCommand.Flags().Bool("personal", true, "")
|
||||
createProjectCommand.Flags().IntSlice("userids", nil, "")
|
||||
createProjectCommand.MarkFlagRequired("name")
|
||||
createProjectCommand.MarkFlagRequired("userids")
|
||||
projectCommand.AddCommand(createProjectCommand)
|
||||
}
|
||||
|
||||
func addProjectTagCommand(projectCommand *cobra.Command) {
|
||||
projectTagCommand := &cobra.Command{
|
||||
Use: "tag",
|
||||
Short: "Create or update a project's tag",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
projectID, _ := cmd.Flags().GetInt("projectid")
|
||||
tag, _ := cmd.Flags().GetString("tag")
|
||||
|
||||
ctx := context.Background()
|
||||
conn := db.NewConnPool(1, 1)
|
||||
defer conn.Close()
|
||||
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
p, err := website.FetchProject(ctx, tx, nil, projectID, website.ProjectsQuery{
|
||||
IncludeHidden: true,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if p.Project.TagID == nil {
|
||||
// Create a tag
|
||||
tagID, err := db.QueryInt(ctx, tx,
|
||||
`
|
||||
INSERT INTO tags (text) VALUES ($1)
|
||||
RETURNING id
|
||||
`,
|
||||
tag,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Attach it to the project
|
||||
_, err = tx.Exec(ctx,
|
||||
`
|
||||
UPDATE handmade_project
|
||||
SET tag = $1
|
||||
WHERE id = $2
|
||||
`,
|
||||
tagID, projectID,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// Update the text of an existing one
|
||||
_, err := tx.Exec(ctx,
|
||||
`
|
||||
UPDATE tags
|
||||
SET text = $1
|
||||
WHERE id = (SELECT tag FROM handmade_project WHERE id = $2)
|
||||
`,
|
||||
tag, projectID,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Project now has tag: %s\n", tag)
|
||||
},
|
||||
}
|
||||
projectTagCommand.Flags().Int("projectid", 0, "")
|
||||
projectTagCommand.Flags().String("tag", "", "")
|
||||
projectTagCommand.MarkFlagRequired("projectid")
|
||||
projectTagCommand.MarkFlagRequired("tag")
|
||||
projectCommand.AddCommand(projectTagCommand)
|
||||
}
|
|
@ -297,4 +297,6 @@ func init() {
|
|||
moveThreadsToSubforumCommand.MarkFlagRequired("project_slug")
|
||||
moveThreadsToSubforumCommand.MarkFlagRequired("subforum_slug")
|
||||
adminCommand.AddCommand(moveThreadsToSubforumCommand)
|
||||
|
||||
addProjectCommands(adminCommand)
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ func FetchProjects(
|
|||
qb.Add(`AND project.id = ANY ($?)`, q.ProjectIDs)
|
||||
}
|
||||
if len(q.Slugs) > 0 {
|
||||
qb.Add(`AND project.slug = ANY ($?)`, q.Slugs)
|
||||
qb.Add(`AND (project.slug != '' AND project.slug = ANY ($?))`, q.Slugs)
|
||||
}
|
||||
if len(q.Lifecycles) > 0 {
|
||||
qb.Add(`AND project.lifecycle = ANY($?)`, q.Lifecycles)
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
"github.com/teacat/noire"
|
||||
)
|
||||
|
||||
func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, perfCollector *perf.PerfCollector) http.Handler {
|
||||
func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool) http.Handler {
|
||||
router := &Router{}
|
||||
routes := RouteBuilder{
|
||||
Router: router,
|
||||
|
@ -36,7 +36,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, pe
|
|||
return func(c *RequestContext) (res ResponseData) {
|
||||
c.Conn = conn
|
||||
|
||||
logPerf := TrackRequestPerf(c, perfCollector)
|
||||
logPerf := TrackRequestPerf(c)
|
||||
defer logPerf()
|
||||
|
||||
defer LogContextErrorsFromResponse(c, &res)
|
||||
|
@ -52,7 +52,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, pe
|
|||
return func(c *RequestContext) (res ResponseData) {
|
||||
c.Conn = conn
|
||||
|
||||
logPerf := TrackRequestPerf(c, perfCollector)
|
||||
logPerf := TrackRequestPerf(c)
|
||||
defer logPerf()
|
||||
|
||||
defer LogContextErrorsFromResponse(c, &res)
|
||||
|
@ -74,7 +74,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, pe
|
|||
return func(c *RequestContext) (res ResponseData) {
|
||||
c.Conn = conn
|
||||
|
||||
logPerf := TrackRequestPerf(c, perfCollector)
|
||||
logPerf := TrackRequestPerf(c)
|
||||
defer logPerf()
|
||||
|
||||
defer LogContextErrorsFromResponse(c, &res)
|
||||
|
@ -534,7 +534,7 @@ func getCurrentUserAndSession(c *RequestContext, sessionId string) (*models.User
|
|||
|
||||
const PerfContextKey = "HMNPerf"
|
||||
|
||||
func TrackRequestPerf(c *RequestContext, perfCollector *perf.PerfCollector) (after func()) {
|
||||
func TrackRequestPerf(c *RequestContext) (after func()) {
|
||||
c.Perf = perf.MakeNewRequestPerf(c.Route, c.Req.Method, c.Req.URL.Path)
|
||||
c.ctx = context.WithValue(c.Context(), PerfContextKey, c.Perf)
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ var WebsiteCommand = &cobra.Command{
|
|||
|
||||
server := http.Server{
|
||||
Addr: config.Config.Addr,
|
||||
Handler: NewWebsiteRoutes(longRequestContext, conn, perfCollector),
|
||||
Handler: NewWebsiteRoutes(longRequestContext, conn),
|
||||
}
|
||||
|
||||
backgroundJobsDone := zipJobs(
|
||||
|
|
Loading…
Reference in New Issue