Open education up to all
This commit is contained in:
parent
bd1edb2077
commit
f0597f3eb8
|
@ -40,7 +40,10 @@ func EducationIndex(c *RequestContext) ResponseData {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
article := func(slug string) templates.EduArticle {
|
article := func(slug string) templates.EduArticle {
|
||||||
if article, err := fetchEduArticle(c, c.Conn, slug, models.EduArticleTypeArticle, c.CurrentUser); err == nil {
|
if article, err := fetchEduArticle(c, c.Conn, slug, c.CurrentUser, EduArticleQuery{
|
||||||
|
Types: []models.EduArticleType{models.EduArticleTypeArticle},
|
||||||
|
IncludeUnpublished: true,
|
||||||
|
}); err == nil {
|
||||||
return templates.EducationArticleToTemplate(article)
|
return templates.EducationArticleToTemplate(article)
|
||||||
} else if errors.Is(err, db.NotFound) {
|
} else if errors.Is(err, db.NotFound) {
|
||||||
return templates.EduArticle{
|
return templates.EduArticle{
|
||||||
|
@ -119,7 +122,9 @@ func EducationArticle(c *RequestContext) ResponseData {
|
||||||
DeleteUrl string
|
DeleteUrl string
|
||||||
}
|
}
|
||||||
|
|
||||||
article, err := fetchEduArticle(c, c.Conn, c.PathParams["slug"], models.EduArticleTypeArticle, c.CurrentUser)
|
article, err := fetchEduArticle(c, c.Conn, c.PathParams["slug"], c.CurrentUser, EduArticleQuery{
|
||||||
|
Types: []models.EduArticleType{models.EduArticleTypeArticle},
|
||||||
|
})
|
||||||
if errors.Is(err, db.NotFound) {
|
if errors.Is(err, db.NotFound) {
|
||||||
return FourOhFour(c)
|
return FourOhFour(c)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -215,7 +220,7 @@ func EducationArticleEdit(c *RequestContext) ResponseData {
|
||||||
Article templates.EduArticle
|
Article templates.EduArticle
|
||||||
}
|
}
|
||||||
|
|
||||||
article, err := fetchEduArticle(c, c.Conn, c.PathParams["slug"], 0, c.CurrentUser)
|
article, err := fetchEduArticle(c, c.Conn, c.PathParams["slug"], c.CurrentUser, EduArticleQuery{})
|
||||||
if errors.Is(err, db.NotFound) {
|
if errors.Is(err, db.NotFound) {
|
||||||
return FourOhFour(c)
|
return FourOhFour(c)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -239,7 +244,7 @@ func EducationArticleEditSubmit(c *RequestContext) ResponseData {
|
||||||
return c.ErrorResponse(http.StatusBadRequest, err)
|
return c.ErrorResponse(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = fetchEduArticle(c, c.Conn, c.PathParams["slug"], 0, c.CurrentUser)
|
_, err = fetchEduArticle(c, c.Conn, c.PathParams["slug"], c.CurrentUser, EduArticleQuery{})
|
||||||
if errors.Is(err, db.NotFound) {
|
if errors.Is(err, db.NotFound) {
|
||||||
return FourOhFour(c)
|
return FourOhFour(c)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -255,7 +260,7 @@ func EducationArticleEditSubmit(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
func EducationArticleDelete(c *RequestContext) ResponseData {
|
func EducationArticleDelete(c *RequestContext) ResponseData {
|
||||||
article, err := fetchEduArticle(c, c.Conn, c.PathParams["slug"], 0, c.CurrentUser)
|
article, err := fetchEduArticle(c, c.Conn, c.PathParams["slug"], c.CurrentUser, EduArticleQuery{})
|
||||||
if errors.Is(err, db.NotFound) {
|
if errors.Is(err, db.NotFound) {
|
||||||
return FourOhFour(c)
|
return FourOhFour(c)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -291,7 +296,7 @@ func EducationArticleDeleteSubmit(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
func EducationRerender(c *RequestContext) ResponseData {
|
func EducationRerender(c *RequestContext) ResponseData {
|
||||||
everything := utils.Must1(fetchEduArticles(c, c.Conn, 0, c.CurrentUser))
|
everything := utils.Must1(fetchEduArticles(c, c.Conn, c.CurrentUser, EduArticleQuery{}))
|
||||||
for _, thing := range everything {
|
for _, thing := range everything {
|
||||||
newHTML := parsing.ParseMarkdown(thing.CurrentVersion.ContentRaw, parsing.EducationRealMarkdown)
|
newHTML := parsing.ParseMarkdown(thing.CurrentVersion.ContentRaw, parsing.EducationRealMarkdown)
|
||||||
utils.Must1(c.Conn.Exec(c,
|
utils.Must1(c.Conn.Exec(c,
|
||||||
|
@ -310,11 +315,16 @@ func EducationRerender(c *RequestContext) ResponseData {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EduArticleQuery struct {
|
||||||
|
Types []models.EduArticleType
|
||||||
|
IncludeUnpublished bool // If true, unpublished articles will be fetched even if they would not otherwise be visible
|
||||||
|
}
|
||||||
|
|
||||||
func fetchEduArticles(
|
func fetchEduArticles(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
dbConn db.ConnOrTx,
|
dbConn db.ConnOrTx,
|
||||||
t models.EduArticleType,
|
|
||||||
currentUser *models.User,
|
currentUser *models.User,
|
||||||
|
q EduArticleQuery,
|
||||||
) ([]models.EduArticle, error) {
|
) ([]models.EduArticle, error) {
|
||||||
type eduArticleResult struct {
|
type eduArticleResult struct {
|
||||||
Article models.EduArticle `db:"a"`
|
Article models.EduArticle `db:"a"`
|
||||||
|
@ -330,11 +340,11 @@ func fetchEduArticles(
|
||||||
WHERE
|
WHERE
|
||||||
TRUE
|
TRUE
|
||||||
`)
|
`)
|
||||||
if t != 0 {
|
if len(q.Types) > 0 {
|
||||||
qb.Add(`AND a.type = $?`, t)
|
qb.Add(`AND a.type = ANY($?)`, q.Types)
|
||||||
}
|
}
|
||||||
if currentUser == nil || !currentUser.CanSeeUnpublishedEducationContent() {
|
if (currentUser == nil || !currentUser.CanSeeUnpublishedEducationContent()) && !q.IncludeUnpublished {
|
||||||
qb.Add(`AND NOT a.published`)
|
qb.Add(`AND a.published`)
|
||||||
}
|
}
|
||||||
|
|
||||||
articles, err := db.Query[eduArticleResult](ctx, dbConn, qb.String(), qb.Args()...)
|
articles, err := db.Query[eduArticleResult](ctx, dbConn, qb.String(), qb.Args()...)
|
||||||
|
@ -356,8 +366,8 @@ func fetchEduArticle(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
dbConn db.ConnOrTx,
|
dbConn db.ConnOrTx,
|
||||||
slug string,
|
slug string,
|
||||||
t models.EduArticleType,
|
|
||||||
currentUser *models.User,
|
currentUser *models.User,
|
||||||
|
q EduArticleQuery,
|
||||||
) (*models.EduArticle, error) {
|
) (*models.EduArticle, error) {
|
||||||
type eduArticleResult struct {
|
type eduArticleResult struct {
|
||||||
Article models.EduArticle `db:"a"`
|
Article models.EduArticle `db:"a"`
|
||||||
|
@ -376,11 +386,11 @@ func fetchEduArticle(
|
||||||
`,
|
`,
|
||||||
slug,
|
slug,
|
||||||
)
|
)
|
||||||
if t != 0 {
|
if len(q.Types) > 0 {
|
||||||
qb.Add(`AND a.type = $?`, t)
|
qb.Add(`AND a.type = ANY($?)`, q.Types)
|
||||||
}
|
}
|
||||||
if currentUser == nil || !currentUser.CanSeeUnpublishedEducationContent() {
|
if (currentUser == nil || !currentUser.CanSeeUnpublishedEducationContent()) && !q.IncludeUnpublished {
|
||||||
qb.Add(`AND NOT a.published`)
|
qb.Add(`AND a.published`)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := db.QueryOne[eduArticleResult](ctx, dbConn, qb.String(), qb.Args()...)
|
res, err := db.QueryOne[eduArticleResult](ctx, dbConn, qb.String(), qb.Args()...)
|
||||||
|
|
|
@ -117,19 +117,16 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
|
||||||
hmnOnly.GET(hmnurl.RegexFishbowlIndex, FishbowlIndex)
|
hmnOnly.GET(hmnurl.RegexFishbowlIndex, FishbowlIndex)
|
||||||
hmnOnly.GET(hmnurl.RegexFishbowl, Fishbowl)
|
hmnOnly.GET(hmnurl.RegexFishbowl, Fishbowl)
|
||||||
|
|
||||||
educationPrerelease := hmnOnly.WithMiddleware(educationBetaTestersOnly)
|
hmnOnly.GET(hmnurl.RegexEducationIndex, EducationIndex)
|
||||||
{
|
hmnOnly.GET(hmnurl.RegexEducationGlossary, EducationGlossary)
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationIndex, EducationIndex)
|
hmnOnly.GET(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNew))
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationGlossary, EducationGlossary)
|
hmnOnly.POST(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNewSubmit))
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNew))
|
hmnOnly.GET(hmnurl.RegexEducationRerender, educationAuthorsOnly(EducationRerender))
|
||||||
educationPrerelease.POST(hmnurl.RegexEducationArticleNew, educationAuthorsOnly(EducationArticleNewSubmit))
|
hmnOnly.GET(hmnurl.RegexEducationArticle, EducationArticle) // Article stuff must be last so `/glossary` and others do not match as an article slug
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationRerender, educationAuthorsOnly(EducationRerender))
|
hmnOnly.GET(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEdit))
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationArticle, EducationArticle) // Article stuff must be last so `/glossary` and others do not match as an article slug
|
hmnOnly.POST(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEditSubmit))
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEdit))
|
hmnOnly.GET(hmnurl.RegexEducationArticleDelete, educationAuthorsOnly(EducationArticleDelete))
|
||||||
educationPrerelease.POST(hmnurl.RegexEducationArticleEdit, educationAuthorsOnly(EducationArticleEditSubmit))
|
hmnOnly.POST(hmnurl.RegexEducationArticleDelete, educationAuthorsOnly(csrfMiddleware(EducationArticleDeleteSubmit)))
|
||||||
educationPrerelease.GET(hmnurl.RegexEducationArticleDelete, educationAuthorsOnly(EducationArticleDelete))
|
|
||||||
educationPrerelease.POST(hmnurl.RegexEducationArticleDelete, educationAuthorsOnly(csrfMiddleware(EducationArticleDeleteSubmit)))
|
|
||||||
}
|
|
||||||
|
|
||||||
hmnOnly.POST(hmnurl.RegexAPICheckUsername, csrfMiddleware(APICheckUsername))
|
hmnOnly.POST(hmnurl.RegexAPICheckUsername, csrfMiddleware(APICheckUsername))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue