Compare commits
8 Commits
82b64fe642
...
2f6897ceb7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f6897ceb7 | ||
|
|
3c9cef8165 | ||
|
|
e5485ea1c3 | ||
|
|
a1579113dd | ||
|
|
2edc3a3a44 | ||
|
|
a60603d54d | ||
|
|
1d4b4b069f | ||
|
|
c5e8ee90c7 |
@@ -5,26 +5,57 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gitea.elara.ws/Hazel/music-kraken/internal/data"
|
||||
"gitea.elara.ws/Hazel/music-kraken/internal/plugin"
|
||||
)
|
||||
|
||||
func printResults(musicObjects []data.MusicObject) {
|
||||
if len(musicObjects) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range musicObjects {
|
||||
if a, ok := m.(data.Artist); ok {
|
||||
fmt.Println("artist: " + a.Name)
|
||||
|
||||
} else if a, ok := m.(data.Album); ok {
|
||||
fmt.Println("release: " + a.Name)
|
||||
fmt.Print("release: " + a.Name)
|
||||
|
||||
if len(a.Artists) > 0 {
|
||||
names := make([]string, len(a.Artists))
|
||||
for i, artist := range a.Artists {
|
||||
names[i] = artist.Name
|
||||
}
|
||||
fmt.Println(" by " + strings.Join(names, ", "))
|
||||
} else {
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
} else if a, ok := m.(data.Song); ok {
|
||||
fmt.Println("track: " + a.Name)
|
||||
fmt.Print("track: " + a.Name)
|
||||
if len(a.Artists) > 0 {
|
||||
names := make([]string, len(a.Artists))
|
||||
for i, artist := range a.Artists {
|
||||
names[i] = artist.Name
|
||||
}
|
||||
fmt.Println(" by " + strings.Join(names, ", "))
|
||||
} else {
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func Shell() {
|
||||
plugin.RegisterPlugin(&plugin.Musify{})
|
||||
|
||||
fmt.Println("== MusicKraken Shell ==")
|
||||
fmt.Println()
|
||||
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -49,8 +49,9 @@ func (m Musify) RegexSong() *regexp.Regexp {
|
||||
return regexp.MustCompile(`(?i)https?://musify\.club/track/[a-z\-0-9]+`)
|
||||
}
|
||||
|
||||
func parseArtistContact(contact *goquery.Selection) data.Artist {
|
||||
func parseArtistContact(contact *goquery.Selection) (data.Artist, error) {
|
||||
artist := data.Artist{}
|
||||
var err error
|
||||
|
||||
anchor := contact.Find("a")
|
||||
if anchor.Length() > 0 {
|
||||
@@ -66,15 +67,104 @@ func parseArtistContact(contact *goquery.Selection) data.Artist {
|
||||
if name, nameExists := anchor.Attr("title"); nameExists {
|
||||
artist.Name = name
|
||||
}
|
||||
} else {
|
||||
err = errors.New("no anchor found")
|
||||
}
|
||||
|
||||
return artist
|
||||
/*
|
||||
# artist image
|
||||
image_soup = contact.find("img")
|
||||
if image_soup is not None:
|
||||
alt = image_soup.get("alt")
|
||||
if alt is not None:
|
||||
name = alt
|
||||
|
||||
artist_thumbnail = image_soup.get("src")
|
||||
*/
|
||||
|
||||
return artist, err
|
||||
}
|
||||
|
||||
func parseAlbumContact(contact *goquery.Selection) data.Album {
|
||||
func parseAlbumContact(contact *goquery.Selection) (data.Album, error) {
|
||||
album := data.Album{}
|
||||
var err error
|
||||
|
||||
return album
|
||||
/*
|
||||
<div class="contacts__item">
|
||||
<a href="/release/ghost-bath-ghost-bath-2013-602489" title="Ghost Bath - 2013">
|
||||
|
||||
<div class="contacts__img release">
|
||||
<img alt="Ghost Bath" class="lozad" data-src="https://37s.musify.club/img/69/9060265/24178833.jpg"/>
|
||||
<noscript><img alt="Ghost Bath" src="https://37s.musify.club/img/69/9060265/24178833.jpg"/></noscript>
|
||||
</div>
|
||||
|
||||
<div class="contacts__info">
|
||||
<strong>Ghost Bath - 2013</strong>
|
||||
<small>Ghost Bath</small>
|
||||
<small>Треков: 4</small> <!--tracks-->
|
||||
<small><i class="zmdi zmdi-star zmdi-hc-fw"></i> 9,04</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
*/
|
||||
|
||||
anchor := contact.Find("a")
|
||||
if anchor.Length() > 0 {
|
||||
if url, urlExists := anchor.Attr("href"); urlExists {
|
||||
album.Sources = append(album.Sources, data.Source{
|
||||
Url: musifyHost + url,
|
||||
ObjectType: data.ArtistSource,
|
||||
})
|
||||
}
|
||||
|
||||
if titleDate, titleExists := anchor.Attr("title"); titleExists {
|
||||
delimiter := " - "
|
||||
|
||||
splitAttr := strings.Split(strings.TrimSpace(titleDate), delimiter)
|
||||
album.Name = strings.Join(splitAttr[:len(splitAttr)-1], delimiter)
|
||||
}
|
||||
} else {
|
||||
err = errors.New("no anchor found")
|
||||
}
|
||||
|
||||
contactInfo := contact.Find("div.contacts__info")
|
||||
if contactInfo.Length() > 0 {
|
||||
/*
|
||||
<strong>Ghost Bath - 2013</strong>
|
||||
<small>Ghost Bath</small>
|
||||
<small>Треков: 4</small> <!--tracks-->
|
||||
<small><i class="zmdi zmdi-star zmdi-hc-fw"></i> 9,04</small>
|
||||
*/
|
||||
|
||||
// titleSoup := contactInfo.Find("strong")
|
||||
|
||||
smallList := contactInfo.Find("small")
|
||||
if smallList.Length() == 3 {
|
||||
// artist
|
||||
rawArtistStr := smallList.First().Text()
|
||||
|
||||
for _, artistStr := range strings.Split(rawArtistStr, "&") {
|
||||
artistStr = strings.TrimRight(artistStr, "& ...\r\n")
|
||||
artistStr = strings.TrimSpace(artistStr)
|
||||
|
||||
if strings.HasSuffix(artistStr, "]") && strings.Contains(artistStr, "[") {
|
||||
parts := strings.Split(artistStr, "[")
|
||||
if len(parts) > 1 {
|
||||
artistStr = strings.TrimSpace(parts[0])
|
||||
}
|
||||
}
|
||||
|
||||
album.Artists = append(album.Artists, data.Artist{
|
||||
Name: artistStr,
|
||||
})
|
||||
}
|
||||
|
||||
// trackCountSoup := smallList[1]
|
||||
// ratingSoup := smallList[2]
|
||||
}
|
||||
}
|
||||
|
||||
return album, err
|
||||
}
|
||||
|
||||
func parseContactContainer(contactContainer *goquery.Selection) []data.MusicObject {
|
||||
@@ -88,9 +178,13 @@ func parseContactContainer(contactContainer *goquery.Selection) []data.MusicObje
|
||||
|
||||
if exists {
|
||||
if strings.Contains(url, "artist") {
|
||||
res = append(res, parseArtistContact(contact))
|
||||
if artist, err := parseArtistContact(contact); err == nil {
|
||||
res = append(res, artist)
|
||||
}
|
||||
} else if strings.Contains(url, "release") {
|
||||
res = append(res, parseAlbumContact(contact))
|
||||
if album, err := parseAlbumContact(contact); err == nil {
|
||||
res = append(res, album)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,9 +193,57 @@ func parseContactContainer(contactContainer *goquery.Selection) []data.MusicObje
|
||||
return res
|
||||
}
|
||||
|
||||
func parsePlaylistItem(playlistItem *goquery.Selection) (data.Song, error) {
|
||||
song := data.Song{}
|
||||
var err error
|
||||
|
||||
song.Name, _ = playlistItem.Attr("data-name")
|
||||
|
||||
playlistDetails := playlistItem.Find("div.playlist__heading")
|
||||
if playlistDetails.Length() > 0 {
|
||||
anchorList := playlistDetails.Find("a")
|
||||
|
||||
if anchorList.Length() >= 2 {
|
||||
// artists
|
||||
anchorList.Each(func(i int, artistAnchor *goquery.Selection) {
|
||||
if i < anchorList.Length()-1 { // all except the last one
|
||||
if url, exists := artistAnchor.Attr("href"); exists {
|
||||
song.Artists = append(song.Artists, data.Artist{
|
||||
Name: strings.TrimSpace(artistAnchor.Text()),
|
||||
Sources: []data.Source{
|
||||
{Url: musifyHost + url, ObjectType: data.ArtistSource},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// track
|
||||
trackAnchor := anchorList.Last()
|
||||
if href, exists := trackAnchor.Attr("href"); exists {
|
||||
song.Sources = append(song.Sources, data.Source{
|
||||
Url: musifyHost + href,
|
||||
ObjectType: data.SongSource,
|
||||
})
|
||||
}
|
||||
|
||||
} else {
|
||||
err = errors.New("there are not enough anchors (2) for artist and track")
|
||||
}
|
||||
}
|
||||
|
||||
return song, err
|
||||
}
|
||||
|
||||
func parsePlaylist(playlist *goquery.Selection) []data.MusicObject {
|
||||
res := []data.MusicObject{}
|
||||
|
||||
playlist.Find("div.playlist__item").Each(func(i int, playlistItem *goquery.Selection) {
|
||||
if song, err := parsePlaylistItem(playlistItem); err == nil {
|
||||
res = append(res, song)
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -115,9 +257,6 @@ func (m *Musify) Search(query common.Query) ([]data.MusicObject, error) {
|
||||
return musicObjects, err
|
||||
}
|
||||
|
||||
fmt.Println(resp.Header)
|
||||
fmt.Println(resp.StatusCode)
|
||||
|
||||
doc, err := scraper.GetHtml(resp)
|
||||
if err != nil {
|
||||
return musicObjects, err
|
||||
|
||||
24
internal/scraper/helper.go
Normal file
24
internal/scraper/helper.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package scraper
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
func GetText(resp *http.Response) (string, error) {
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
return string(body), err
|
||||
}
|
||||
|
||||
func GetHtml(resp *http.Response) (*goquery.Document, error) {
|
||||
text, err := GetText(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return goquery.NewDocumentFromReader(strings.NewReader(text))
|
||||
}
|
||||
Reference in New Issue
Block a user