implemented fetch album
This commit is contained in:
@@ -376,10 +376,236 @@ func (m *Musify) FetchSong(source data.Source) (data.Song, error) {
|
||||
return song, nil
|
||||
}
|
||||
|
||||
func parseSongCard(songCard *goquery.Selection) data.Song {
|
||||
song := data.Song{
|
||||
Artists: []data.Artist{},
|
||||
Sources: []data.Source{},
|
||||
}
|
||||
|
||||
// Get song name from data attribute
|
||||
songName, _ := songCard.Attr("data-name")
|
||||
song.Name = songName
|
||||
|
||||
/*
|
||||
// Get tracksort
|
||||
tracksortSelection := songCard.Find("div.playlist__position")
|
||||
if tracksortSelection.Length() > 0 {
|
||||
rawTracksort := strings.TrimSpace(tracksortSelection.Text())
|
||||
if parsedTracksort, err := strconv.Atoi(rawTracksort); err == nil {
|
||||
tracksort = parsedTracksort
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Playlist details
|
||||
playlistDetails := songCard.Find("div.playlist__details")
|
||||
if playlistDetails.Length() > 0 {
|
||||
// Track anchor
|
||||
anchorList := playlistDetails.Find("a")
|
||||
if anchorList.Length() > 1 {
|
||||
trackAnchor := anchorList.Last()
|
||||
if href, exists := trackAnchor.Attr("href"); exists {
|
||||
song.Sources = append(song.Sources, data.Source{Url: musifyHost + href})
|
||||
}
|
||||
song.Name = strings.TrimSpace(trackAnchor.Text())
|
||||
}
|
||||
|
||||
// Artist spans
|
||||
playlistDetails.Find("span[itemprop='byArtist']").Each(func(i int, artistSpan *goquery.Selection) {
|
||||
artist := data.Artist{
|
||||
Sources: []data.Source{},
|
||||
}
|
||||
|
||||
// Artist URL
|
||||
metaArtistSrc := artistSpan.Find("meta[itemprop='url']")
|
||||
if metaArtistSrc.Length() > 0 {
|
||||
if content, exists := metaArtistSrc.Attr("content"); exists && content != "" {
|
||||
artist.Sources = append(artist.Sources, data.Source{
|
||||
Url: musifyHost + content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Artist name
|
||||
metaArtistName := artistSpan.Find("meta[itemprop='name']")
|
||||
if metaArtistName.Length() > 0 {
|
||||
if content, exists := metaArtistName.Attr("content"); exists && content != "" {
|
||||
artist.Name = content
|
||||
}
|
||||
}
|
||||
|
||||
if artist.Name != "" || len(artist.Sources) > 0 {
|
||||
song.Artists = append(song.Artists, artist)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
// Playlist actions - download link
|
||||
playlistActions := songCard.Find("div.playlist__actions")
|
||||
if playlistActions.Length() > 0 {
|
||||
downloadAnchor := playlistActions.Find("a[itemprop='audio']")
|
||||
if downloadAnchor.Length() > 0 {
|
||||
if href, exists := downloadAnchor.Attr("href"); exists && currentURL != "" {
|
||||
// Add source with audio URL
|
||||
song.Sources = append(song.Sources, data.Source{
|
||||
Url: currentURL,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return song
|
||||
}
|
||||
|
||||
func parseAlbum(doc *goquery.Document) data.Album {
|
||||
album := data.Album{
|
||||
Artists: []data.Artist{},
|
||||
Sources: []data.Source{},
|
||||
Songs: []data.Song{},
|
||||
}
|
||||
|
||||
// Breadcrumb
|
||||
breadcrumb := doc.Find("ol.breadcrumb")
|
||||
breadcrumbElements := breadcrumb.Find("li.breadcrumb-item")
|
||||
if breadcrumbElements.Length() == 4 {
|
||||
// Album name from last breadcrumb
|
||||
albumCrumb := breadcrumbElements.Eq(3)
|
||||
album.Name = strings.TrimSpace(albumCrumb.Text())
|
||||
|
||||
// Artist from second last breadcrumb
|
||||
artistCrumb := breadcrumbElements.Eq(2)
|
||||
artistAnchor := artistCrumb.Find("a")
|
||||
if artistAnchor.Length() > 0 {
|
||||
if href, exists := artistAnchor.Attr("href"); exists {
|
||||
hrefParts := strings.Split(href, "/")
|
||||
if len(hrefParts) > 1 && hrefParts[len(hrefParts)-2] == "artist" {
|
||||
artist := data.Artist{
|
||||
Sources: []data.Source{},
|
||||
}
|
||||
|
||||
artist.Sources = append(artist.Sources, data.Source{
|
||||
Url: musifyHost + strings.TrimSpace(href),
|
||||
})
|
||||
|
||||
// Artist name from span
|
||||
if span := artistAnchor.Find("span"); span.Length() > 0 {
|
||||
artist.Name = strings.TrimSpace(span.Text())
|
||||
} else {
|
||||
artist.Name = strings.TrimSpace(artistAnchor.Text())
|
||||
}
|
||||
|
||||
album.Artists = append(album.Artists, artist)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// m.logger.Debug("there are not 4 breadcrumb items, which shouldn't be the case")
|
||||
}
|
||||
|
||||
// Meta tags
|
||||
metaURL := doc.Find("meta[itemprop='url']")
|
||||
if metaURL.Length() > 0 {
|
||||
if content, exists := metaURL.Attr("content"); exists {
|
||||
album.Sources = append(album.Sources, data.Source{
|
||||
Url: musifyHost + content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
metaName := doc.Find("meta[itemprop='name']")
|
||||
if metaName.Length() > 0 {
|
||||
if content, exists := metaName.Attr("content"); exists {
|
||||
album.Name = content
|
||||
}
|
||||
}
|
||||
|
||||
// Album info
|
||||
albumInfo := doc.Find("ul.album-info")
|
||||
if albumInfo.Length() > 0 {
|
||||
// Artists
|
||||
albumInfo.Find("a[itemprop='byArtist']").Each(func(i int, artistAnchor *goquery.Selection) {
|
||||
artist := data.Artist{
|
||||
Sources: []data.Source{},
|
||||
}
|
||||
|
||||
// Artist URL
|
||||
artistURLMeta := artistAnchor.Find("meta[itemprop='url']")
|
||||
if artistURLMeta.Length() > 0 {
|
||||
if content, exists := artistURLMeta.Attr("content"); exists {
|
||||
artist.Sources = append(artist.Sources, data.Source{
|
||||
Url: musifyHost + content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Artist name
|
||||
artistNameMeta := artistAnchor.Find("meta[itemprop='name']")
|
||||
if artistNameMeta.Length() > 0 {
|
||||
if content, exists := artistNameMeta.Attr("content"); exists {
|
||||
artist.Name = content
|
||||
}
|
||||
}
|
||||
|
||||
if artist.Name != "" {
|
||||
album.Artists = append(album.Artists, artist)
|
||||
}
|
||||
})
|
||||
|
||||
/*
|
||||
// Date published
|
||||
timeSelection := albumInfo.Find("time[itemprop='datePublished']")
|
||||
if timeSelection.Length() > 0 {
|
||||
if datetime, exists := timeSelection.Attr("datetime"); exists {
|
||||
// Note: You'll need to parse the datetime according to your needs
|
||||
// For now, we'll store it as a string or you can parse it to time.Time
|
||||
// album.Date = parsedDate
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Album artwork would be handled here based on your ArtworkCollection implementation
|
||||
|
||||
return album
|
||||
}
|
||||
|
||||
func (m Musify) FetchAlbum(source data.Source) (data.Album, error) {
|
||||
return data.Album{
|
||||
Name: extractName(source.Url),
|
||||
}, nil
|
||||
album := data.Album{
|
||||
Sources: []data.Source{source},
|
||||
Artists: []data.Artist{},
|
||||
Songs: []data.Song{},
|
||||
}
|
||||
|
||||
resp, err := m.session.Get(source.Url)
|
||||
if err != nil {
|
||||
return album, err
|
||||
}
|
||||
|
||||
doc, err := scraper.GetHtml(resp)
|
||||
if err != nil {
|
||||
return album, err
|
||||
}
|
||||
|
||||
// Parse album metadata
|
||||
parsedAlbum := parseAlbum(doc)
|
||||
album.Name = parsedAlbum.Name
|
||||
album.Artists = parsedAlbum.Artists
|
||||
album.Sources = append(album.Sources, parsedAlbum.Sources...)
|
||||
|
||||
// Parse songs from cards
|
||||
cardBody := doc.Find("div.card-body")
|
||||
if cardBody.Length() > 0 {
|
||||
cardBody.Find("div.playlist__item").Each(func(i int, songCard *goquery.Selection) {
|
||||
song := parseSongCard(songCard)
|
||||
album.Songs = append(album.Songs, song)
|
||||
})
|
||||
}
|
||||
|
||||
// Update tracksort would be handled here based on your implementation
|
||||
|
||||
return album, nil
|
||||
}
|
||||
|
||||
func (m Musify) FetchArtist(source data.Source) (data.Artist, error) {
|
||||
|
||||
Reference in New Issue
Block a user