From b9498c66f70b495e6bdfab0e36b458a22d331081 Mon Sep 17 00:00:00 2001 From: James Ravenscroft Date: Sat, 5 Feb 2022 21:52:46 +0000 Subject: [PATCH] implement pulling data from IMDB and caching --- controllers/scrobble.go | 37 +++++++++++++++++- go.mod | 4 ++ go.sum | 8 ++++ scrobble/imdb.go | 76 ++++++++++++++++++++++++++++++++++++ scrobble/meta.go | 23 +++++++++++ scrobble/types.go | 31 ++++++++++++++- server/router.go | 1 - static/css/indiescrobble.css | 17 ++++++++ templates/head.tmpl | 1 + templates/scrobble.tmpl | 69 ++++++++++++++++++++++++++++++-- 10 files changed, 261 insertions(+), 6 deletions(-) create mode 100644 scrobble/imdb.go create mode 100644 scrobble/meta.go create mode 100644 static/css/indiescrobble.css diff --git a/controllers/scrobble.go b/controllers/scrobble.go index 4482243..bfb3c67 100644 --- a/controllers/scrobble.go +++ b/controllers/scrobble.go @@ -21,9 +21,44 @@ func Scrobble(c *gin.Context){ // TODO: add validation of type scrobbleType := c.Request.Form.Get("type") + searchEngine := scrobble.NewSearchProvider(scrobbleType) + + var searchResults []scrobble.ScrobbleMetaRecord = nil + var item scrobble.ScrobbleMetaRecord = nil + + query := c.Request.Form.Get("q") + itemID := c.Request.Form.Get("item") + + if itemID != "" { + + item, err = searchEngine.SearchProvider.GetItem(itemID) + + if err != nil{ + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ + "message": err, + }) + return + } + }else if query != "" { + var err error = nil + searchResults, err = searchEngine.SearchProvider.Search(query) + + if err != nil{ + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ + "message": err, + }) + return + } + } + c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ "user": c.GetString("user"), - "scrobbleType": scrobble.ScrobbleTypeNames[scrobbleType], + "scrobbleType": scrobbleType, + "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], + "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], + "searchEngine": searchEngine.SearchProvider.GetName(), + "searchResults": searchResults, + "item": item, }) } \ No newline at end of file diff --git a/go.mod b/go.mod index 27ff10b..02da4e1 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.17 require ( github.com/0xAX/notificator v0.0.0-20210731104411-c42e3d4a43ee // indirect + github.com/StalkR/imdb v1.0.7 // indirect github.com/codegangsta/envy v0.0.0-20141216192214-4b78388c8ce4 // indirect github.com/codegangsta/gin v0.0.0-20211113050330-71f90109db02 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect @@ -17,6 +18,8 @@ require ( github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/goccy/go-json v0.9.4 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/btree v1.0.0 // indirect + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hacdias/indieauth v1.7.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -34,6 +37,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml v1.9.4 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect diff --git a/go.sum b/go.sum index c10d714..3f661fe 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,9 @@ github.com/0xAX/notificator v0.0.0-20210731104411-c42e3d4a43ee h1:LgokYDTCpaZBHt github.com/0xAX/notificator v0.0.0-20210731104411-c42e3d4a43ee/go.mod h1:NtXa9WwQsukMHZpjNakTTz0LArxvGYdPA9CjIcUSZ6s= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/StalkR/httpcache v1.0.0/go.mod h1:yvbaYwH6w1USHPqgspMSwumbLwWE+B7jIZgfLYkTw1M= +github.com/StalkR/imdb v1.0.7 h1:T9ra3IObhWoNB2I2CNT6EFe8sTQH56adKJdEQi1q0Ig= +github.com/StalkR/imdb v1.0.7/go.mod h1:nxQmP4/nGtTVICl2+UmwhCnosVwVClmksdyptjE5Lj8= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -121,6 +124,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -152,6 +156,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hacdias/indieauth v1.7.1 h1:gIIVrUozSTbTEOpqSYs884y37UWeFnVwX3KVT3sm/94= github.com/hacdias/indieauth v1.7.1/go.mod h1:NHpFIYe4d5vl+hZY+16XsneVmD6usNcZdrSIpP5blqM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -207,6 +213,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/scrobble/imdb.go b/scrobble/imdb.go new file mode 100644 index 0000000..a4ea395 --- /dev/null +++ b/scrobble/imdb.go @@ -0,0 +1,76 @@ +package scrobble + +import ( + "fmt" + "net/http" + + "github.com/StalkR/imdb" + "github.com/gregjones/httpcache" + "github.com/gregjones/httpcache/diskcache" +) + +type IMDBMetaRecord struct{ + title imdb.Title +} + +func (r *IMDBMetaRecord) GetID() string{ + return r.title.ID +} + +func (r *IMDBMetaRecord) GetDisplayName() string{ + return fmt.Sprintf("%v (%v)", r.title.Name, r.title.Year) +} + + +func (r *IMDBMetaRecord) GetCanonicalURL() string{ + return r.title.URL +} + +func (r *IMDBMetaRecord) GetThumbnailURL() string{ + return r.title.Poster.ContentURL +} + + +type IMDBScrobbleMetadataProvider struct { + client *http.Client +} + +func NewIMDBProvider() *IMDBScrobbleMetadataProvider { + + cache := diskcache.New("cache") + client := &http.Client{Transport: httpcache.NewTransport(cache)} + return &IMDBScrobbleMetadataProvider{client:client} +} + + +func (i *IMDBScrobbleMetadataProvider) GetName() string { return "IMDB" } + + +func (i *IMDBScrobbleMetadataProvider) GetItem(id string) (ScrobbleMetaRecord, error) { + + title, err := imdb.NewTitle(i.client, id) + + if err != nil{ + return nil, err + } + + return &IMDBMetaRecord{title: *title}, nil + +} + +func (i *IMDBScrobbleMetadataProvider) Search(query string) ([]ScrobbleMetaRecord, error) { + + titles, err := imdb.SearchTitle(i.client, query) + + if err != nil{ + return nil, err + } + + records := make([]ScrobbleMetaRecord, len(titles)) + + for i, title := range titles { + records[i] = &IMDBMetaRecord{title: title} + } + + return records, nil +} \ No newline at end of file diff --git a/scrobble/meta.go b/scrobble/meta.go new file mode 100644 index 0000000..4073e92 --- /dev/null +++ b/scrobble/meta.go @@ -0,0 +1,23 @@ +package scrobble + + +type MetaSearchProvider struct{ + ScrobbleType string + SearchProvider ScrobbleMetaProvider +} + +func NewSearchProvider(scrobbleType string) *MetaSearchProvider{ + provider := &MetaSearchProvider{ScrobbleType: scrobbleType} + + if scrobbleType == SCROBBLE_TYPE_MOVIE { + provider.SearchProvider = NewIMDBProvider() + } + + return provider + +} + + +func (m *MetaSearchProvider) search(query string) { + +} \ No newline at end of file diff --git a/scrobble/types.go b/scrobble/types.go index ad9bf63..e2af13f 100644 --- a/scrobble/types.go +++ b/scrobble/types.go @@ -1,8 +1,37 @@ package scrobble +const( + SCROBBLE_TYPE_LISTEN = "listen" + SCROBBLE_TYPE_TV = "tv" + SCROBBLE_TYPE_MOVIE = "movie" + SCROBBLE_TYPE_READ = "read" +) + var ScrobbleTypeNames = map[string]string { "scrobble" : "🎧 Listen", "tv" : "πŸ“Ί TV Show", "movie": "🎬 Movie", "read": "πŸ“– Read", -}; \ No newline at end of file +}; + +var ScrobblePlaceholders = map[string]string { + "scrobble" : "Jump Van Halen", + "tv" : "Schitt's Creek", + "movie": "Ferris Bueller's Day Off", + "read": "Three Body Problem Cixin Liu", +}; + + +type ScrobbleMetaRecord interface{ + GetID() string + GetDisplayName() string + GetCanonicalURL() string + GetThumbnailURL() string +} + +type ScrobbleMetaProvider interface{ + + GetName() string + Search(query string) ([]ScrobbleMetaRecord, error) + GetItem(id string) (ScrobbleMetaRecord, error) +} \ No newline at end of file diff --git a/server/router.go b/server/router.go index 8ed45a9..05b02cc 100644 --- a/server/router.go +++ b/server/router.go @@ -40,7 +40,6 @@ func NewRouter() *gin.Engine { - // v1 := router.Group("v1") // { // userGroup := v1.Group("user") diff --git a/static/css/indiescrobble.css b/static/css/indiescrobble.css new file mode 100644 index 0000000..2544a22 --- /dev/null +++ b/static/css/indiescrobble.css @@ -0,0 +1,17 @@ +.thumbnail{ + max-width: 256px; +} + +.float-right{ + float: right; + display: inline; +} + +.float-right { + float: left; + display: inline; +} + +.clear-both { + clear: both; +} \ No newline at end of file diff --git a/templates/head.tmpl b/templates/head.tmpl index 090676e..c35cce1 100644 --- a/templates/head.tmpl +++ b/templates/head.tmpl @@ -1,6 +1,7 @@ {{ define "head.tmpl" }} + IndieScrobble {{end}} \ No newline at end of file diff --git a/templates/scrobble.tmpl b/templates/scrobble.tmpl index 0cb6fce..1f8c9a3 100644 --- a/templates/scrobble.tmpl +++ b/templates/scrobble.tmpl @@ -1,3 +1,4 @@ +{{ define "scrobble.tmpl" }} {{ template "head.tmpl" . }} @@ -5,17 +6,79 @@ {{ template "header.tmpl" . }}
+ {{ $scrobbleType := .scrobbleType }} + {{ if .user }} Logged in as {{.user}} {{end}} -

Add A Post > Add {{ .scrobbleType }}

+ + +
+ + {{if .searchResults}} + +

Add A Post > Add {{ .scrobbleTypeName }} > {{.searchEngine}} Results

+ + + + {{ else if .item}} + +

Add A Post > Add {{ .scrobbleTypeName }} > {{.item.GetDisplayName}}

+ +

{{.item.GetDisplayName}}

+ +
+ + {{if .item.GetThumbnailURL}} + + {{end}} + + +
+ +
+ +
+ +
+ +
+ + +
+ + +
- + {{ else }} + +

Add A Post Add {{ .scrobbleTypeName }}

+ +

Search {{.searchEngine}} for items to scrobble

+ + + + + + {{end}} + +

- \ No newline at end of file + +{{end}} \ No newline at end of file