diff --git a/config/config.go b/config/config.go index 91505a3..71ddc89 100644 --- a/config/config.go +++ b/config/config.go @@ -7,6 +7,10 @@ import ( "github.com/spf13/viper" ) +const( + BROWSER_TIME_FORMAT = "2006-01-02T15:04" +) + var config *viper.Viper // Init is an exported method that takes the environment starts the viper diff --git a/controllers/index.go b/controllers/index.go index 90ca28d..766bf5c 100644 --- a/controllers/index.go +++ b/controllers/index.go @@ -4,7 +4,6 @@ import ( "net/http" "git.jamesravey.me/ravenscroftj/indiescrobble/models" - "git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble" "github.com/gin-gonic/gin" ) @@ -24,6 +23,21 @@ func Index(c *gin.Context) { c.HTML(http.StatusOK, "index.tmpl", gin.H{ "title": "test", "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, + }) +} \ No newline at end of file diff --git a/controllers/posts.go b/controllers/posts.go new file mode 100644 index 0000000..c6b022f --- /dev/null +++ b/controllers/posts.go @@ -0,0 +1,3 @@ +package controllers + +/* Controllers concerning accessing user posts */ \ No newline at end of file diff --git a/controllers/scrobble.go b/controllers/scrobble.go index 5fcac3b..c575380 100644 --- a/controllers/scrobble.go +++ b/controllers/scrobble.go @@ -4,9 +4,10 @@ import ( "net/http" "time" + "git.jamesravey.me/ravenscroftj/indiescrobble/config" "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/scrobble" "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -36,7 +37,20 @@ func (s *ScrobbleController) DoScrobble(c *gin.Context){ 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 }else{ - c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ + c.HTML(http.StatusOK, "scrobble/compose.tmpl", gin.H{ "user": currentUser, "scrobbleType": scrobbleType, "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], "item": item, - "now": time.Now().Format("2006-01-02T15:04"), + "now": time.Now().Format(config.BROWSER_TIME_FORMAT), }) return } @@ -91,7 +105,7 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){ return } - c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ + c.HTML(http.StatusOK, "scrobble/search.tmpl", gin.H{ "user": currentUser, "scrobbleType": scrobbleType, "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], @@ -100,18 +114,25 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){ "searchResults": searchResults, "now": time.Now().Format("2006-01-02T15:04"), }) - }else{ - c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ + }else if scrobbleType := c.Request.Form.Get("type"); scrobbleType != "" { + c.HTML(http.StatusOK, "scrobble/search.tmpl", gin.H{ "user": currentUser, "scrobbleType": scrobbleType, "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], "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){ 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{ c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ "message": err, }) - return } + scrobbleType := c.Request.Form.Get("type") + discovery := micropub.MicropubDiscoveryService{} config, err := discovery.Discover(currentUser.Me, currentUser.Token ) @@ -151,15 +168,23 @@ func (s *ScrobbleController) PreviewScrobble(c *gin.Context){ 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, "scrobbleType": scrobbleType, "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], - "item": item, - "when": c.Request.Form.Get("when"), - "rating": c.Request.Form.Get("rating"), - "content": c.Request.Form.Get("content"), + "post": post, "config": config, + "summary": s.scrobbler.GenerateSummary(post), + "postBody": string(postBody), }) } \ No newline at end of file diff --git a/models/post.go b/models/post.go index f68d016..dbd7592 100644 --- a/models/post.go +++ b/models/post.go @@ -16,4 +16,5 @@ type Post struct { MediaItem MediaItem ScrobbledAt sql.NullTime Content sql.NullString + Rating sql.NullString } \ No newline at end of file diff --git a/server/router.go b/server/router.go index 4b85a13..0f86c7b 100644 --- a/server/router.go +++ b/server/router.go @@ -24,6 +24,7 @@ func NewRouter(db *gorm.DB) *gin.Engine { router.Use(middlewares.AuthMiddleware(false, iam)) router.GET("/", controllers.Index) + router.GET("/faqs", controllers.FAQ) router.Static("/static", config.GetString("server.static_path")) diff --git a/server/server.go b/server/server.go index 27b2159..b58a4c6 100644 --- a/server/server.go +++ b/server/server.go @@ -32,6 +32,6 @@ func Init() { db.AutoMigrate(&models.User{}, &models.Post{}, &models.MediaItem{}) 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"))) } diff --git a/services/scrobble/scrobbler.go b/services/scrobble/scrobbler.go index a4d2e78..ed9cc7a 100644 --- a/services/scrobble/scrobbler.go +++ b/services/scrobble/scrobbler.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "fmt" + "log" "net/url" "time" @@ -67,7 +68,7 @@ func (s *Scrobbler) GetSearchEngineNameForType(scrobbleType string) string { 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["type"] = []string{"h-entry"} postObj["visibility"] = []string{"public"} @@ -82,7 +83,7 @@ func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) { 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{}) @@ -105,7 +106,46 @@ func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) { 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) { @@ -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) 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 } @@ -138,28 +179,29 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m if err == nil{ post.ScrobbledAt = sql.NullTime{Time: time, Valid: true} }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{ return nil, err } + log.Printf("Send post payload to %v\n", currentUser.Me) resp, err := discovery.SubmitMicropub(currentUser, postBody) if err != nil{ + log.Printf("Error creating user post: %v\n", err) return nil, err } loc, err := resp.Location() if err != nil{ + log.Printf("Error getting Location header from user micropub endpoint: %v\n", err) return nil, err } @@ -167,6 +209,7 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m result = s.db.Create(&post) if result.Error != nil{ + log.Printf("Error creating post in database: %v\n", result.Error) return nil, result.Error } diff --git a/services/scrobble/types.go b/services/scrobble/types.go index 3034a8a..7953ab9 100644 --- a/services/scrobble/types.go +++ b/services/scrobble/types.go @@ -7,6 +7,13 @@ const( SCROBBLE_TYPE_READ = "read" ) +var ScrobbleTypeEmojis = map[string]string { + "scrobble" : "π§", + "tv" : "πΊ", + "movie": "π¬", + "read": "π", +}; + var ScrobbleTypeNames = map[string]string { "scrobble" : "π§ Listen", "tv" : "πΊ TV Show", diff --git a/templates/error.tmpl b/templates/error.tmpl deleted file mode 100644 index c7e2bd2..0000000 --- a/templates/error.tmpl +++ /dev/null @@ -1,11 +0,0 @@ - - - {{ template "head.tmpl" . }} -
- {{ template "header.tmpl" . }} -Welcome to indiescrobble! IndieScrobble is a MicroPub compliant tool + for posting about your watches, reads and scrobbles directly back to your site.
+ +I am not a lawyer however, it is my understanding that review is an example of "fair usage" of related promotional material + as per this legal thread
+ +Welcome to indiescrobble! IndieScrobble is a MicroPub compliant tool + for posting about your watches, reads and scrobbles directly back to your site.
+ {{ if .user }} + + + + {{else}} + + + {{ end }} +Add A Post > Add {{ .scrobbleTypeName }} > {{.post.MediaItem.DisplayName.String}}
Add A Post > Add {{ .scrobbleTypeName }} > {{.searchEngine}} Results
+ +