Skip to content

Commit

Permalink
Merge pull request #24 from mBaratta96/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
mBaratta96 authored Aug 8, 2023
2 parents b859a59 + 9231580 commit f94bed3
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 125 deletions.
67 changes: 46 additions & 21 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import (
"github.com/wk8/go-ordered-map/v2"
)

type gotData struct {
credits bool
reviews bool
similar bool
}

func checkIndex(index int) int {
if index == -1 {
os.Exit(0)
Expand Down Expand Up @@ -43,51 +49,70 @@ func app(s scraper.Scraper) {
cli.PrintMap(s.StyleColor(), albumData.Metadata)
cli.PrintLink(data.Links[index])
_ = checkIndex(cli.PrintTable(albumData.Rows, albumData.Columns.Title, albumData.Columns.Width))
listIndex := checkIndex(cli.PrintList(s.ListChoices()))
if listIndex == 0 {
continue
}
gotCredits := false
gotReviews := false
var creditsData *orderedmap.OrderedMap[string, string]
var reviewData scraper.ScrapedData
var similData scraper.ScrapedData
var flags gotData = gotData{}
for true {
listIndex := cli.PrintList(s.ListChoices())
if listIndex == "Exit" {
os.Exit(0)
}
goingBack := false
switch listIndex {
case 1:
if !gotCredits {
case "Go back":
goingBack = true
case "Show credits":
if !flags.credits {
creditsData = s.Credits()
gotCredits = true
flags.credits = true
}
cli.PrintMap(s.StyleColor(), creditsData)

case 2:
if !gotReviews {
case "Show reviews":
if !flags.reviews {
reviewData = scraper.ScrapeData(s.ReviewsList)
gotReviews = true
flags.reviews = true
}
reviewIndex := checkIndex(
cli.PrintTable(reviewData.Rows, reviewData.Columns.Title, reviewData.Columns.Width),
)
cli.PrintReview(reviewData.Links[reviewIndex])
case 3:
if len(reviewData.Links) > 0 {
cli.PrintReview(reviewData.Links[reviewIndex])
}
case "Set rating":
var rating string
for true {
fmt.Println("Insert rating (0 to 10):")
if _, err := fmt.Scanln(&rating); err != nil {
panic(err)
}
if i, err := strconv.Atoi(rating); err == nil {
if i >= 0 && i <= 10 {
break
}
if i, err := strconv.Atoi(rating); err == nil && i >= 0 && i <= 10 {
break
}
fmt.Println("Wrong rating value")
}
id, _ := albumData.Metadata.Get("ID")
s.AdditionalFunctions()[3].(func(string, string))(rating, id)
s.AdditionalFunctions()["Set rating"].(func(string, string))(rating, id)
case "Get similar artists":
if !flags.similar {
id, _ := albumData.Metadata.Get("ID")
s.SetLink(fmt.Sprintf("https://www.metal-archives.com/band/ajax-recommendations/id/%s", id))
similData = scraper.ScrapeData(
s.AdditionalFunctions()["Get similar artists"].(func(*scraper.ScrapedData) ([]int, []string)),
)
flags.similar = true
}
similIndex := checkIndex(cli.PrintTable(similData.Rows, similData.Columns.Title, similData.Columns.Width))
if similIndex < len(similData.Links) { // go to new artist and start again
s.SetLink(similData.Links[similIndex])
data = scraper.ScrapeData(s.AlbumList)
goingBack = true
} else { // get back to current artist and do nothing
s.SetLink(data.Links[index])
}
}
listIndex = checkIndex(cli.PrintList(s.ListChoices()))
if listIndex == 0 {
if goingBack {
break
}
}
Expand Down
3 changes: 3 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func PrintMap(color string, metadata *orderedmap.OrderedMap[string, string]) {
style := lipgloss.NewStyle().Foreground(lipgloss.Color(color))
valueSpace := w - maxKeyLength
for pair := metadata.Oldest(); pair != nil; pair = pair.Next() {
if pair.Key == "ID" {
continue
}
key := pair.Key
value := pair.Value
if len(value) > valueSpace {
Expand Down
10 changes: 4 additions & 6 deletions cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,11 @@ func (m listModel) View() string {
return "\n" + m.list.View()
}

func PrintList(choices []string) int {
func PrintList(choices []string) string {
const defaultWidth = 20
items := []list.Item{}
choiceMap := make(map[string]int)
for i, choice := range choices {
for _, choice := range choices {
items = append(items, item(choice))
choiceMap[choice] = i
}

l := list.New(items, itemDelegate{}, defaultWidth, listHeight)
Expand All @@ -110,12 +108,12 @@ func PrintList(choices []string) int {
}
if m, ok := m.(listModel); ok {
if !m.quitting {
return choiceMap[m.choice]
return m.choice
}
} else {
fmt.Println("Error in table")
os.Exit(1)
}

return -1
return "Exit"
}
95 changes: 58 additions & 37 deletions scraper/metallum.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"image"
"path"
"strings"

_ "image/jpeg"
Expand All @@ -15,21 +16,23 @@ import (
"github.com/wk8/go-ordered-map/v2"
)

type SearchResponse struct {
type searchResponse struct {
AaData [][]string `json:"aaData"`
}

const METALLUMSTYLECOLOR string = "#b57614"

var (
mBandColumnTitles = [3]string{"Band Name", "Genre", "Country"}
mBandColumnWidths = [3]int{64, 64, 32}
mAlbumlistColumnTitles = [4]string{"Name", "Type", "Year", "Reviews"}
mAlbumlistColumnWidths = [4]int{64, 16, 4, 8}
mAlbumColumnTitles = [4]string{"N.", "Title", "Duration", "Lyric"}
mAlbumColumnWidths = [4]int{4, 64, 8, 16}
mReviewColumnTitles = [4]string{"Title", "Rating", "User", "Date"}
mReviewColumnWidths = [4]int{32, 7, 32, 32}
mBandColTitles = [3]string{"Band Name", "Genre", "Country"}
mBandColWidths = [3]int{64, 64, 32}
mAlbumlistColTitles = [4]string{"Name", "Type", "Year", "Reviews"}
mAlbumlistColWidths = [4]int{64, 16, 4, 8}
mAlbumColTitles = [4]string{"N.", "Title", "Duration", "Lyric"}
mAlbumColWidths = [4]int{4, 64, 8, 16}
mReviewColTitles = [4]string{"Title", "Rating", "User", "Date"}
mReviewColWidths = [4]int{32, 7, 32, 32}
mSimilarArtistColTitles = [4]string{"Name", "Country", "Genre", "Score"}
mSimilarArtistColWidths = [4]int{64, 32, 64, 4}
)

type Metallum struct {
Expand All @@ -54,34 +57,27 @@ func (m *Metallum) SearchBand(data *ScrapedData) ([]int, []string) {
data.Links = make([]string, 0)

c.OnResponse(func(r *colly.Response) {
var response SearchResponse
var response searchResponse
if err := json.Unmarshal(r.Body, &response); err != nil {
fmt.Println("Can not unmarshal JSON")
}

for _, el := range response.AaData {
var row [3]string
for i, node := range el {
switch i {
case 0:
doc, err := goquery.NewDocumentFromReader(strings.NewReader(node))
if err != nil {
fmt.Println("Error on response")
}
band := doc.Find("a").First()
row[0] = band.Text()
data.Links = append(data.Links, band.AttrOr("href", ""))
case 1:
row[1] = node
case 2:
row[2] = node
}
doc, err := goquery.NewDocumentFromReader(strings.NewReader(el[0]))
if err != nil {
fmt.Println("Error on response")
}
data.Rows = append(data.Rows, row[:])
bandLink := doc.Find("a").First()
band := bandLink.Text()
data.Links = append(data.Links, bandLink.AttrOr("href", ""))
genre := el[1]
country := el[2]
data.Rows = append(data.Rows, []string{band, genre, country})
}
})

c.Visit(fmt.Sprintf("https://www.metal-archives.com/search/ajax-band-search/?field=name&query=%s", m.Link))
return mBandColumnWidths[:], mAlbumColumnTitles[:]
return mBandColWidths[:], mAlbumColTitles[:]
}

func (m *Metallum) AlbumList(data *ScrapedData) ([]int, []string) {
Expand All @@ -108,7 +104,7 @@ func (m *Metallum) AlbumList(data *ScrapedData) ([]int, []string) {
})

c.Visit(m.Link)
return mAlbumlistColumnWidths[:], mAlbumlistColumnTitles[:]
return mAlbumlistColWidths[:], mAlbumlistColTitles[:]
}

func (m *Metallum) Album(data *ScrapedData) ([]int, []string) {
Expand All @@ -124,6 +120,10 @@ func (m *Metallum) Album(data *ScrapedData) ([]int, []string) {
data.Rows = append(data.Rows, row[:])
})

c.OnHTML("h2.band_name > a", func(h *colly.HTMLElement) {
data.Metadata.Set("ID", path.Base(h.Attr("href")))
})

c.OnHTML("a#cover.image", func(h *colly.HTMLElement) {
image_src := h.ChildAttr("img", "src")
h.Request.Visit(image_src)
Expand All @@ -144,7 +144,7 @@ func (m *Metallum) Album(data *ScrapedData) ([]int, []string) {
})

c.Visit(m.Link)
return mAlbumColumnWidths[:], mAlbumColumnTitles[:]
return mAlbumColWidths[:], mAlbumColTitles[:]
}

func (m *Metallum) StyleColor() string {
Expand All @@ -161,15 +161,13 @@ func (m *Metallum) ReviewsList(data *ScrapedData) ([]int, []string) {

c.OnHTML("div#album_tabs_reviews tr.even, div#album_tabs_reviews tr.odd", func(h *colly.HTMLElement) {
var row [4]string
var link string
i := 0
h.ForEach("td", func(_ int, h *colly.HTMLElement) {
if len(h.Attr("nowrap")) == 0 {
row[i] = h.Text
i += 1
} else {
link = h.ChildAttrs("a", "href")[0]
h.Request.Visit(link)
h.Request.Visit(h.ChildAttrs("a", "href")[0])
}
})
data.Rows = append(data.Rows, row[:])
Expand All @@ -183,7 +181,7 @@ func (m *Metallum) ReviewsList(data *ScrapedData) ([]int, []string) {
})

c.Visit(m.Link)
return mReviewColumnWidths[:], mReviewColumnTitles[:]
return mReviewColWidths[:], mReviewColTitles[:]
}

func (m *Metallum) Credits() *orderedmap.OrderedMap[string, string] {
Expand All @@ -200,10 +198,33 @@ func (m *Metallum) Credits() *orderedmap.OrderedMap[string, string] {
return credits
}

func (m *Metallum) similarArtists(data *ScrapedData) ([]int, []string) {
c := colly.NewCollector()
data.Links = make([]string, 0)

c.OnHTML("table#artist_list tbody tr[id*='recRow']", func(h *colly.HTMLElement) {
var row [4]string
h.ForEach("td", func(i int, h *colly.HTMLElement) {
row[i] = h.Text
if i == 0 {
data.Links = append(data.Links, h.ChildAttr("a", "href"))
}
})
data.Rows = append(data.Rows, row[:])
})

c.OnScraped(func(_ *colly.Response) { // This makes len(data.Rown) = len(data.Links) + 1 (see app.go)
data.Rows = append(data.Rows, []string{"Go back to choices", "", "", ""})
})

c.Visit(m.Link)
return mSimilarArtistColWidths[:], mSimilarArtistColTitles[:]
}

func (m *Metallum) ListChoices() []string {
return listMenuDefaultChoices
return append(listMenuDefaultChoices, "Get similar artists")
}

func (m *Metallum) AdditionalFunctions() map[int]interface{} {
return map[int]interface{}{}
func (m *Metallum) AdditionalFunctions() map[string]interface{} {
return map[string]interface{}{"Get similar artists": m.similarArtists}
}
3 changes: 1 addition & 2 deletions scraper/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -56,7 +55,7 @@ func readJsonFile[D JsonData](path string) (D, error) {
fmt.Println("No login file found in " + path + ". Skipped user authentication")
return configData, errors.New("No file")
}
configFile, err := ioutil.ReadFile(path)
configFile, err := os.ReadFile(path)
if err != nil {
panic("Error when opening file: ")
}
Expand Down
Loading

0 comments on commit f94bed3

Please sign in to comment.