refactor layouts and templates, initial commit of FAQs page, preview of json generation
This commit is contained in:
parent
781c003bad
commit
306af3dcc1
|
@ -7,6 +7,10 @@ import (
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const(
|
||||||
|
BROWSER_TIME_FORMAT = "2006-01-02T15:04"
|
||||||
|
)
|
||||||
|
|
||||||
var config *viper.Viper
|
var config *viper.Viper
|
||||||
|
|
||||||
// Init is an exported method that takes the environment starts the viper
|
// Init is an exported method that takes the environment starts the viper
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.jamesravey.me/ravenscroftj/indiescrobble/models"
|
"git.jamesravey.me/ravenscroftj/indiescrobble/models"
|
||||||
"git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +23,21 @@ func Index(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "index.tmpl", gin.H{
|
c.HTML(http.StatusOK, "index.tmpl", gin.H{
|
||||||
"title": "test",
|
"title": "test",
|
||||||
"user": user,
|
"user": user,
|
||||||
"scrobbleTypes": scrobble.ScrobbleTypeNames,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FAQ(c *gin.Context){
|
||||||
|
currentUser, exists := c.Get("user")
|
||||||
|
|
||||||
|
var user *models.BaseUser
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
user = currentUser.(*models.BaseUser)
|
||||||
|
}else{
|
||||||
|
user = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "faq.tmpl", gin.H{
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
/* Controllers concerning accessing user posts */
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.jamesravey.me/ravenscroftj/indiescrobble/config"
|
||||||
"git.jamesravey.me/ravenscroftj/indiescrobble/models"
|
"git.jamesravey.me/ravenscroftj/indiescrobble/models"
|
||||||
"git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble"
|
|
||||||
"git.jamesravey.me/ravenscroftj/indiescrobble/services/micropub"
|
"git.jamesravey.me/ravenscroftj/indiescrobble/services/micropub"
|
||||||
|
"git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
@ -36,7 +37,20 @@ func (s *ScrobbleController) DoScrobble(c *gin.Context){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.scrobbler.Scrobble(&c.Request.Form, currentUser)
|
post, err := s.scrobbler.Scrobble(&c.Request.Form, currentUser)
|
||||||
|
|
||||||
|
if err != nil{
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "scrobble/done.tmpl", gin.H{
|
||||||
|
"user": currentUser,
|
||||||
|
"scrobbleTypeName": scrobble.ScrobbleTypeNames[post.PostType],
|
||||||
|
"post": post,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,13 +83,13 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}else{
|
}else{
|
||||||
c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{
|
c.HTML(http.StatusOK, "scrobble/compose.tmpl", gin.H{
|
||||||
"user": currentUser,
|
"user": currentUser,
|
||||||
"scrobbleType": scrobbleType,
|
"scrobbleType": scrobbleType,
|
||||||
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
|
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
|
||||||
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
|
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
|
||||||
"item": item,
|
"item": item,
|
||||||
"now": time.Now().Format("2006-01-02T15:04"),
|
"now": time.Now().Format(config.BROWSER_TIME_FORMAT),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -91,7 +105,7 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{
|
c.HTML(http.StatusOK, "scrobble/search.tmpl", gin.H{
|
||||||
"user": currentUser,
|
"user": currentUser,
|
||||||
"scrobbleType": scrobbleType,
|
"scrobbleType": scrobbleType,
|
||||||
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
|
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
|
||||||
|
@ -100,18 +114,25 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){
|
||||||
"searchResults": searchResults,
|
"searchResults": searchResults,
|
||||||
"now": time.Now().Format("2006-01-02T15:04"),
|
"now": time.Now().Format("2006-01-02T15:04"),
|
||||||
})
|
})
|
||||||
}else{
|
}else if scrobbleType := c.Request.Form.Get("type"); scrobbleType != "" {
|
||||||
c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{
|
c.HTML(http.StatusOK, "scrobble/search.tmpl", gin.H{
|
||||||
"user": currentUser,
|
"user": currentUser,
|
||||||
"scrobbleType": scrobbleType,
|
"scrobbleType": scrobbleType,
|
||||||
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
|
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
|
||||||
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
|
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
|
||||||
"now": time.Now().Format("2006-01-02T15:04"),
|
"now": time.Now().Format("2006-01-02T15:04"),
|
||||||
})
|
})
|
||||||
|
}else{
|
||||||
|
c.HTML(http.StatusOK, "scrobble/begin.tmpl", gin.H{
|
||||||
|
"user": currentUser,
|
||||||
|
"scrobbleTypes": scrobble.ScrobbleTypeNames,
|
||||||
|
"now": time.Now().Format("2006-01-02T15:04"),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Preview the content of a scrobble to be submitted to \*/
|
||||||
func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
|
func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
|
||||||
|
|
||||||
err := c.Request.ParseForm()
|
err := c.Request.ParseForm()
|
||||||
|
@ -125,21 +146,17 @@ func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
scrobbleType := c.Request.Form.Get("type")
|
post, err := s.scrobbler.Preview(&c.Request.Form)
|
||||||
|
|
||||||
searchEngine := scrobble.NewSearchProvider(scrobbleType, s.db)
|
|
||||||
|
|
||||||
itemID := c.Request.Form.Get("item")
|
|
||||||
|
|
||||||
item, err := searchEngine.SearchProvider.GetItem(itemID)
|
|
||||||
|
|
||||||
if err != nil{
|
if err != nil{
|
||||||
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
"message": err,
|
"message": err,
|
||||||
})
|
})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrobbleType := c.Request.Form.Get("type")
|
||||||
|
|
||||||
discovery := micropub.MicropubDiscoveryService{}
|
discovery := micropub.MicropubDiscoveryService{}
|
||||||
|
|
||||||
config, err := discovery.Discover(currentUser.Me, currentUser.Token )
|
config, err := discovery.Discover(currentUser.Me, currentUser.Token )
|
||||||
|
@ -151,15 +168,23 @@ func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "preview.tmpl", gin.H{
|
postBody, err := s.scrobbler.BuildMicroPubPayload(post)
|
||||||
|
|
||||||
|
if err != nil{
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "scrobble/preview.tmpl", gin.H{
|
||||||
"user": currentUser,
|
"user": currentUser,
|
||||||
"scrobbleType": scrobbleType,
|
"scrobbleType": scrobbleType,
|
||||||
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
|
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
|
||||||
"item": item,
|
"post": post,
|
||||||
"when": c.Request.Form.Get("when"),
|
|
||||||
"rating": c.Request.Form.Get("rating"),
|
|
||||||
"content": c.Request.Form.Get("content"),
|
|
||||||
"config": config,
|
"config": config,
|
||||||
|
"summary": s.scrobbler.GenerateSummary(post),
|
||||||
|
"postBody": string(postBody),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,4 +16,5 @@ type Post struct {
|
||||||
MediaItem MediaItem
|
MediaItem MediaItem
|
||||||
ScrobbledAt sql.NullTime
|
ScrobbledAt sql.NullTime
|
||||||
Content sql.NullString
|
Content sql.NullString
|
||||||
|
Rating sql.NullString
|
||||||
}
|
}
|
|
@ -24,6 +24,7 @@ func NewRouter(db *gorm.DB) *gin.Engine {
|
||||||
router.Use(middlewares.AuthMiddleware(false, iam))
|
router.Use(middlewares.AuthMiddleware(false, iam))
|
||||||
|
|
||||||
router.GET("/", controllers.Index)
|
router.GET("/", controllers.Index)
|
||||||
|
router.GET("/faqs", controllers.FAQ)
|
||||||
|
|
||||||
router.Static("/static", config.GetString("server.static_path"))
|
router.Static("/static", config.GetString("server.static_path"))
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,6 @@ func Init() {
|
||||||
db.AutoMigrate(&models.User{}, &models.Post{}, &models.MediaItem{})
|
db.AutoMigrate(&models.User{}, &models.Post{}, &models.MediaItem{})
|
||||||
|
|
||||||
r := NewRouter(db)
|
r := NewRouter(db)
|
||||||
r.LoadHTMLGlob("templates/*.tmpl")
|
r.LoadHTMLGlob("templates/**/*.tmpl")
|
||||||
r.Run(fmt.Sprintf("%v:%v", config.GetString("server.host"), config.GetString("server.port")))
|
r.Run(fmt.Sprintf("%v:%v", config.GetString("server.host"), config.GetString("server.port")))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ func (s *Scrobbler) GetSearchEngineNameForType(scrobbleType string) string {
|
||||||
return NewSearchProvider(scrobbleType, s.db).SearchProvider.GetName()
|
return NewSearchProvider(scrobbleType, s.db).SearchProvider.GetName()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) {
|
func (s *Scrobbler) BuildMicroPubPayload(post *models.Post) ([]byte, error) {
|
||||||
postObj := make(map[string]interface{})
|
postObj := make(map[string]interface{})
|
||||||
postObj["type"] = []string{"h-entry"}
|
postObj["type"] = []string{"h-entry"}
|
||||||
postObj["visibility"] = []string{"public"}
|
postObj["visibility"] = []string{"public"}
|
||||||
|
@ -82,7 +83,7 @@ func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) {
|
||||||
properties["rating"] = []string{post.Rating.String}
|
properties["rating"] = []string{post.Rating.String}
|
||||||
}
|
}
|
||||||
|
|
||||||
properties["summary"] = fmt.Sprintf("%v %v and gave it %v/5", ScrobbleTypeVerbs[post.PostType], post.MediaItem.DisplayName.String, post.Rating.String)
|
properties["summary"] = []string{s.GenerateSummary(post)}
|
||||||
|
|
||||||
|
|
||||||
citationProps := make(map[string]interface{})
|
citationProps := make(map[string]interface{})
|
||||||
|
@ -105,7 +106,46 @@ func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) {
|
||||||
postObj["properties"] = properties
|
postObj["properties"] = properties
|
||||||
|
|
||||||
|
|
||||||
return json.Marshal(postObj)
|
return json.MarshalIndent(postObj, ""," ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Scrobbler) GenerateSummary(post *models.Post) string{
|
||||||
|
return fmt.Sprintf("%v %v %v and gave it %v/5",
|
||||||
|
ScrobbleTypeEmojis[post.PostType],
|
||||||
|
ScrobbleTypeVerbs[post.PostType],
|
||||||
|
post.MediaItem.DisplayName.String,
|
||||||
|
post.Rating.String)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Scrobbler) Preview(form *url.Values) (*models.Post, error) {
|
||||||
|
|
||||||
|
if err := s.ValidateType(form); err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
item := models.MediaItem{}
|
||||||
|
result := s.db.Where(&models.MediaItem{MediaID: form.Get("item")}).First(&item)
|
||||||
|
|
||||||
|
if result.Error != nil{
|
||||||
|
return nil, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
post := models.Post{
|
||||||
|
MediaItem: item,
|
||||||
|
PostType: form.Get("type"),
|
||||||
|
Content: sql.NullString{String: form.Get("content"), Valid: true},
|
||||||
|
Rating: sql.NullString{String: form.Get("rating"), Valid: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
time, err := time.Parse(config.BROWSER_TIME_FORMAT, form.Get("when"))
|
||||||
|
|
||||||
|
if err == nil{
|
||||||
|
post.ScrobbledAt = sql.NullTime{Time: time, Valid: true}
|
||||||
|
}else{
|
||||||
|
log.Printf("Failed to parse time %v because %v",form.Get("when"), err )
|
||||||
|
}
|
||||||
|
|
||||||
|
return &post, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*models.Post, error) {
|
func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*models.Post, error) {
|
||||||
|
@ -118,6 +158,7 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m
|
||||||
result := s.db.Where(&models.MediaItem{MediaID: form.Get("item")}).First(&item)
|
result := s.db.Where(&models.MediaItem{MediaID: form.Get("item")}).First(&item)
|
||||||
|
|
||||||
if result.Error != nil{
|
if result.Error != nil{
|
||||||
|
log.Printf("Error finding media item with ID %v in db: %v\n", form.Get("item"), result.Error)
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,28 +179,29 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m
|
||||||
if err == nil{
|
if err == nil{
|
||||||
post.ScrobbledAt = sql.NullTime{Time: time, Valid: true}
|
post.ScrobbledAt = sql.NullTime{Time: time, Valid: true}
|
||||||
}else{
|
}else{
|
||||||
fmt.Errorf("Failed to parse time %v because %v",form.Get("when"), err )
|
log.Printf("Failed to parse time %v because %v",form.Get("when"), err )
|
||||||
}
|
}
|
||||||
|
|
||||||
postBody, err := s.buildMicroPubPayload(&post)
|
postBody, err := s.BuildMicroPubPayload(&post)
|
||||||
|
|
||||||
|
|
||||||
fmt.Printf("Post body: %v\n", string(postBody))
|
|
||||||
|
|
||||||
if err != nil{
|
if err != nil{
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("Send post payload to %v\n", currentUser.Me)
|
||||||
|
|
||||||
resp, err := discovery.SubmitMicropub(currentUser, postBody)
|
resp, err := discovery.SubmitMicropub(currentUser, postBody)
|
||||||
|
|
||||||
if err != nil{
|
if err != nil{
|
||||||
|
log.Printf("Error creating user post: %v\n", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
loc, err := resp.Location()
|
loc, err := resp.Location()
|
||||||
|
|
||||||
if err != nil{
|
if err != nil{
|
||||||
|
log.Printf("Error getting Location header from user micropub endpoint: %v\n", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +209,7 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m
|
||||||
result = s.db.Create(&post)
|
result = s.db.Create(&post)
|
||||||
|
|
||||||
if result.Error != nil{
|
if result.Error != nil{
|
||||||
|
log.Printf("Error creating post in database: %v\n", result.Error)
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,13 @@ const(
|
||||||
SCROBBLE_TYPE_READ = "read"
|
SCROBBLE_TYPE_READ = "read"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ScrobbleTypeEmojis = map[string]string {
|
||||||
|
"scrobble" : "🎧",
|
||||||
|
"tv" : "📺",
|
||||||
|
"movie": "🎬",
|
||||||
|
"read": "📖",
|
||||||
|
};
|
||||||
|
|
||||||
var ScrobbleTypeNames = map[string]string {
|
var ScrobbleTypeNames = map[string]string {
|
||||||
"scrobble" : "🎧 Listen",
|
"scrobble" : "🎧 Listen",
|
||||||
"tv" : "📺 TV Show",
|
"tv" : "📺 TV Show",
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
{{ template "head.tmpl" . }}
|
|
||||||
<body>
|
|
||||||
{{ template "header.tmpl" . }}
|
|
||||||
<main>
|
|
||||||
<h2>Error</h2>
|
|
||||||
{{ .message }}
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,7 +0,0 @@
|
||||||
{{ define "header.tmpl" }}
|
|
||||||
<header>
|
|
||||||
<h1>
|
|
||||||
IndieScrobble
|
|
||||||
</h1>
|
|
||||||
</header>
|
|
||||||
{{end}}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{{ define "error.tmpl" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "partial/head.tmpl" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "partial/header.tmpl" . }}
|
||||||
|
<main>
|
||||||
|
<h2>Error</h2>
|
||||||
|
{{ .message }}
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{{ define "faq.tmpl" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "partial/head.tmpl" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "partial/header.tmpl" . }}
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<p>Welcome to indiescrobble! IndieScrobble is a <a href="https://micropub.spec.indieweb.org/">MicroPub</a> compliant tool
|
||||||
|
for posting about your watches, reads and scrobbles directly back to your site.</p>
|
||||||
|
|
||||||
|
<h3>Is it copyright infringement to display movie/tv posters, book covers, album covers on my website?</h3>
|
||||||
|
<p>I am not a lawyer however, it is my understanding that review is an example of "fair usage" of related promotional material
|
||||||
|
as per <a href="https://splc.org/2019/03/ask-splc-can-we-use-an-image-found-online-to-illustrate-a-movie-review/">this legal thread</a></p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
{{ template "partial/footer.tmpl" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{ define "index.tmpl" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "partial/head.tmpl" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "partial/header.tmpl" . }}
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<p>Welcome to indiescrobble! IndieScrobble is a <a href="https://micropub.spec.indieweb.org/">MicroPub</a> compliant tool
|
||||||
|
for posting about your watches, reads and scrobbles directly back to your site.</p>
|
||||||
|
{{ if .user }}
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="/scrobble/">Add a scrobble</a></li>
|
||||||
|
<li><a href="/posts">View your posts</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
|
||||||
|
<form action="/indieauth" method="POST">
|
||||||
|
<p>
|
||||||
|
<label>Your domain: </label>
|
||||||
|
<input type="text" name="domain"/>
|
||||||
|
<button type="submit">Log in</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
|
</main>
|
||||||
|
{{ template "partial/footer.tmpl" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
|
@ -1,4 +1,4 @@
|
||||||
{{ define "footer.tmpl" }}
|
{{ define "partial/footer.tmpl" }}
|
||||||
<footer>
|
<footer>
|
||||||
IndieScrobble is a FLOSS service provided by <a href="https://brainsteam.co.uk">James Ravenscroft</a>. It is licensed under AGPL-3.0.
|
IndieScrobble is a FLOSS service provided by <a href="https://brainsteam.co.uk">James Ravenscroft</a>. It is licensed under AGPL-3.0.
|
||||||
</footer>
|
</footer>
|
|
@ -1,4 +1,4 @@
|
||||||
{{ define "head.tmpl" }}
|
{{ define "partial/head.tmpl" }}
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="/static/css/simple-v1.css" />
|
<link rel="stylesheet" href="/static/css/simple-v1.css" />
|
||||||
<link rel="stylesheet" href="/static/css/indiescrobble.css" />
|
<link rel="stylesheet" href="/static/css/indiescrobble.css" />
|
|
@ -0,0 +1,23 @@
|
||||||
|
{{ define "partial/header.tmpl" }}
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<a href="/">Home</a>
|
||||||
|
<a href="/faqs">About/FAQs</a>
|
||||||
|
{{ if .user }}
|
||||||
|
<a href="/scrobble/">Add a Scrobble</a>
|
||||||
|
<a href="">My Posts</a>
|
||||||
|
<a href="">My Settings</a>
|
||||||
|
{{else}}
|
||||||
|
<a href="/">Sign in via IndieAuth</a>
|
||||||
|
{{end}}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
IndieScrobble
|
||||||
|
</h1>
|
||||||
|
{{ if .user.Me }}
|
||||||
|
Logged in as {{.user.Me}} <a href="/logout"><button>Log Out</button></a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
</header>
|
||||||
|
{{end}}
|
|
@ -1,65 +0,0 @@
|
||||||
{{ define "preview.tmpl" }}
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
{{ template "head.tmpl" . }}
|
|
||||||
<body>
|
|
||||||
{{ template "header.tmpl" . }}
|
|
||||||
<main>
|
|
||||||
|
|
||||||
{{ $scrobbleType := .scrobbleType }}
|
|
||||||
|
|
||||||
{{ if .user }}
|
|
||||||
Logged in as {{.user.Me}} <a href="/logout"><button>Log Out</button></a>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
|
|
||||||
<form method="POST" action="/scrobble/do">
|
|
||||||
|
|
||||||
<p><a href="/">Add A Post</a> > <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> > {{.item.GetDisplayName}}</p>
|
|
||||||
|
|
||||||
<h3>Preview Post: {{.item.GetDisplayName}}</h3>
|
|
||||||
|
|
||||||
<div class="float-left">
|
|
||||||
|
|
||||||
{{if .item.GetThumbnailURL}}
|
|
||||||
<img class="thumbnail" src="{{.item.GetThumbnailURL}}"/>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<label>When: <b>{{.when}}</b></label> <input type="hidden" name="when" value="{{.when}}" /><br/>
|
|
||||||
|
|
||||||
<label>Rating: (out of 5)</label> <b>{{.rating}}</b> <input type="hidden" name="rating" value="{{.rating}}"/> <br/>
|
|
||||||
|
|
||||||
<label>Note/Content: </label> <br>
|
|
||||||
<pre>{{.content}}</pre>
|
|
||||||
<input type="hidden" name="content" value="{{.content}}"/>
|
|
||||||
|
|
||||||
{{if .config.SyndicateTargets}}
|
|
||||||
<h3>Syndication Options</h3>
|
|
||||||
{{ range $target := .config.SyndicateTargets}}
|
|
||||||
<label><input type="checkbox" name="mp-syndicate[]" value="{{$target.Uid}}" /> {{$target.Name}}</label><br />
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<button type="submit">Submit Post > ></button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="hidden" name="item" value="{{.item.GetID}}"/>
|
|
||||||
<input type="hidden" name="type" value="{{ .scrobbleType }}"/>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</main>
|
|
||||||
{{ template "footer.tmpl" . }}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
{{end}}
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
{{ define "scrobble/begin.tmpl" }}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
{{ template "head.tmpl" . }}
|
{{ template "partial/head.tmpl" . }}
|
||||||
<body>
|
<body>
|
||||||
{{ template "header.tmpl" . }}
|
{{ template "partial/header.tmpl" . }}
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
{{ if .user }}
|
{{ if .user }}
|
||||||
|
@ -34,4 +35,5 @@
|
||||||
</main>
|
</main>
|
||||||
{{ template "footer.tmpl" . }}
|
{{ template "footer.tmpl" . }}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
{{end}}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{{ define "scrobble/compose.tmpl" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "partial/head.tmpl" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "partial/header.tmpl" . }}
|
||||||
|
<main>
|
||||||
|
|
||||||
|
{{ $scrobbleType := .scrobbleType }}
|
||||||
|
|
||||||
|
<form method="POST" action="/scrobble/preview">
|
||||||
|
|
||||||
|
<p><a href="/">Add A Post</a> > <a href="/scrobble?type=movie">Add {{ .scrobbleTypeName }}</a> > {{.item.GetDisplayName}}</p>
|
||||||
|
|
||||||
|
<h3>{{.item.GetDisplayName}}</h3>
|
||||||
|
|
||||||
|
<div class="float-left">
|
||||||
|
|
||||||
|
{{if .item.GetThumbnailURL}}
|
||||||
|
<img class="thumbnail" src="{{.item.GetThumbnailURL}}"/>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<label>When: </label> <input type="datetime-local" name='when' value="{{.now}}"/><br/>
|
||||||
|
|
||||||
|
<label>Rating: (out of 5)</label> <input type="number" name='rating'/><br/>
|
||||||
|
|
||||||
|
<label>Note/Content: </label> <br>
|
||||||
|
<textarea rows="6" name='content'></textarea>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<button type="submit">Preview > ></button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="item" value="{{.item.GetID}}"/>
|
||||||
|
<input type="hidden" name="type" value="{{.scrobbleType}}"/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
{{ template "partial/footer.tmpl" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
|
@ -1,24 +1,20 @@
|
||||||
{{ define "scrobbled.tmpl" }}
|
{{ define "scrobble/done.tmpl" }}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
{{ template "head.tmpl" . }}
|
{{ template "partial/head.tmpl" . }}
|
||||||
<body>
|
<body>
|
||||||
{{ template "header.tmpl" . }}
|
{{ template "partial/header.tmpl" . }}
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
{{ $scrobbleType := .scrobbleType }}
|
{{ $scrobbleType := .scrobbleType }}
|
||||||
|
|
||||||
{{ if .user }}
|
|
||||||
Logged in as {{.user.Me}} <a href="/logout"><button>Log Out</button></a>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
|
|
||||||
<p><a href="/">Add A Post</a> > <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> > {{.post.MediaItem.DisplayName.String}}</p>
|
<p><a href="/">Add A Post</a> > <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> > {{.post.MediaItem.DisplayName.String}}</p>
|
||||||
|
|
||||||
<h3>Post Complete: <a href="{{.post.URL}}">{{.post.URL}}</a></h3>
|
<h3>Post Complete: <a href="{{.post.URL}}">{{.post.URL}}</a></h3>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
{{ template "footer.tmpl" . }}
|
{{ template "partial/footer.tmpl" . }}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{{end}}
|
{{end}}
|
|
@ -0,0 +1,73 @@
|
||||||
|
{{ define "scrobble/preview.tmpl" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "partial/head.tmpl" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "partial/header.tmpl" . }}
|
||||||
|
<main>
|
||||||
|
|
||||||
|
{{ $scrobbleType := .scrobbleType }}
|
||||||
|
|
||||||
|
|
||||||
|
<form method="POST" action="/scrobble/do">
|
||||||
|
|
||||||
|
<p><a href="/">Add A Post</a> > <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> > {{.post.MediaItem.DisplayName.String}}</p>
|
||||||
|
|
||||||
|
<h3>Preview Post: {{.post.MediaItem.DisplayName.String}}</h3>
|
||||||
|
|
||||||
|
<h4>Summary</h4>
|
||||||
|
<p>{{.summary}}</p>
|
||||||
|
|
||||||
|
<h4>Thumbnail</h4>
|
||||||
|
<div class="float-left">
|
||||||
|
|
||||||
|
{{if .post.MediaItem.ThumbnailURL.Valid}}
|
||||||
|
<img class="thumbnail" src="{{.post.MediaItem.ThumbnailURL.String}}"/>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4>Details</h4>
|
||||||
|
<label>When: <b>{{.post.ScrobbledAt.Time}}</b></label> <input type="hidden" name="when" value="{{.when}}" /><br/>
|
||||||
|
|
||||||
|
<label>Rating: (out of 5)</label> <b>{{.post.Rating.String}}</b> <input type="hidden" name="rating" value="{{.rating}}"/> <br/>
|
||||||
|
|
||||||
|
<label>Note/Content: </label> <br>
|
||||||
|
<blockquote>{{.post.Content.String}}</blockquote>
|
||||||
|
<input type="hidden" name="content" value="{{.post.Content.String}}"/>
|
||||||
|
|
||||||
|
{{if .config.SyndicateTargets}}
|
||||||
|
<h4>Syndication Options</h4>
|
||||||
|
{{ range $target := .config.SyndicateTargets}}
|
||||||
|
<label><input type="checkbox" name="mp-syndicate[]" value="{{$target.Uid}}" /> {{$target.Name}}</label><br />
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Micropub Payload Details</summary>
|
||||||
|
<pre>{{.postBody}}</pre>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
<button type="submit">Submit Post > ></button>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="item" value="{{.post.MediaItem.MediaID}}"/>
|
||||||
|
<input type="hidden" name="type" value="{{ .scrobbleType }}"/>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
{{ template "partial/footer.tmpl" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
|
@ -0,0 +1,46 @@
|
||||||
|
{{ define "scrobble/search.tmpl" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "partial/head.tmpl" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "partial/header.tmpl" . }}
|
||||||
|
<main>
|
||||||
|
|
||||||
|
{{ $scrobbleType := .scrobbleType }}
|
||||||
|
|
||||||
|
|
||||||
|
{{if .searchResults}}
|
||||||
|
|
||||||
|
<p><a href="/">Add A Post</a> > <a href="/scrobble?type=movie">Add {{ .scrobbleTypeName }}</a> > {{.searchEngine}} Results</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{{ $scrobbleType := .scrobbleType }}
|
||||||
|
{{range $result := .searchResults}}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/scrobble?type={{$scrobbleType}}&item={{$result.GetID}}">{{$result.GetDisplayName}}</a>
|
||||||
|
<a href="{{$result.GetCanonicalURL}}" target="_blank">(🔍more info)</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ else }}
|
||||||
|
<form method="GET" action="/scrobble">
|
||||||
|
<h2><a href="/">Add A Post</a> Add {{ .scrobbleTypeName }}</h2>
|
||||||
|
|
||||||
|
<p>Search <b>{{.searchEngine}}</b> for items to scrobble<p>
|
||||||
|
|
||||||
|
<input type="text" name="q" placeholder="{{.scrobblePlaceholder}}">
|
||||||
|
|
||||||
|
<button type="submit">Next >></button>
|
||||||
|
|
||||||
|
<input type="hidden" name="type" value="{{.scrobbleType}}"/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
</main>
|
||||||
|
{{ template "partial/footer.tmpl" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
Loading…
Reference in New Issue