- Document all exported types, functions, methods, and constants across 52 files - Add package-level doc comments to client, models, utils, and ynison packages - Document HTTP method and endpoint path for each API client method - Document model struct fields and DeJSON/DeList/ToJSON/ToMap methods - Fix duplicate package doc comment in internal/models/base.go Co-Authored-By: Claude Code <noreply@anthropic.com>
82 lines
2.1 KiB
Go
82 lines
2.1 KiB
Go
// Package utils provides utility functions for the Yandex Music API client.
|
|
package utils
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
// DefaultSignKey is the signing key from the Android app.
|
|
DefaultSignKey = "p93jhgh689SBReK6ghtw62"
|
|
// DesktopSignKey is the signing key from the desktop app.
|
|
DesktopSignKey = "kzqU4XhfCaY6B6JTHODeq5"
|
|
// DesktopClient is the X-Yandex-Music-Client header value for desktop.
|
|
DesktopClient = "YandexMusicDesktopAppWindows/5.95.0"
|
|
)
|
|
|
|
// Sign represents a request signature for signed API requests.
|
|
type Sign struct {
|
|
Timestamp int64
|
|
Value string
|
|
}
|
|
|
|
// GetSignRequest creates a signature for a track request using HMAC-SHA256.
|
|
// It returns a Sign with the timestamp and base64-encoded signature value.
|
|
// If key is empty, DefaultSignKey is used.
|
|
func GetSignRequest(trackID string, key string) Sign {
|
|
if key == "" {
|
|
key = DefaultSignKey
|
|
}
|
|
|
|
timestamp := time.Now().Unix()
|
|
message := trackID + strconv.FormatInt(timestamp, 10)
|
|
|
|
h := hmac.New(sha256.New, []byte(key))
|
|
h.Write([]byte(message))
|
|
sign := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
|
|
|
return Sign{
|
|
Timestamp: timestamp,
|
|
Value: sign,
|
|
}
|
|
}
|
|
|
|
// GetFileInfoSign creates a signature for file info requests using HMAC-SHA256.
|
|
// It returns a Sign with the timestamp and base64-encoded signature value (last character removed as in Python).
|
|
// If key is empty, DesktopSignKey is used.
|
|
func GetFileInfoSign(trackID, quality string, codecs []string, transport, key string) Sign {
|
|
if key == "" {
|
|
key = DesktopSignKey
|
|
}
|
|
|
|
timestamp := time.Now().Unix()
|
|
message := fmt.Sprintf("%d%s%s%s%s", timestamp, trackID, quality, joinCodecs(codecs), transport)
|
|
|
|
h := hmac.New(sha256.New, []byte(key))
|
|
h.Write([]byte(message))
|
|
sign := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
|
// Remove last character as in Python
|
|
if len(sign) > 0 {
|
|
sign = sign[:len(sign)-1]
|
|
}
|
|
|
|
return Sign{
|
|
Timestamp: timestamp,
|
|
Value: sign,
|
|
}
|
|
}
|
|
|
|
// joinCodecs joins a list of codec strings into a single string.
|
|
func joinCodecs(codecs []string) string {
|
|
result := ""
|
|
for _, c := range codecs {
|
|
result += c
|
|
}
|
|
return result
|
|
}
|