Ver código fonte

initial push

Douglas Andreani 5 anos atrás
pai
commit
5b18e268ed
4 arquivos alterados com 213 adições e 0 exclusões
  1. 5 0
      go.mod
  2. 10 0
      go.sum
  3. 171 0
      mb.go
  4. 27 0
      mb_test.go

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module go-music
+
+go 1.14
+
+require github.com/stretchr/testify v1.5.1

+ 10 - 0
go.sum

@@ -0,0 +1,10 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

+ 171 - 0
mb.go

@@ -0,0 +1,171 @@
+package mb
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"sort"
+	"time"
+)
+
+const (
+	apiURI               = "https://musicbrainz.org/ws/2"
+	artistSearchEndpoint = "artist?query"
+)
+
+//MB holds the http client
+type MB struct {
+	Client http.Client
+}
+
+//Search holds the search returns
+type Search struct {
+	artist artistSearch
+}
+
+//NewMusicBrainz returns a new Search object
+func NewMusicBrainz() MB {
+
+	var mb MB
+	timeout := time.Duration(10 * time.Second)
+
+	mb.Client = http.Client{Timeout: timeout}
+	return mb
+}
+
+//SearchForArtist return a list of artists using `query` as parameter if none found returns error
+func (m MB) SearchForArtist(query string) (*Search, error) {
+	var ret Search
+	uri := fmt.Sprintf("%s/%s=%s", apiURI, artistSearchEndpoint, query)
+
+	req, err := http.NewRequest(
+		"GET",
+		uri,
+		nil)
+
+	req.Header.Set(
+		"User-Agent",
+		"Go Application Development: Create spotify playlist based on artist")
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("Accept", "application/json")
+
+	if err != nil {
+		fmt.Printf("error creating request\n%v", err)
+		return nil, err
+	}
+
+	resp, err := m.Client.Do(req)
+	if err != nil {
+		fmt.Printf("error opening request\n%v", err)
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if err != nil {
+		fmt.Printf("could not read body\n%v", err)
+		return nil, err
+	}
+
+	err = json.NewDecoder(resp.Body).Decode(&ret.artist)
+	if err != nil {
+		fmt.Printf("could not decode body\n%v", err)
+		return nil, err
+	}
+
+	if ret.artist.Count == 0 {
+		return nil, fmt.Errorf("cound not found artist: %s", query)
+	}
+
+	return &ret, nil
+}
+
+//GetArtistName get the artist with the highest score on the search
+func (s Search) GetArtistName() (string, error) {
+
+	if len(s.artist.Artists) == 0 {
+		return "", fmt.Errorf("could not find any artist")
+	}
+	return s.artist.Artists[0].Name, nil
+}
+
+//GetArtistTags returns the tags in order of relevance of the current artist
+func (s Search) GetArtistTags() []Tags {
+	var t []Tags
+	for _, elem := range s.artist.Artists[0].Tags {
+		if int(elem.Count) > 0 {
+			t = append(t, elem)
+		}
+	}
+	sort.Sort(ByInverseCount(t))
+	return t
+}
+
+type artistSearch struct {
+	Created time.Time `json:"created"`
+	Count   int       `json:"count"`
+	Offset  int       `json:"offset"`
+	Artists []artists `json:"artists"`
+}
+
+type area struct {
+	ID       string `json:"id"`
+	Type     string `json:"type"`
+	TypeID   string `json:"type-id"`
+	Name     string `json:"name"`
+	SortName string `json:"sort-name"`
+	LifeSpan struct {
+		Ended interface{} `json:"ended"`
+	} `json:"life-span"`
+}
+
+type alias struct {
+	SortName  string      `json:"sort-name"`
+	TypeID    string      `json:"type-id,omitempty"`
+	Name      string      `json:"name"`
+	Locale    interface{} `json:"locale"`
+	Type      string      `json:"type"`
+	Primary   interface{} `json:"primary"`
+	BeginDate interface{} `json:"begin-date"`
+	EndDate   interface{} `json:"end-date"`
+}
+
+type artists struct {
+	ID        string `json:"id"`
+	Type      string `json:"type,omitempty"`
+	TypeID    string `json:"type-id,omitempty"`
+	Score     int    `json:"score"`
+	Name      string `json:"name"`
+	SortName  string `json:"sort-name"`
+	Country   string `json:"country,omitempty"`
+	Area      area   `json:"area,omitempty"`
+	BeginArea struct {
+		ID       string `json:"id"`
+		Type     string `json:"type"`
+		TypeID   string `json:"type-id"`
+		Name     string `json:"name"`
+		SortName string `json:"sort-name"`
+		LifeSpan struct {
+			Ended interface{} `json:"ended"`
+		} `json:"life-span"`
+	} `json:"begin-area,omitempty"`
+	Isnis    []string `json:"isnis,omitempty"`
+	LifeSpan struct {
+		Begin string      `json:"begin"`
+		Ended interface{} `json:"ended"`
+	} `json:"life-span,omitempty"`
+	Aliases        []alias `json:"aliases,omitempty"`
+	Tags           []Tags  `json:"tags,omitempty"`
+	Disambiguation string  `json:"disambiguation,omitempty"`
+}
+
+//Tags represent Artist tags (eg. Rock, Punk, Late 2000s)
+type Tags struct {
+	Count int    `json:"count"`
+	Name  string `json:"name"`
+}
+
+//ByInverseCount return the tags in relevance order
+type ByInverseCount []Tags
+
+func (t ByInverseCount) Len() int           { return len(t) }
+func (t ByInverseCount) Less(i, j int) bool { return t[i].Count >= t[j].Count }
+func (t ByInverseCount) Swap(i, j int)      { t[i], t[j] = t[j], t[i] }

+ 27 - 0
mb_test.go

@@ -0,0 +1,27 @@
+package mb
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestShouldBeEqualToArtist(t *testing.T) {
+	m := NewMusicBrainz()
+	s, _ := m.SearchForArtist("Metallica")
+	name, _ := s.GetArtistName()
+
+	assert.Equal(t, name, "Metallica")
+}
+
+func TestIfArtistIsValidThenErrIsNil(t *testing.T) {
+	m := NewMusicBrainz()
+	_, err := m.SearchForArtist("Metallica")
+	assert.Nil(t, err, "err should be nil if found artist")
+}
+
+func TestErrShouldContainErrorIfArtistIsInvalid(t *testing.T) {
+	m := NewMusicBrainz()
+	_, err := m.SearchForArtist("asdfkjahsdflkjasdhfoia")
+	assert.NotNil(t, err, "err should not be nil if found artist")
+}