mirror of
https://github.com/nxshock/promodj.git
synced 2025-07-05 00:23:11 +05:00
Initial commit
This commit is contained in:
commit
01138252ac
16 changed files with 1195 additions and 0 deletions
120
parser.go
Normal file
120
parser.go
Normal file
|
@ -0,0 +1,120 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
// Genre represents track information
|
||||
type TrackInfo struct {
|
||||
Title string
|
||||
Url string
|
||||
}
|
||||
|
||||
// Genre represents genre information
|
||||
type Genre struct {
|
||||
Name string
|
||||
Code string
|
||||
}
|
||||
|
||||
// Genres holds cached list of available genres
|
||||
var Genres []Genre
|
||||
|
||||
func UpdateGenres() error {
|
||||
var err error
|
||||
|
||||
Genres, err = updateGenreList()
|
||||
if err != nil {
|
||||
return fmt.Errorf("get genres list failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateGenreList() ([]Genre, error) {
|
||||
url := "https://promodj.com/music"
|
||||
|
||||
doc, err := goquery.NewDocument(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var genres []Genre
|
||||
doc.Find("div.styles_tagcloud > a").Each(func(i int, s *goquery.Selection) {
|
||||
genres = append(genres, Genre{s.Text(), strings.TrimPrefix(s.AttrOr("href", ""), "/music/")})
|
||||
})
|
||||
|
||||
return genres, nil
|
||||
}
|
||||
|
||||
// tracksByGenre возвращает список треков по указанному жанру
|
||||
func tracksByGenre(genre string) ([]TrackInfo, error) {
|
||||
var result []TrackInfo
|
||||
|
||||
for i := 1; i <= 50; i++ {
|
||||
url := fmt.Sprintf("https://promodj.com/music/%s?download=1&page=%d", genre, i)
|
||||
|
||||
doc, err := goquery.NewDocument(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
doc.Find("div.title > a.invert").Each(
|
||||
func(n int, s *goquery.Selection) {
|
||||
href, exists := s.Attr("href")
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
fields := strings.Split(href, "/")
|
||||
if len(fields) != 7 {
|
||||
return
|
||||
}
|
||||
|
||||
fileUrl := fmt.Sprintf("https://promodj.com/download/%s/%s.mp3", fields[5], fields[6])
|
||||
|
||||
result = append(result, TrackInfo{s.Text(), fileUrl})
|
||||
})
|
||||
}
|
||||
|
||||
result = removeDuplicate(result)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// tracksToM3u возвращает байты M3U-плейлиста, сгенерированного по указанному
|
||||
// списку треков
|
||||
func tracksToM3u(host string, tracks []TrackInfo) []byte {
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
b.Write([]byte{0xEF, 0xBB, 0xBF})
|
||||
fmt.Fprint(b, "#EXTM3U\n")
|
||||
|
||||
for _, track := range tracks {
|
||||
fmt.Fprintf(b, "#EXTINF:-1,%s\n", track.Title)
|
||||
|
||||
u, _ := url.Parse(fmt.Sprintf("https://%s/stream", host))
|
||||
q := make(url.Values)
|
||||
q.Add("url", track.Url)
|
||||
u.RawQuery = q.Encode()
|
||||
fmt.Fprintf(b, "%s\n", u.String())
|
||||
}
|
||||
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func removeDuplicate(strSlice []TrackInfo) []TrackInfo {
|
||||
allKeys := make(map[string]bool)
|
||||
list := []TrackInfo{}
|
||||
for _, item := range strSlice {
|
||||
if _, value := allKeys[item.Url]; !value {
|
||||
allKeys[item.Url] = true
|
||||
list = append(list, item)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue