test: 重构

This commit is contained in:
itouakirai
2025-03-02 23:44:05 +08:00
parent 2db22524b6
commit b2bcdfde88
12 changed files with 1823 additions and 1060 deletions

193
utils/task/album.go Normal file
View File

@@ -0,0 +1,193 @@
package task
import (
"bufio"
"errors"
"fmt"
"os"
"strconv"
"strings"
"github.com/fatih/color"
"github.com/olekukonko/tablewriter"
"main/utils/ampapi"
)
type Album struct {
Storefront string
ID string
SaveDir string
SaveName string
Codec string
CoverPath string
Language string
Resp ampapi.AlbumResp
Name string
Tracks []Track
}
func NewAlbum(st string, id string) *Album {
a := new(Album)
a.Storefront = st
a.ID = id
//fmt.Println("Album created")
return a
}
func (a *Album) GetResp(token, l string) error {
var err error
a.Language = l
resp, err := ampapi.GetAlbumResp(a.Storefront, a.ID, a.Language, token)
if err != nil {
return errors.New("error getting album response")
}
a.Resp = *resp
//简化高频调用名称
a.Name = a.Resp.Data[0].Attributes.Name
//fmt.Println("Getting album response")
//从resp中的Tracks数据中提取trackData信息到新的Track结构体中
for i, trackData := range a.Resp.Data[0].Relationships.Tracks.Data {
len := len(a.Resp.Data[0].Relationships.Tracks.Data)
a.Tracks = append(a.Tracks, Track{
ID: trackData.ID,
Type: trackData.Type,
Name: trackData.Attributes.Name,
Language: a.Language,
Storefront: a.Storefront,
//SaveDir: filepath.Join(a.SaveDir, a.SaveName),
//Codec: a.Codec,
TaskNum: i + 1,
TaskTotal: len,
M3u8: trackData.Attributes.ExtendedAssetUrls.EnhancedHls,
WebM3u8: trackData.Attributes.ExtendedAssetUrls.EnhancedHls,
//CoverPath: a.CoverPath,
Resp: trackData,
PreType: "albums",
DiscTotal: a.Resp.Data[0].Relationships.Tracks.Data[len-1].Attributes.DiscNumber,
PreID: a.ID,
AlbumData: a.Resp.Data[0],
})
}
return nil
}
func (a *Album) GetArtwork() string {
return a.Resp.Data[0].Attributes.Artwork.URL
}
func (a *Album) ShowSelect() []int {
meta := a.Resp
trackTotal := len(meta.Data[0].Relationships.Tracks.Data)
arr := make([]int, trackTotal)
for i := 0; i < trackTotal; i++ {
arr[i] = i + 1
}
selected := []int{}
var data [][]string
for trackNum, track := range meta.Data[0].Relationships.Tracks.Data {
trackNum++
trackName := fmt.Sprintf("%02d. %s", track.Attributes.TrackNumber, track.Attributes.Name)
data = append(data, []string{fmt.Sprint(trackNum),
trackName,
track.Attributes.ContentRating,
track.Type})
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"", "Track Name", "Rating", "Type"})
//table.SetFooter([]string{"", "", "Footer", "Footer4"})
table.SetRowLine(false)
//table.SetAutoMergeCells(true)
table.SetCaption(true, fmt.Sprintf("Storefront: %s, %d tracks missing", strings.ToUpper(a.Storefront), meta.Data[0].Attributes.TrackCount-trackTotal))
table.SetHeaderColor(tablewriter.Colors{},
tablewriter.Colors{tablewriter.FgRedColor, tablewriter.Bold},
tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.Bold},
tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.Bold})
table.SetColumnColor(tablewriter.Colors{tablewriter.FgCyanColor},
tablewriter.Colors{tablewriter.Bold, tablewriter.FgRedColor},
tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor},
tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})
for _, row := range data {
if row[2] == "explicit" {
row[2] = "E"
} else if row[2] == "clean" {
row[2] = "C"
} else {
row[2] = "None"
}
if row[3] == "music-videos" {
row[3] = "MV"
} else if row[3] == "songs" {
row[3] = "SONG"
}
table.Append(row)
}
//table.AppendBulk(data)
table.Render()
fmt.Println("Please select from the track options above (multiple options separated by commas, ranges supported, or type 'all' to select all)")
cyanColor := color.New(color.FgCyan)
cyanColor.Print("select: ")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
}
input = strings.TrimSpace(input)
if input == "all" {
fmt.Println("You have selected all options:")
selected = arr
} else {
selectedOptions := [][]string{}
parts := strings.Split(input, ",")
for _, part := range parts {
if strings.Contains(part, "-") { // Range setting
rangeParts := strings.Split(part, "-")
selectedOptions = append(selectedOptions, rangeParts)
} else { // Single option
selectedOptions = append(selectedOptions, []string{part})
}
}
//
for _, opt := range selectedOptions {
if len(opt) == 1 { // Single option
num, err := strconv.Atoi(opt[0])
if err != nil {
fmt.Println("Invalid option:", opt[0])
continue
}
if num > 0 && num <= len(arr) {
selected = append(selected, num)
//args = append(args, urls[num-1])
} else {
fmt.Println("Option out of range:", opt[0])
}
} else if len(opt) == 2 { // Range
start, err1 := strconv.Atoi(opt[0])
end, err2 := strconv.Atoi(opt[1])
if err1 != nil || err2 != nil {
fmt.Println("Invalid range:", opt)
continue
}
if start < 1 || end > len(arr) || start > end {
fmt.Println("Range out of range:", opt)
continue
}
for i := start; i <= end; i++ {
//fmt.Println(options[i-1])
selected = append(selected, i)
}
} else {
fmt.Println("Invalid option:", opt)
}
}
}
return selected
}

195
utils/task/playlist.go Normal file
View File

@@ -0,0 +1,195 @@
package task
import (
"bufio"
"errors"
"fmt"
"os"
"strconv"
"strings"
"github.com/fatih/color"
"github.com/olekukonko/tablewriter"
"main/utils/ampapi"
)
type Playlist struct {
Storefront string
ID string
SaveDir string
SaveName string
Codec string
CoverPath string
Language string
Resp ampapi.PlaylistResp
Name string
Tracks []Track
}
func NewPlaylist(st string, id string) *Playlist {
a := new(Playlist)
a.Storefront = st
a.ID = id
//fmt.Println("Album created")
return a
}
func (a *Playlist) GetResp(token, l string) error {
var err error
a.Language = l
resp, err := ampapi.GetPlaylistResp(a.Storefront, a.ID, a.Language, token)
if err != nil {
return errors.New("error getting album response")
}
a.Resp = *resp
a.Resp.Data[0].Attributes.ArtistName = "Apple Music"
//简化高频调用名称
a.Name = a.Resp.Data[0].Attributes.Name
//fmt.Println("Getting album response")
//从resp中的Tracks数据中提取trackData信息到新的Track结构体中
for i, trackData := range a.Resp.Data[0].Relationships.Tracks.Data {
len := len(a.Resp.Data[0].Relationships.Tracks.Data)
a.Tracks = append(a.Tracks, Track{
ID: trackData.ID,
Type: trackData.Type,
Name: trackData.Attributes.Name,
Language: a.Language,
Storefront: a.Storefront,
//SaveDir: filepath.Join(a.SaveDir, a.SaveName),
//Codec: a.Codec,
TaskNum: i + 1,
TaskTotal: len,
M3u8: trackData.Attributes.ExtendedAssetUrls.EnhancedHls,
WebM3u8: trackData.Attributes.ExtendedAssetUrls.EnhancedHls,
//CoverPath: a.CoverPath,
Resp: trackData,
PreType: "playlists",
//DiscTotal: a.Resp.Data[0].Relationships.Tracks.Data[len-1].Attributes.DiscNumber, 在它处获取
PreID: a.ID,
PlaylistData: a.Resp.Data[0],
})
}
return nil
}
func (a *Playlist) GetArtwork() string {
return a.Resp.Data[0].Attributes.Artwork.URL
}
func (a *Playlist) ShowSelect() []int {
meta := a.Resp
trackTotal := len(meta.Data[0].Relationships.Tracks.Data)
arr := make([]int, trackTotal)
for i := 0; i < trackTotal; i++ {
arr[i] = i + 1
}
selected := []int{}
var data [][]string
for trackNum, track := range meta.Data[0].Relationships.Tracks.Data {
trackNum++
trackName := fmt.Sprintf("%s - %s", track.Attributes.Name, track.Attributes.ArtistName)
data = append(data, []string{fmt.Sprint(trackNum),
trackName,
track.Attributes.ContentRating,
track.Type})
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"", "Track Name", "Rating", "Type"})
//table.SetFooter([]string{"", "", "Footer", "Footer4"})
table.SetRowLine(false)
//table.SetAutoMergeCells(true)
table.SetCaption(true, fmt.Sprintf("Playlists: %d tracks", trackTotal))
table.SetHeaderColor(tablewriter.Colors{},
tablewriter.Colors{tablewriter.FgRedColor, tablewriter.Bold},
tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.Bold},
tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.Bold})
table.SetColumnColor(tablewriter.Colors{tablewriter.FgCyanColor},
tablewriter.Colors{tablewriter.Bold, tablewriter.FgRedColor},
tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor},
tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})
for _, row := range data {
if row[2] == "explicit" {
row[2] = "E"
} else if row[2] == "clean" {
row[2] = "C"
} else {
row[2] = "None"
}
if row[3] == "music-videos" {
row[3] = "MV"
} else if row[3] == "songs" {
row[3] = "SONG"
}
table.Append(row)
}
//table.AppendBulk(data)
table.Render()
fmt.Println("Please select from the track options above (multiple options separated by commas, ranges supported, or type 'all' to select all)")
cyanColor := color.New(color.FgCyan)
cyanColor.Print("select: ")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
}
input = strings.TrimSpace(input)
if input == "all" {
fmt.Println("You have selected all options:")
selected = arr
} else {
selectedOptions := [][]string{}
parts := strings.Split(input, ",")
for _, part := range parts {
if strings.Contains(part, "-") { // Range setting
rangeParts := strings.Split(part, "-")
selectedOptions = append(selectedOptions, rangeParts)
} else { // Single option
selectedOptions = append(selectedOptions, []string{part})
}
}
//
for _, opt := range selectedOptions {
if len(opt) == 1 { // Single option
num, err := strconv.Atoi(opt[0])
if err != nil {
fmt.Println("Invalid option:", opt[0])
continue
}
if num > 0 && num <= len(arr) {
selected = append(selected, num)
//args = append(args, urls[num-1])
} else {
fmt.Println("Option out of range:", opt[0])
}
} else if len(opt) == 2 { // Range
start, err1 := strconv.Atoi(opt[0])
end, err2 := strconv.Atoi(opt[1])
if err1 != nil || err2 != nil {
fmt.Println("Invalid range:", opt)
continue
}
if start < 1 || end > len(arr) || start > end {
fmt.Println("Range out of range:", opt)
continue
}
for i := start; i <= end; i++ {
//fmt.Println(options[i-1])
selected = append(selected, i)
}
} else {
fmt.Println("Invalid option:", opt)
}
}
}
return selected
}

44
utils/task/track.go Normal file
View File

@@ -0,0 +1,44 @@
package task
import (
"main/utils/ampapi"
)
type Track struct {
ID string
Type string
Name string
Storefront string
Language string
SaveDir string
SaveName string
SavePath string
Codec string
TaskNum int
TaskTotal int
M3u8 string
WebM3u8 string
DeviceM3u8 string
Quality string
CoverPath string
Resp ampapi.TrackRespData
PreType string // 上级类型 专辑或者歌单
PreID string // 上级ID
DiscTotal int
AlbumData ampapi.AlbumRespData
PlaylistData ampapi.PlaylistRespData
}
func (t *Track) GetAlbumData(token string) error {
var err error
resp, err := ampapi.GetAlbumRespByHref(t.Resp.Href, t.Language, token)
if err != nil {
return err
}
t.AlbumData = resp.Data[0]
//len := len(resp.Data[0].Relationships.Tracks.Data)
//t.DiscTotal = resp.Data[0].Relationships.Tracks.Data[len-1].Attributes.DiscNumber
return nil
}