From 0456ca0665a6df005ed6124aafe2370fdc6de306 Mon Sep 17 00:00:00 2001 From: Vladimir Zagainov Date: Sun, 18 Oct 2026 08:57:43 +0300 Subject: [PATCH] Add comprehensive godoc documentation to all exported symbols - 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 --- .serena/.gitignore | 2 + .serena/project.yml | 163 ++++++++++++++++++++++++ CLAUDE.md | 182 +++++++++++++++++++++++++++ internal/client/account.go | 18 +-- internal/client/albums.go | 10 +- internal/client/artists.go | 15 ++- internal/client/auth.go | 16 ++- internal/client/clips.go | 10 +- internal/client/concerts.go | 13 +- internal/client/feed.go | 18 +-- internal/client/history.go | 7 +- internal/client/labels.go | 12 +- internal/client/likes.go | 37 ++---- internal/client/metatags.go | 21 ++-- internal/client/pins.go | 9 +- internal/client/playlists.go | 29 +++-- internal/client/queue.go | 50 +++----- internal/client/radio.go | 27 ++-- internal/client/request.go | 35 ++++-- internal/client/search.go | 22 ++-- internal/client/settings.go | 15 +-- internal/client/supplements.go | 41 +++---- internal/client/tracks.go | 17 ++- internal/models/account.go | 25 ++-- internal/models/album.go | 25 ++-- internal/models/artist.go | 33 ++--- internal/models/artist_albums.go | 7 +- internal/models/artist_tracks.go | 7 +- internal/models/base.go | 29 +++-- internal/models/client.go | 13 +- internal/models/clip.go | 25 ++-- internal/models/concert.go | 33 ++--- internal/models/credits.go | 17 +-- internal/models/feed.go | 35 +++--- internal/models/label.go | 11 +- internal/models/landing.go | 17 +-- internal/models/metatag.go | 45 +++---- internal/models/music_history.go | 21 ++-- internal/models/pin.go | 19 +-- internal/models/playlist.go | 23 ++-- internal/models/queue.go | 25 ++-- internal/models/radio.go | 37 +++--- internal/models/search.go | 21 ++-- internal/models/settings.go | 35 +++--- internal/models/supplement.go | 37 +++--- internal/models/track.go | 15 +-- internal/models/track_short.go | 13 +- internal/utils/json.go | 35 ++++-- internal/utils/response.go | 50 +++++--- internal/utils/schema.go | 45 +++++-- internal/utils/sign.go | 18 ++- internal/ynison/client.go | 44 +++---- internal/ynison/helpers.go | 16 +-- yandexmusic/client.go | 204 ++++++++++++++++--------------- 54 files changed, 1097 insertions(+), 652 deletions(-) create mode 100644 .serena/.gitignore create mode 100644 .serena/project.yml create mode 100644 CLAUDE.md diff --git a/.serena/.gitignore b/.serena/.gitignore new file mode 100644 index 0000000..2e510af --- /dev/null +++ b/.serena/.gitignore @@ -0,0 +1,2 @@ +/cache +/project.local.yml diff --git a/.serena/project.yml b/.serena/project.yml new file mode 100644 index 0000000..3acbf7a --- /dev/null +++ b/.serena/project.yml @@ -0,0 +1,163 @@ +# the name by which the project can be referenced within Serena/when chatting with the LLM. +project_name: "yandex-music-api-go" + +# list of languages for which language servers are started (LSP backend only); choose from: +# ada al angular ansible bash +# bsl clojure cpp cpp_ccls crystal +# csharp csharp_omnisharp cue dart elixir +# elm erlang fortran fsharp gdscript +# go groovy haskell haxe hlsl +# html java json julia kotlin +# latex lean4 lua luau markdown +# matlab msl nix ocaml pascal +# perl php php_phpactor php_phpantom powershell +# python python_jedi python_pyrefly python_ty r +# rego ruby ruby_solargraph rust scala +# scss solidity svelte swift systemverilog +# terraform toml typescript typescript_vts vue +# yaml zig +# (This list may be outdated; generated with scripts/print_language_list.py; +# For the current list, see values of Language enum here: +# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py) +# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# Note: +# - For C, use cpp +# - For JavaScript, use typescript +# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root) +# - For Svelte projects, use svelte (subsumes typescript/javascript for .svelte projects; requires npm) +# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three) +# - For Free Pascal/Lazarus, use pascal +# Special requirements: +# Some languages require additional setup/installations. +# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers +# When using multiple languages, the first language server that supports a given file will be used for that file. +# The first language is the default language and the respective language server will be used as a fallback. +# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. +languages: +- python +- go +- markdown +- json + +# the encoding used by text files in the project +# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings +encoding: "utf-8" + +# optional shell command to run before the language backend (LSP or JetBrains) is initialised. +# the command runs in the project root directory and is only executed if the project is trusted +# (see trusted_project_path_patterns in the global configuration). +# serena waits for the command to exit: a non-zero exit code is logged as an error but does not +# abort activation. a per-project timeout (activation_command_timeout, default 180s) is the safety +# backstop for non-terminating commands; on expiry the process is killed and activation continues. +# example: activation_command: "npx nx run-many -t build" +activation_command: + +# maximum time in seconds to wait for activation_command to complete before killing it (default 180s). +# must be a positive number. +activation_command_timeout: 180.0 + +# line ending convention to use when writing source files. +# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default) +# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings. +line_ending: + +# The language backend to use for this project. +# If not set, the global setting from serena_config.yml is used. +# Valid values: LSP, JetBrains +# Note: the backend is fixed at startup. If a project with a different backend +# is activated post-init, an error will be returned. +language_backend: + +# whether to use project's .gitignore files to ignore files +ignore_all_files_in_gitignore: true + +# advanced configuration option allowing to configure language server-specific options. +# Maps the language key to the options. +# The settings are considered only if the project is trusted (see global configuration to define trusted projects). +# See https://oraios.github.io/serena/02-usage/050_configuration.html#language-server-specific-settings +ls_specific_settings: {} + +# list of workspace folder paths (LSP backend only). +# These folders will be used to build up Serena's symbol index. +# Paths must be within the project root and should thus be relative to the project root. +# Furthermore, the paths should not be filtered by ignore settings. +# Default setting: The entire project root folder (".") is considered. +# In (large) monorepos, this can be used to index only subfolders of the project root, e.g. +# ls_workspace_folders: +# - "./subproject1" +# - "./subproject2" +ls_workspace_folders: +- "." + +# list of additional workspace folder paths for cross-package reference support. +# Paths can be absolute or relative to the project root. +# Each folder is registered as an LSP workspace folder, enabling language servers to discover +# symbols and references across package boundaries, but these folders are not indexed by Serena, +# i.e. the respective symbols will not be found using Serena's symbol search tools. +# Example: +# additional_workspace_folders: +# - ../sibling-package +# - ../shared-lib +ls_additional_workspace_folders: [] + +# list of additional paths to ignore in this project. +# Same syntax as gitignore, so you can use * and **. +# Note: global ignored_paths from serena_config.yml are also applied additively. +ignored_paths: [] + +# whether the project is in read-only mode +# If set to true, all editing tools will be disabled and attempts to use them will result in an error +# Added on 2025-04-18 +read_only: false + +# list of tool names to exclude. +# This extends the existing exclusions (e.g. from the global configuration) +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +excluded_tools: [] + +# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default). +# This extends the existing inclusions (e.g. from the global configuration). +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +included_optional_tools: [] + +# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools. +# This cannot be combined with non-empty excluded_tools or included_optional_tools. +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +fixed_tools: [] + +# list of mode names that are to be activated by default, overriding the setting in the global configuration. +# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes. +# If the setting is undefined/empty, the default_modes from the global configuration (serena_config.yml) apply. +# Otherwise, this overrides the setting from the global configuration (serena_config.yml). +# Therefore, you can set this to [] if you do not want the default modes defined in the global config to apply +# for this project. +# This setting can, in turn, be overridden by CLI parameters (--mode). +# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes +default_modes: + +# list of mode names to be activated additionally for this project, e.g. ["query-projects"] +# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes. +# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes +added_modes: + +# initial prompt for the project. It will always be given to the LLM upon activating the project +# (contrary to the memories, which are loaded on demand). +initial_prompt: "" + +# time budget (seconds) per tool call for the retrieval of additional symbol information +# such as docstrings or parameter information. +# This overrides the corresponding setting in the global configuration; see the documentation there. +# If null or missing, use the setting from the global configuration. +symbol_info_budget: + +# list of regex patterns which, when matched, mark a memory entry as read‑only. +# Extends the list from the global configuration, merging the two lists. +read_only_memory_patterns: [] + +# list of regex patterns for memories to completely ignore. +# Matching memories will not appear in list_memories or activate_project output +# and cannot be accessed via read_memory or write_memory. +# To access ignored memory files, use the read_file tool on the raw file path. +# Extends the list from the global configuration, merging the two lists. +# Example: ["_archive/.*", "_episodes/.*"] +ignored_memory_patterns: [] diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..05e7025 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,182 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a Go port of the [yandex-music-api](https://github.com/MarshalX/yandex-music-api) Python library. The original Python library is in `yandex-music-api-python/` and serves as the reference implementation. + +The Python library provides: +- **Sync and async HTTP clients** for Yandex Music API +- **Ynison protocol support** for player synchronization across devices +- **Radio sessions** (My Wave, generative stations) +- **High-level wrapper objects** (Track, Album, Artist, Playlist, etc.) +- **Schema mismatch handling** for API evolution +- **Multiple JSON backend support** (orjson, pydantic-core, ujson, stdlib json) + +## Python Library Architecture (Reference) + +### Core Structure +``` +yandex_music/ +├── client.py # Sync Client (main entry point) +├── client_async.py # Async ClientAsync +├── _client_base.py # Shared base class with common attributes +├── base.py # YandexMusicObject base model with de_json/de_list +├── exceptions.py # Custom exceptions +├── utils/ +│ ├── request.py # Sync HTTP request handling +│ ├── request_async.py # Async HTTP request handling +│ ├── json_backend.py # Pluggable JSON backends +│ └── schema_mismatch.py # Schema mismatch reporting +├── _client/ # Generated sync method mixins (20+ files) +├── _client_async/ # Generated async method mixins +├── track/, album/, artist/, playlist/, etc. # Model packages +├── ynison/ # Ynison protocol (WebSocket) +│ ├── client.py # Sync Ynison client +│ ├── client_async.py # Async Ynison client +│ └── models/ # Protobuf-generated models +└── supplement/ # Lyrics, video supplements +``` + +### Key Patterns +- **Mixin-based Client**: `Client` inherits from 20+ mixins (AccountMixin, AlbumsMixin, TracksMixin, etc.) +- **Model deserialization**: Each model has `de_json(data, client)` and `de_list(list_data, client)` classmethods +- **Request signing**: Requests to `api.music.yandex.net` are signed with a custom algorithm +- **Device auth**: OAuth Device Flow for token acquisition +- **Generated code**: Sync/async clients and models are partially code-generated from OpenAPI spec + +## Go Project Structure (Target) + +``` +yandex-music-api-go/ +├── go.mod +├── go.sum +├── cmd/ +│ └── examples/ # Example applications +├── internal/ +│ ├── client/ # Core HTTP client +│ │ ├── client.go # Main Client struct +│ │ ├── request.go # Request building/signing +│ │ └── auth.go # Device auth, token handling +│ ├── models/ # Data models (Track, Album, Artist, etc.) +│ │ ├── base.go # BaseModel interface +│ │ ├── track.go +│ │ ├── album.go +│ │ └── ... +│ ├── ynison/ # Ynison WebSocket client +│ │ ├── client.go +│ │ └── proto/ # Protobuf-generated Go code +│ └── utils/ +│ ├── json.go # JSON handling +│ └── schema.go # Schema mismatch handling +├── yandexmusic/ # Public API package (re-exports) +│ ├── client.go # Public Client interface +│ └── models.go # Public model types +└── tests/ # Integration tests +``` + +## Development Commands + +### Go Toolchain +```bash +# Initialize module (run once) +go mod init github.com/your-org/yandex-music-api-go + +# Download dependencies +go mod tidy + +# Build +go build ./... + +# Run tests +go test ./... + +# Run tests with coverage +go test -cover ./... + +# Run single test +go test -v -run TestName ./path/to/package + +# Lint (requires golangci-lint) +golangci-lint run + +# Format +go fmt ./... + +# Vet +go vet ./... + +# Generate code (if using code generation) +go generate ./... +``` + +### Protobuf (for Ynison) +```bash +# Install protoc and plugins +go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +go install github.com/bufbuild/buf/cmd/buf@latest # optional, for buf.yaml workflow + +# Generate from .proto files +protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + internal/ynison/proto/*.proto + +# Or with buf +buf generate +``` + +## Key Implementation Notes + +### Request Signing +The Python library signs requests with a custom algorithm. Port this exactly from `yandex_music/utils/request.py`: +- Request parameters are sorted and concatenated +- Signed with a secret key +- Signature added as `sign` parameter + +### JSON Handling +Go's standard `encoding/json` is fast enough. No need for multiple backends. Use `json.RawMessage` for flexible fields. + +### Schema Mismatch Handling +Port the Python `SchemaMismatch` logic: +- Track unknown fields in API responses +- Configurable: ignore, warn, or strict (error) +- Callback support for custom handling (e.g., Sentry) + +### Ynison Protocol +- Uses WebSocket with protobuf messages +- Python uses `betterproto` for protobuf; Go uses standard `protobuf` module +- Port the message types from `yandex_music/ynison/models/` + +### Model Structure +Follow Python patterns: +```go +// Base interface for all models +type Model interface { + // DeJSON deserializes from JSON + DeJSON(data []byte, client *Client) (Model, error) + // DeList deserializes a list + DeList(data []byte, client *Client) ([]Model, error) +} +``` + +### Client Design +- Single `Client` struct with methods (not mixins - Go doesn't have them) +- Group methods by feature using separate files: `client_tracks.go`, `client_albums.go`, etc. +- Support both sync and async (context-based) patterns + +## Testing Strategy +- Unit tests for models (de/serialization) +- Integration tests against mock server (use `httptest`) +- Test schema mismatch handling +- Test request signing + +## License +LGPL-3.0-only (same as Python library) + +## References +- Python library: `yandex-music-api-python/` +- OpenAPI spec: https://ym.marshal.dev/api/openapi.json +- Documentation: https://ym.marshal.dev/ +- Telegram: https://t.me/yandex_music_api \ No newline at end of file diff --git a/internal/client/account.go b/internal/client/account.go index a2c9cab..113af1e 100644 --- a/internal/client/account.go +++ b/internal/client/account.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -6,7 +7,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetAccountSettings gets account settings (current user's settings from /account/settings) +// GetAccountSettings gets account settings (current user's settings from /account/settings). func (c *Client) GetAccountSettings(ctx context.Context) (*models.UserSettings, error) { var result models.UserSettings if err := c.request.Get(ctx, "/account/settings", nil, &result); err != nil { @@ -15,7 +16,7 @@ func (c *Client) GetAccountSettings(ctx context.Context) (*models.UserSettings, return &result, nil } -// UpdateAccountSettings updates account settings +// UpdateAccountSettings updates account settings (PUT /account/settings). func (c *Client) UpdateAccountSettings(ctx context.Context, settings *models.AccountSettings) (*models.AccountSettings, error) { var result models.AccountSettings if err := c.request.Put(ctx, "/account/settings", settings, &result); err != nil { @@ -24,7 +25,7 @@ func (c *Client) UpdateAccountSettings(ctx context.Context, settings *models.Acc return &result, nil } -// GetSubscription gets user subscription info +// GetSubscription gets user subscription info (GET /account/subscription). func (c *Client) GetSubscription(ctx context.Context) (*models.Subscription, error) { var result models.Subscription if err := c.request.Get(ctx, "/account/subscription", nil, &result); err != nil { @@ -33,7 +34,7 @@ func (c *Client) GetSubscription(ctx context.Context) (*models.Subscription, err return &result, nil } -// GetPlusInfo gets Plus subscription info +// GetPlusInfo gets Plus subscription info (GET /account/plus). func (c *Client) GetPlusInfo(ctx context.Context) (*models.PlusInfo, error) { var result models.PlusInfo if err := c.request.Get(ctx, "/account/plus", nil, &result); err != nil { @@ -42,7 +43,7 @@ func (c *Client) GetPlusInfo(ctx context.Context) (*models.PlusInfo, error) { return &result, nil } -// GetPromoCodeStatus gets promo code status +// GetPromoCodeStatus gets promo code status (GET /promo-code-status). func (c *Client) GetPromoCodeStatus(ctx context.Context, code string) (*models.PromoCodeStatus, error) { params := map[string]string{ "code": code, @@ -54,7 +55,7 @@ func (c *Client) GetPromoCodeStatus(ctx context.Context, code string) (*models.P return &result, nil } -// ActivatePromoCode activates a promo code +// ActivatePromoCode activates a promo code (POST /promo-code/activate). func (c *Client) ActivatePromoCode(ctx context.Context, code string) (*models.PromoCodeStatus, error) { params := map[string]string{ "code": code, @@ -66,7 +67,7 @@ func (c *Client) ActivatePromoCode(ctx context.Context, code string) (*models.Pr return &result, nil } -// GetUserSettings gets user settings +// GetUserSettings gets user settings for a specific user (GET /user/settings). func (c *Client) GetUserSettings(ctx context.Context, userID string) (*models.UserSettings, error) { params := map[string]string{ "user_id": userID, @@ -78,7 +79,8 @@ func (c *Client) GetUserSettings(ctx context.Context, userID string) (*models.Us return &result, nil } -// GetAccountStatus fetches account status +// GetAccountStatus fetches account status (GET /account/status). +// It returns the account status including account info and Plus subscription status. func (c *Client) GetAccountStatus(ctx context.Context) (*Status, error) { var result Status if err := c.request.Get(ctx, "/account/status", nil, &result); err != nil { diff --git a/internal/client/albums.go b/internal/client/albums.go index 62efb5c..ffbef6c 100644 --- a/internal/client/albums.go +++ b/internal/client/albums.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,8 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// GetAlbums gets albums by IDs +// GetAlbums gets albums by their IDs (GET /tracks?album-ids=...). +// Returns a slice of Album pointers, or nil if no IDs are provided. func (c *Client) GetAlbums(ctx context.Context, albumIDs []string) ([]*models.Album, error) { if len(albumIDs) == 0 { return nil, nil @@ -30,7 +32,8 @@ func (c *Client) GetAlbums(ctx context.Context, albumIDs []string) ([]*models.Al return albums, nil } -// GetAlbum gets a single album by ID +// GetAlbum gets a single album by ID using GetAlbums. +// Returns an error if no album is found with the given ID. func (c *Client) GetAlbum(ctx context.Context, albumID string) (*models.Album, error) { albums, err := c.GetAlbums(ctx, []string{albumID}) if err != nil { @@ -42,7 +45,8 @@ func (c *Client) GetAlbum(ctx context.Context, albumID string) (*models.Album, e return albums[0], nil } -// GetAlbumsWithTracks gets albums with tracks expanded +// GetAlbumsWithTracks gets albums with tracks expanded (GET /tracks?with-tracks=true). +// Returns a slice of Album pointers with their tracks populated. func (c *Client) GetAlbumsWithTracks(ctx context.Context, albumIDs []string) ([]*models.Album, error) { if len(albumIDs) == 0 { return nil, nil diff --git a/internal/client/artists.go b/internal/client/artists.go index d45157c..1222a55 100644 --- a/internal/client/artists.go +++ b/internal/client/artists.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -8,7 +9,8 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// GetArtists gets artists by IDs +// GetArtists gets artists by their IDs (GET /tracks?artist-ids=...). +// Returns a slice of Artist pointers, or nil if no IDs are provided. func (c *Client) GetArtists(ctx context.Context, artistIDs []string) ([]*models.Artist, error) { if len(artistIDs) == 0 { return nil, nil @@ -31,7 +33,8 @@ func (c *Client) GetArtists(ctx context.Context, artistIDs []string) ([]*models. return artists, nil } -// GetArtist gets a single artist by ID +// GetArtist gets a single artist by ID using GetArtists. +// Returns an error if no artist is found with the given ID. func (c *Client) GetArtist(ctx context.Context, artistID string) (*models.Artist, error) { artists, err := c.GetArtists(ctx, []string{artistID}) if err != nil { @@ -43,8 +46,8 @@ func (c *Client) GetArtist(ctx context.Context, artistID string) (*models.Artist return artists[0], nil } -// GetArtistAlbums gets albums by an artist -// GET /artists/{artist_id}/direct-albums +// GetArtistAlbums gets albums by an artist (GET /artists/{artist_id}/direct-albums). +// The page and pageSize parameters control pagination. func (c *Client) GetArtistAlbums(ctx context.Context, artistID string, page, pageSize int) (*models.ArtistAlbums, error) { params := map[string]string{ "page": fmt.Sprintf("%d", page), @@ -59,8 +62,8 @@ func (c *Client) GetArtistAlbums(ctx context.Context, artistID string, page, pag return &result, nil } -// GetArtistTracks gets tracks by an artist -// GET /artists/{artist_id}/tracks +// GetArtistTracks gets tracks by an artist (GET /artists/{artist_id}/tracks). +// The page and pageSize parameters control pagination. func (c *Client) GetArtistTracks(ctx context.Context, artistID string, page, pageSize int) (*models.ArtistTracks, error) { params := map[string]string{ "page": fmt.Sprintf("%d", page), diff --git a/internal/client/auth.go b/internal/client/auth.go index b2bece3..62d09f3 100644 --- a/internal/client/auth.go +++ b/internal/client/auth.go @@ -13,7 +13,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// DeviceCode represents the device authorization response +// DeviceCode represents the device authorization response from the Yandex OAuth device flow. type DeviceCode struct { DeviceCode string `json:"device_code"` UserCode string `json:"user_code"` @@ -22,7 +22,7 @@ type DeviceCode struct { Interval int `json:"interval"` } -// OAuthToken represents an OAuth token response +// OAuthToken represents an OAuth token response from the Yandex OAuth token endpoint. type OAuthToken struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` @@ -30,7 +30,9 @@ type OAuthToken struct { ExpiresIn int `json:"expires_in"` } -// DeviceAuth performs OAuth Device Flow authentication +// DeviceAuth performs OAuth Device Flow authentication. +// It requests a device code, invokes the onCode callback with it, then polls for the token. +// The onCode callback receives the DeviceCode which contains the user_code and verification URL. func (r *Request) DeviceAuth(ctx context.Context, onCode func(*DeviceCode)) (*OAuthToken, error) { // Step 1: Request device code deviceCode, err := r.requestDeviceCode(ctx) @@ -47,7 +49,7 @@ func (r *Request) DeviceAuth(ctx context.Context, onCode func(*DeviceCode)) (*OA return r.pollForToken(ctx, deviceCode) } -// requestDeviceCode requests a device code from Yandex OAuth +// requestDeviceCode requests a device code from the Yandex OAuth device code endpoint. func (r *Request) requestDeviceCode(ctx context.Context) (*DeviceCode, error) { // Use Yandex OAuth endpoint for device auth data := url.Values{} @@ -85,7 +87,8 @@ func (r *Request) requestDeviceCode(ctx context.Context) (*DeviceCode, error) { return &deviceCode, nil } -// pollForToken polls for the OAuth token +// pollForToken polls the Yandex OAuth token endpoint until the user authorizes the device code. +// It returns the OAuthToken once authorization is complete, or an error if the code expires or is denied. func (r *Request) pollForToken(ctx context.Context, deviceCode *DeviceCode) (*OAuthToken, error) { interval := deviceCode.Interval if interval == 0 { @@ -155,7 +158,8 @@ func (r *Request) pollForToken(ctx context.Context, deviceCode *DeviceCode) (*OA } } -// RefreshToken refreshes an access token using a refresh token +// RefreshToken refreshes an access token using the provided refresh token. +// It makes a POST request to the Yandex OAuth token endpoint with grant_type=refresh_token. func (r *Request) RefreshToken(ctx context.Context, refreshToken string) (*OAuthToken, error) { data := url.Values{} data.Set("grant_type", "refresh_token") diff --git a/internal/client/clips.go b/internal/client/clips.go index ed0a0ed..3f0e0be 100644 --- a/internal/client/clips.go +++ b/internal/client/clips.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetClips gets clips +// GetClips gets clips with pagination (GET /clips). func (c *Client) GetClips(ctx context.Context, page, pageSize int) ([]*models.Clip, error) { params := map[string]string{ "page": "1", @@ -33,7 +34,7 @@ func (c *Client) GetClips(ctx context.Context, page, pageSize int) ([]*models.Cl return clips, nil } -// GetClipsWillLike gets clips the user might like +// GetClipsWillLike gets clips the user might like (GET /clips/will/like). func (c *Client) GetClipsWillLike(ctx context.Context) (*models.ClipsWillLike, error) { var result models.ClipsWillLike if err := c.request.Get(ctx, "/clips/will/like", nil, &result); err != nil { @@ -42,8 +43,7 @@ func (c *Client) GetClipsWillLike(ctx context.Context) (*models.ClipsWillLike, e return &result, nil } -// GetArtistClips gets clips by an artist -// GET /artists/{artistID}/blocks/artist-clips +// GetArtistClips gets clips by an artist (GET /artists/{artistID}/blocks/artist-clips). func (c *Client) GetArtistClips(ctx context.Context, artistID string) (*models.ArtistClipData, error) { var result models.ArtistClipData if err := c.request.Get(ctx, fmt.Sprintf("/artists/%s/blocks/artist-clips", artistID), nil, &result); err != nil { @@ -52,7 +52,7 @@ func (c *Client) GetArtistClips(ctx context.Context, artistID string) (*models.A return &result, nil } -// GetShots gets shots +// GetShots gets shots with pagination (GET /shots). func (c *Client) GetShots(ctx context.Context, page, pageSize int) ([]*models.Shot, error) { params := map[string]string{ "page": "1", diff --git a/internal/client/concerts.go b/internal/client/concerts.go index 9adcbe7..16cee04 100644 --- a/internal/client/concerts.go +++ b/internal/client/concerts.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetConcerts gets concerts +// GetConcerts gets concerts with pagination (GET /concerts). func (c *Client) GetConcerts(ctx context.Context, page, pageSize int) (*models.ConcertFeed, error) { params := map[string]string{ "page": "1", @@ -27,7 +28,7 @@ func (c *Client) GetConcerts(ctx context.Context, page, pageSize int) (*models.C return &result, nil } -// GetConcertFeed gets concert feed +// GetConcertFeed gets the concert feed (GET /concerts/feed). func (c *Client) GetConcertFeed(ctx context.Context) (*models.ConcertFeed, error) { var result models.ConcertFeed if err := c.request.Get(ctx, "/concerts/feed", nil, &result); err != nil { @@ -36,8 +37,7 @@ func (c *Client) GetConcertFeed(ctx context.Context) (*models.ConcertFeed, error return &result, nil } -// GetConcertInfo gets concert info -// GET /concerts/{concertID}/info +// GetConcertInfo gets concert info by ID (GET /concerts/{concertID}/info). func (c *Client) GetConcertInfo(ctx context.Context, concertID string) (*models.ConcertInfo, error) { var result models.ConcertInfo if err := c.request.Get(ctx, fmt.Sprintf("/concerts/%s/info", concertID), nil, &result); err != nil { @@ -46,7 +46,7 @@ func (c *Client) GetConcertInfo(ctx context.Context, concertID string) (*models. return &result, nil } -// GetConcertLocations gets concert locations +// GetConcertLocations gets concert locations (GET /concerts/locations). func (c *Client) GetConcertLocations(ctx context.Context) (*models.ConcertLocations, error) { var result models.ConcertLocations if err := c.request.Get(ctx, "/concerts/locations", nil, &result); err != nil { @@ -55,8 +55,7 @@ func (c *Client) GetConcertLocations(ctx context.Context) (*models.ConcertLocati return &result, nil } -// GetConcertTabs gets concert tabs -// GET /concerts/tab-config +// GetConcertTabs gets concert tab configuration (GET /concerts/tab-config). func (c *Client) GetConcertTabs(ctx context.Context) (*models.ConcertTabConfig, error) { var result models.ConcertTabConfig if err := c.request.Get(ctx, "/concerts/tab-config", nil, &result); err != nil { diff --git a/internal/client/feed.go b/internal/client/feed.go index d147a0e..0b130d0 100644 --- a/internal/client/feed.go +++ b/internal/client/feed.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetFeed gets the main feed +// GetFeed gets the main feed (GET /feed). func (c *Client) GetFeed(ctx context.Context) (*models.Feed, error) { var result models.Feed if err := c.request.Get(ctx, "/feed", nil, &result); err != nil { @@ -16,7 +17,7 @@ func (c *Client) GetFeed(ctx context.Context) (*models.Feed, error) { return &result, nil } -// GetFeedBlocks gets feed blocks +// GetFeedBlocks gets feed blocks (GET /feed/blocks). func (c *Client) GetFeedBlocks(ctx context.Context) ([]*models.DayBlock, error) { var result []models.DayBlock if err := c.request.Get(ctx, "/feed/blocks", nil, &result); err != nil { @@ -31,7 +32,7 @@ func (c *Client) GetFeedBlocks(ctx context.Context) ([]*models.DayBlock, error) return blocks, nil } -// GetFeedGeneratedPlaylist gets a generated playlist by ID from feed +// GetFeedGeneratedPlaylist gets a generated playlist by ID from the feed (GET /feed/generated-playlist). func (c *Client) GetFeedGeneratedPlaylist(ctx context.Context, playlistID string) (*models.GeneratedPlaylist, error) { params := map[string]string{ "playlist_id": playlistID, @@ -45,7 +46,7 @@ func (c *Client) GetFeedGeneratedPlaylist(ctx context.Context, playlistID string return &result, nil } -// GetFeedDay gets a specific day from the feed +// GetFeedDay gets a specific day from the feed by date (GET /feed/day). func (c *Client) GetFeedDay(ctx context.Context, date string) (*models.Day, error) { params := map[string]string{ "date": date, @@ -58,7 +59,7 @@ func (c *Client) GetFeedDay(ctx context.Context, date string) (*models.Day, erro return &result, nil } -// GetGeneratedPlaylists gets generated playlists +// GetGeneratedPlaylists gets generated playlists (GET /generated-playlists). func (c *Client) GetGeneratedPlaylists(ctx context.Context) ([]*models.GeneratedPlaylist, error) { var result []models.GeneratedPlaylist if err := c.request.Get(ctx, "/generated-playlists", nil, &result); err != nil { @@ -73,8 +74,7 @@ func (c *Client) GetGeneratedPlaylists(ctx context.Context) ([]*models.Generated return playlists, nil } -// GetLanding gets a landing page -// GET /landing3/{landingID} +// GetLanding gets a landing page by ID (GET /landing3/{landingID}). func (c *Client) GetLanding(ctx context.Context, landingID string) (*models.Landing, error) { params := map[string]string{ "landing_id": landingID, @@ -87,7 +87,7 @@ func (c *Client) GetLanding(ctx context.Context, landingID string) (*models.Land return &result, nil } -// GetLandingList gets a list of landings +// GetLandingList gets a list of landings (GET /landing3/list). func (c *Client) GetLandingList(ctx context.Context) (*models.LandingList, error) { var result models.LandingList if err := c.request.Get(ctx, "/landing3/list", nil, &result); err != nil { @@ -96,7 +96,7 @@ func (c *Client) GetLandingList(ctx context.Context) (*models.LandingList, error return &result, nil } -// GetLandingBlocks gets landing blocks by block IDs +// GetLandingBlocks gets landing blocks by block IDs (GET /landing3/blocks). func (c *Client) GetLandingBlocks(ctx context.Context, blockIDs []string) ([]*models.LandingBlock, error) { params := map[string]string{ "blocks": joinStrings(blockIDs, ","), diff --git a/internal/client/history.go b/internal/client/history.go index 9bdbbea..2aa7e07 100644 --- a/internal/client/history.go +++ b/internal/client/history.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetMusicHistory gets music history +// GetMusicHistory gets the user's music history (GET /music-history). func (c *Client) GetMusicHistory(ctx context.Context) (*models.MusicHistory, error) { var result models.MusicHistory if err := c.request.Get(ctx, "/music-history", nil, &result); err != nil { @@ -16,7 +17,7 @@ func (c *Client) GetMusicHistory(ctx context.Context) (*models.MusicHistory, err return &result, nil } -// GetMusicHistoryTabs gets music history tabs +// GetMusicHistoryTabs gets music history tabs (GET /music-history/tabs). func (c *Client) GetMusicHistoryTabs(ctx context.Context) ([]*models.MusicHistoryTab, error) { var result []models.MusicHistoryTab if err := c.request.Get(ctx, "/music-history/tabs", nil, &result); err != nil { @@ -31,7 +32,7 @@ func (c *Client) GetMusicHistoryTabs(ctx context.Context) ([]*models.MusicHistor return tabs, nil } -// GetMusicHistoryItems gets music history items +// GetMusicHistoryItems gets music history items for a tab (GET /music-history/items). func (c *Client) GetMusicHistoryItems(ctx context.Context, tabID string, page, pageSize int) (*models.MusicHistoryItems, error) { params := map[string]string{} if tabID != "" { diff --git a/internal/client/labels.go b/internal/client/labels.go index a4c4bc0..fe0c562 100644 --- a/internal/client/labels.go +++ b/internal/client/labels.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetLabels gets all labels +// GetLabels gets all labels (GET /labels). func (c *Client) GetLabels(ctx context.Context) ([]*models.Label, error) { var result []models.Label if err := c.request.Get(ctx, "/labels", nil, &result); err != nil { @@ -22,8 +23,7 @@ func (c *Client) GetLabels(ctx context.Context) ([]*models.Label, error) { return labels, nil } -// GetLabel gets a label by ID -// GET /labels/{labelID} +// GetLabel gets a label by ID (GET /labels/{labelID}). func (c *Client) GetLabel(ctx context.Context, labelID string) (*models.Label, error) { var result models.Label if err := c.request.Get(ctx, fmt.Sprintf("/labels/%s", labelID), nil, &result); err != nil { @@ -33,8 +33,7 @@ func (c *Client) GetLabel(ctx context.Context, labelID string) (*models.Label, e return &result, nil } -// GetLabelAlbums gets albums for a label -// GET /labels/{labelID}/albums +// GetLabelAlbums gets albums for a label (GET /labels/{labelID}/albums). func (c *Client) GetLabelAlbums(ctx context.Context, labelID string, page, pageSize int) (*models.LabelAlbums, error) { params := map[string]string{} if page > 0 { @@ -51,8 +50,7 @@ func (c *Client) GetLabelAlbums(ctx context.Context, labelID string, page, pageS return &result, nil } -// GetLabelArtists gets artists for a label -// GET /labels/{labelID}/artists +// GetLabelArtists gets artists for a label (GET /labels/{labelID}/artists). func (c *Client) GetLabelArtists(ctx context.Context, labelID string, page, pageSize int) (*models.LabelArtists, error) { params := map[string]string{} if page > 0 { diff --git a/internal/client/likes.go b/internal/client/likes.go index 71f05b0..3cc47d4 100644 --- a/internal/client/likes.go +++ b/internal/client/likes.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,8 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// LikeTrack likes a track -// POST /users/me/likes/tracks/add-multiple +// LikeTrack likes a track (POST /users/me/likes/tracks/add-multiple). func (c *Client) LikeTrack(ctx context.Context, trackID string) error { params := map[string]string{ "track-ids": trackID, @@ -17,8 +17,7 @@ func (c *Client) LikeTrack(ctx context.Context, trackID string) error { return c.request.Post(ctx, "/users/me/likes/tracks/add-multiple", params, &result) } -// UnlikeTrack unlikes a track -// POST /users/me/likes/tracks/remove +// UnlikeTrack unlikes a track (POST /users/me/likes/tracks/remove). func (c *Client) UnlikeTrack(ctx context.Context, trackID string) error { params := map[string]string{ "track-ids": trackID, @@ -27,8 +26,7 @@ func (c *Client) UnlikeTrack(ctx context.Context, trackID string) error { return c.request.Post(ctx, "/users/me/likes/tracks/remove", params, &result) } -// LikeAlbum likes an album -// POST /users/me/likes/albums/add-multiple +// LikeAlbum likes an album (POST /users/me/likes/albums/add-multiple). func (c *Client) LikeAlbum(ctx context.Context, albumID string) error { params := map[string]string{ "album-ids": albumID, @@ -37,8 +35,7 @@ func (c *Client) LikeAlbum(ctx context.Context, albumID string) error { return c.request.Post(ctx, "/users/me/likes/albums/add-multiple", params, &result) } -// UnlikeAlbum unlikes an album -// POST /users/me/likes/albums/remove +// UnlikeAlbum unlikes an album (POST /users/me/likes/albums/remove). func (c *Client) UnlikeAlbum(ctx context.Context, albumID string) error { params := map[string]string{ "album-ids": albumID, @@ -47,8 +44,7 @@ func (c *Client) UnlikeAlbum(ctx context.Context, albumID string) error { return c.request.Post(ctx, "/users/me/likes/albums/remove", params, &result) } -// LikeArtist likes an artist -// POST /users/me/likes/artists/add-multiple +// LikeArtist likes an artist (POST /users/me/likes/artists/add-multiple). func (c *Client) LikeArtist(ctx context.Context, artistID string) error { params := map[string]string{ "artist-ids": artistID, @@ -57,8 +53,7 @@ func (c *Client) LikeArtist(ctx context.Context, artistID string) error { return c.request.Post(ctx, "/users/me/likes/artists/add-multiple", params, &result) } -// UnlikeArtist unlikes an artist -// POST /users/me/likes/artists/remove +// UnlikeArtist unlikes an artist (POST /users/me/likes/artists/remove). func (c *Client) UnlikeArtist(ctx context.Context, artistID string) error { params := map[string]string{ "artist-ids": artistID, @@ -67,8 +62,7 @@ func (c *Client) UnlikeArtist(ctx context.Context, artistID string) error { return c.request.Post(ctx, "/users/me/likes/artists/remove", params, &result) } -// LikePlaylist likes a playlist -// POST /users/me/likes/playlists/add-multiple +// LikePlaylist likes a playlist (POST /users/me/likes/playlists/add-multiple). func (c *Client) LikePlaylist(ctx context.Context, kind int) error { params := map[string]string{ "playlist-ids": fmt.Sprintf("%d", kind), @@ -77,8 +71,7 @@ func (c *Client) LikePlaylist(ctx context.Context, kind int) error { return c.request.Post(ctx, "/users/me/likes/playlists/add-multiple", params, &result) } -// UnlikePlaylist unlikes a playlist -// POST /users/me/likes/playlists/remove +// UnlikePlaylist unlikes a playlist (POST /users/me/likes/playlists/remove). func (c *Client) UnlikePlaylist(ctx context.Context, kind int) error { params := map[string]string{ "playlist-ids": fmt.Sprintf("%d", kind), @@ -87,8 +80,7 @@ func (c *Client) UnlikePlaylist(ctx context.Context, kind int) error { return c.request.Post(ctx, "/users/me/likes/playlists/remove", params, &result) } -// GetLikedTracks gets user's liked tracks -// GET /users/me/likes/tracks +// GetLikedTracks gets the user's liked tracks (GET /users/me/likes/tracks). func (c *Client) GetLikedTracks(ctx context.Context) ([]*models.Track, error) { var result []models.Track if err := c.request.Get(ctx, "/users/me/likes/tracks", nil, &result); err != nil { @@ -103,8 +95,7 @@ func (c *Client) GetLikedTracks(ctx context.Context) ([]*models.Track, error) { return tracks, nil } -// GetLikedAlbums gets user's liked albums -// GET /users/me/likes/albums +// GetLikedAlbums gets the user's liked albums (GET /users/me/likes/albums). func (c *Client) GetLikedAlbums(ctx context.Context) ([]*models.Album, error) { var result []models.Album if err := c.request.Get(ctx, "/users/me/likes/albums", nil, &result); err != nil { @@ -119,8 +110,7 @@ func (c *Client) GetLikedAlbums(ctx context.Context) ([]*models.Album, error) { return albums, nil } -// GetLikedArtists gets user's liked artists -// GET /users/me/likes/artists +// GetLikedArtists gets the user's liked artists (GET /users/me/likes/artists). func (c *Client) GetLikedArtists(ctx context.Context) ([]*models.Artist, error) { var result []models.Artist if err := c.request.Get(ctx, "/users/me/likes/artists", nil, &result); err != nil { @@ -135,8 +125,7 @@ func (c *Client) GetLikedArtists(ctx context.Context) ([]*models.Artist, error) return artists, nil } -// GetLikedPlaylists gets user's liked playlists -// GET /users/me/likes/playlists +// GetLikedPlaylists gets the user's liked playlists (GET /users/me/likes/playlists). func (c *Client) GetLikedPlaylists(ctx context.Context) ([]*models.Playlist, error) { var result []models.Playlist if err := c.request.Get(ctx, "/users/me/likes/playlists", nil, &result); err != nil { diff --git a/internal/client/metatags.go b/internal/client/metatags.go index 1dbb4d2..04ccaf5 100644 --- a/internal/client/metatags.go +++ b/internal/client/metatags.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetMetatags gets all metatags +// GetMetatags gets all metatags (GET /metatags). func (c *Client) GetMetatags(ctx context.Context) ([]*models.Metatag, error) { var result []models.Metatag if err := c.request.Get(ctx, "/metatags", nil, &result); err != nil { @@ -22,7 +23,7 @@ func (c *Client) GetMetatags(ctx context.Context) ([]*models.Metatag, error) { return metatags, nil } -// GetMetatagTree gets metatag tree +// GetMetatagTree gets the metatag tree (GET /metatags/tree). func (c *Client) GetMetatagTree(ctx context.Context) (*models.MetatagTree, error) { var result models.MetatagTree if err := c.request.Get(ctx, "/metatags/tree", nil, &result); err != nil { @@ -31,7 +32,7 @@ func (c *Client) GetMetatagTree(ctx context.Context) (*models.MetatagTree, error return &result, nil } -// GetMetatagArtists gets artists for a metatag +// GetMetatagArtists gets artists for a metatag (GET /metatags/artists). func (c *Client) GetMetatagArtists(ctx context.Context, metatagID string, page, pageSize int) (*models.MetatagArtists, error) { params := map[string]string{ "metatag_id": metatagID, @@ -50,7 +51,7 @@ func (c *Client) GetMetatagArtists(ctx context.Context, metatagID string, page, return &result, nil } -// GetMetatagAlbums gets albums for a metatag +// GetMetatagAlbums gets albums for a metatag (GET /metatags/albums). func (c *Client) GetMetatagAlbums(ctx context.Context, metatagID string, page, pageSize int) (*models.MetatagAlbums, error) { params := map[string]string{ "metatag_id": metatagID, @@ -69,7 +70,7 @@ func (c *Client) GetMetatagAlbums(ctx context.Context, metatagID string, page, p return &result, nil } -// GetMetatagPlaylists gets playlists for a metatag +// GetMetatagPlaylists gets playlists for a metatag (GET /metatags/playlists). func (c *Client) GetMetatagPlaylists(ctx context.Context, metatagID string, page, pageSize int) (*models.MetatagPlaylists, error) { params := map[string]string{ "metatag_id": metatagID, @@ -88,7 +89,7 @@ func (c *Client) GetMetatagPlaylists(ctx context.Context, metatagID string, page return &result, nil } -// GetGenres gets all genres +// GetGenres gets all genres (GET /genres). func (c *Client) GetGenres(ctx context.Context) ([]*models.Genre, error) { var result []models.Genre if err := c.request.Get(ctx, "/genres", nil, &result); err != nil { @@ -103,7 +104,7 @@ func (c *Client) GetGenres(ctx context.Context) ([]*models.Genre, error) { return genres, nil } -// GetCharts gets charts +// GetCharts gets all charts (GET /charts). func (c *Client) GetCharts(ctx context.Context) ([]*models.Chart, error) { var result []models.Chart if err := c.request.Get(ctx, "/charts", nil, &result); err != nil { @@ -118,7 +119,7 @@ func (c *Client) GetCharts(ctx context.Context) ([]*models.Chart, error) { return charts, nil } -// GetChartInfo gets chart info +// GetChartInfo gets chart info for a chart ID (GET /charts/info). func (c *Client) GetChartInfo(ctx context.Context, chartID string) (*models.ChartInfo, error) { params := map[string]string{ "chart_id": chartID, @@ -131,7 +132,7 @@ func (c *Client) GetChartInfo(ctx context.Context, chartID string) (*models.Char return &result, nil } -// GetChartItems gets chart items +// GetChartItems gets chart items for a chart ID (GET /charts/items). func (c *Client) GetChartItems(ctx context.Context, chartID string, page, pageSize int) (*models.ChartItems, error) { params := map[string]string{ "chart_id": chartID, @@ -150,7 +151,7 @@ func (c *Client) GetChartItems(ctx context.Context, chartID string, page, pageSi return &result, nil } -// GetChartMenu gets chart menu +// GetChartMenu gets chart menu for a chart ID (GET /charts/menu). func (c *Client) GetChartMenu(ctx context.Context, chartID string) (*models.ChartInfoMenu, error) { params := map[string]string{ "chart_id": chartID, diff --git a/internal/client/pins.go b/internal/client/pins.go index 46fa014..1ae41ef 100644 --- a/internal/client/pins.go +++ b/internal/client/pins.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -6,7 +7,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetPins gets user's pins +// GetPins gets user's pins (GET /pins). func (c *Client) GetPins(ctx context.Context) (*models.PinsList, error) { var result models.PinsList if err := c.request.Get(ctx, "/pins", nil, &result); err != nil { @@ -15,7 +16,7 @@ func (c *Client) GetPins(ctx context.Context) (*models.PinsList, error) { return &result, nil } -// AddPin adds a pin +// AddPin adds a pin (POST /pins). func (c *Client) AddPin(ctx context.Context, pinType, entityID string) (*models.Pin, error) { params := map[string]string{ "type": pinType, @@ -29,7 +30,7 @@ func (c *Client) AddPin(ctx context.Context, pinType, entityID string) (*models. return &result, nil } -// RemovePin removes a pin +// RemovePin removes a pin by ID (DELETE /pins). func (c *Client) RemovePin(ctx context.Context, pinID string) error { params := map[string]string{ "pin_id": pinID, @@ -38,7 +39,7 @@ func (c *Client) RemovePin(ctx context.Context, pinID string) error { return c.request.Delete(ctx, "/pins", params, &result) } -// GetPresaves gets user's presaves +// GetPresaves gets user's presaves (GET /presaves). func (c *Client) GetPresaves(ctx context.Context) (*models.Presaves, error) { var result models.Presaves if err := c.request.Get(ctx, "/presaves", nil, &result); err != nil { diff --git a/internal/client/playlists.go b/internal/client/playlists.go index af4fb4d..ab1c804 100644 --- a/internal/client/playlists.go +++ b/internal/client/playlists.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -8,7 +9,8 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// GetPlaylists gets playlists by IDs (kinds) +// GetPlaylists gets playlists by their kind IDs (GET /playlists). +// Returns a slice of Playlist pointers, or nil if no kinds are provided. func (c *Client) GetPlaylists(ctx context.Context, kinds []int) ([]*models.Playlist, error) { if len(kinds) == 0 { return nil, nil @@ -40,7 +42,8 @@ func (c *Client) GetPlaylists(ctx context.Context, kinds []int) ([]*models.Playl return playlists, nil } -// GetPlaylist gets a single playlist by kind +// GetPlaylist gets a single playlist by kind using GetPlaylists. +// Returns an error if no playlist is found with the given kind. func (c *Client) GetPlaylist(ctx context.Context, kind int) (*models.Playlist, error) { playlists, err := c.GetPlaylists(ctx, []int{kind}) if err != nil { @@ -52,8 +55,7 @@ func (c *Client) GetPlaylist(ctx context.Context, kind int) (*models.Playlist, e return playlists[0], nil } -// GetUserPlaylists gets playlists for a user -// GET /users/{userID}/playlists +// GetUserPlaylists gets playlists for a user (GET /users/{userID}/playlists). func (c *Client) GetUserPlaylists(ctx context.Context, userID string) ([]*models.Playlist, error) { var result []models.Playlist if err := c.request.Get(ctx, fmt.Sprintf("/users/%s/playlists", userID), nil, &result); err != nil { @@ -68,7 +70,8 @@ func (c *Client) GetUserPlaylists(ctx context.Context, userID string) ([]*models return playlists, nil } -// CreatePlaylist creates a new playlist +// CreatePlaylist creates a new playlist (POST /users/me/playlists). +// The visibility parameter should be "public" or "private". func (c *Client) CreatePlaylist(ctx context.Context, title string, visibility string) (*models.Playlist, error) { params := map[string]string{ "title": title, @@ -83,7 +86,8 @@ func (c *Client) CreatePlaylist(ctx context.Context, title string, visibility st return &result, nil } -// EditPlaylist edits an existing playlist +// EditPlaylist edits an existing playlist (PUT /users/me/playlists). +// Only non-empty parameters are updated. func (c *Client) EditPlaylist(ctx context.Context, kind int, title, description, visibility string) (*models.Playlist, error) { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), @@ -106,7 +110,7 @@ func (c *Client) EditPlaylist(ctx context.Context, kind int, title, description, return &result, nil } -// DeletePlaylist deletes a playlist +// DeletePlaylist deletes a playlist (DELETE /users/me/playlists). func (c *Client) DeletePlaylist(ctx context.Context, kind int) error { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), @@ -115,7 +119,8 @@ func (c *Client) DeletePlaylist(ctx context.Context, kind int) error { return c.request.Delete(ctx, "/users/me/playlists", params, &result) } -// AddTracksToPlaylist adds tracks to a playlist +// AddTracksToPlaylist adds tracks to a playlist (POST /users/me/playlists/tracks). +// The revision parameter is the current playlist revision for optimistic concurrency. func (c *Client) AddTracksToPlaylist(ctx context.Context, kind int, trackIDs []string, revision int) (*models.Playlist, error) { if len(trackIDs) == 0 { return nil, utils.NewYandexMusicError("no tracks provided", utils.ErrBadRequest) @@ -143,7 +148,8 @@ func (c *Client) AddTracksToPlaylist(ctx context.Context, kind int, trackIDs []s return &result, nil } -// RemoveTracksFromPlaylist removes tracks from a playlist +// RemoveTracksFromPlaylist removes tracks from a playlist (DELETE /users/me/playlists/tracks). +// The revision parameter is the current playlist revision for optimistic concurrency. func (c *Client) RemoveTracksFromPlaylist(ctx context.Context, kind int, trackIDs []string, revision int) (*models.Playlist, error) { if len(trackIDs) == 0 { return nil, utils.NewYandexMusicError("no tracks provided", utils.ErrBadRequest) @@ -171,7 +177,8 @@ func (c *Client) RemoveTracksFromPlaylist(ctx context.Context, kind int, trackID return &result, nil } -// ReorderPlaylistTracks reorders tracks in a playlist +// ReorderPlaylistTracks reorders tracks in a playlist (PUT /users/me/playlists/tracks/reorder). +// The from and to parameters specify the position range to move. func (c *Client) ReorderPlaylistTracks(ctx context.Context, kind int, from, to, revision int) (*models.Playlist, error) { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), @@ -188,7 +195,7 @@ func (c *Client) ReorderPlaylistTracks(ctx context.Context, kind int, from, to, return &result, nil } -// GetPlaylistRecommendations gets playlist recommendations +// GetPlaylistRecommendations gets playlist recommendations based on a playlist kind (GET /playlists/recommendations). func (c *Client) GetPlaylistRecommendations(ctx context.Context, kind int) ([]*models.Playlist, error) { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), diff --git a/internal/client/queue.go b/internal/client/queue.go index 7e6c9ce..a9c046b 100644 --- a/internal/client/queue.go +++ b/internal/client/queue.go @@ -17,7 +17,8 @@ func (c *Client) GetQueue(ctx context.Context) (*models.Queue, error) { return &result, nil } -// CreateQueue creates a new queue +// CreateQueue creates a new playback queue (POST /queues). +// The queueType parameter specifies the type of queue (e.g., "radio", "album", "playlist"). func (c *Client) CreateQueue(ctx context.Context, trackID string, queueType string) (*models.Queue, error) { params := map[string]string{ "track_id": trackID, @@ -32,8 +33,7 @@ func (c *Client) CreateQueue(ctx context.Context, trackID string, queueType stri return &result, nil } -// GetQueueItem gets a queue item -// GET /queues/{queue_id} +// GetQueueItem gets a queue item by queue ID (GET /queues/{queue_id}). func (c *Client) GetQueueItem(ctx context.Context, queueID string) (*models.QueueItem, error) { var result models.QueueItem if err := c.request.Get(ctx, fmt.Sprintf("/queues/%s", queueID), nil, &result); err != nil { @@ -43,8 +43,7 @@ func (c *Client) GetQueueItem(ctx context.Context, queueID string) (*models.Queu return &result, nil } -// AddToQueue adds a track to the queue -// POST /queues/{queue_id}/add +// AddToQueue adds a track to the queue at the given position (POST /queues/{queue_id}/add). func (c *Client) AddToQueue(ctx context.Context, queueID, trackID string, position int) (*models.Queue, error) { params := map[string]string{ "track_id": trackID, @@ -59,8 +58,7 @@ func (c *Client) AddToQueue(ctx context.Context, queueID, trackID string, positi return &result, nil } -// RemoveFromQueue removes a track from the queue -// DELETE /queues/{queue_id}/remove +// RemoveFromQueue removes a track from the queue (DELETE /queues/{queue_id}/remove). func (c *Client) RemoveFromQueue(ctx context.Context, queueID, trackID string) (*models.Queue, error) { params := map[string]string{ "track_id": trackID, @@ -74,8 +72,7 @@ func (c *Client) RemoveFromQueue(ctx context.Context, queueID, trackID string) ( return &result, nil } -// ReorderQueue reorders the queue -// PUT /queues/{queue_id}/reorder +// ReorderQueue reorders items in the queue from one position to another (PUT /queues/{queue_id}/reorder). func (c *Client) ReorderQueue(ctx context.Context, queueID string, from, to int) (*models.Queue, error) { params := map[string]string{ "from": fmt.Sprintf("%d", from), @@ -90,15 +87,13 @@ func (c *Client) ReorderQueue(ctx context.Context, queueID string, from, to int) return &result, nil } -// ClearQueue clears the queue -// DELETE /queues/{queue_id}/clear +// ClearQueue clears the queue (DELETE /queues/{queue_id}/clear). func (c *Client) ClearQueue(ctx context.Context, queueID string) error { var result map[string]any return c.request.Delete(ctx, fmt.Sprintf("/queues/%s/clear", queueID), nil, &result) } -// NextTrack moves to the next track in the queue -// POST /queues/{queue_id}/next +// NextTrack moves to the next track in the queue (POST /queues/{queue_id}/next). func (c *Client) NextTrack(ctx context.Context, queueID string) (*models.Queue, error) { var result models.Queue if err := c.request.Post(ctx, fmt.Sprintf("/queues/%s/next", queueID), nil, &result); err != nil { @@ -108,8 +103,7 @@ func (c *Client) NextTrack(ctx context.Context, queueID string) (*models.Queue, return &result, nil } -// PreviousTrack moves to the previous track in the queue -// POST /queues/{queue_id}/prev +// PreviousTrack moves to the previous track in the queue (POST /queues/{queue_id}/prev). func (c *Client) PreviousTrack(ctx context.Context, queueID string) (*models.Queue, error) { var result models.Queue if err := c.request.Post(ctx, fmt.Sprintf("/queues/%s/prev", queueID), nil, &result); err != nil { @@ -119,8 +113,8 @@ func (c *Client) PreviousTrack(ctx context.Context, queueID string) (*models.Que return &result, nil } -// Seek seeks to a specific position in the current track (in milliseconds) -// POST /queues/{queue_id}/seek +// Seek seeks to a specific position in the current track (POST /queues/{queue_id}/seek). +// The positionMs parameter is the position in milliseconds. func (c *Client) Seek(ctx context.Context, queueID string, positionMs int) (*models.Queue, error) { params := map[string]string{ "position": fmt.Sprintf("%d", positionMs), @@ -134,9 +128,8 @@ func (c *Client) Seek(ctx context.Context, queueID string, positionMs int) (*mod return &result, nil } -// SetRepeatMode sets the repeat mode for the queue -// mode can be "off", "one", or "all" -// POST /queues/{queue_id}/repeat +// SetRepeatMode sets the repeat mode for the queue (POST /queues/{queue_id}/repeat). +// The mode parameter can be "off", "one", or "all". func (c *Client) SetRepeatMode(ctx context.Context, queueID, mode string) (*models.Queue, error) { params := map[string]string{ "mode": mode, @@ -150,8 +143,7 @@ func (c *Client) SetRepeatMode(ctx context.Context, queueID, mode string) (*mode return &result, nil } -// SetShuffle enables or disables shuffle for the queue -// POST /queues/{queue_id}/shuffle +// SetShuffle enables or disables shuffle for the queue (POST /queues/{queue_id}/shuffle). func (c *Client) SetShuffle(ctx context.Context, queueID string, enabled bool) (*models.Queue, error) { params := map[string]string{ "enabled": fmt.Sprintf("%t", enabled), @@ -165,8 +157,8 @@ func (c *Client) SetShuffle(ctx context.Context, queueID string, enabled bool) ( return &result, nil } -// SetVolume sets the volume for the queue (0-100) -// POST /queues/{queue_id}/volume +// SetVolume sets the volume for the queue (POST /queues/{queue_id}/volume). +// The volume parameter should be between 0 and 100. func (c *Client) SetVolume(ctx context.Context, queueID string, volume int) (*models.Queue, error) { params := map[string]string{ "volume": fmt.Sprintf("%d", volume), @@ -180,8 +172,7 @@ func (c *Client) SetVolume(ctx context.Context, queueID string, volume int) (*mo return &result, nil } -// GetCurrentTrack gets the currently playing track from the queue -// GET /queues/{queue_id}/current +// GetCurrentTrack gets the currently playing track from the queue (GET /queues/{queue_id}/current). func (c *Client) GetCurrentTrack(ctx context.Context, queueID string) (*models.QueueItem, error) { var result models.QueueItem if err := c.request.Get(ctx, fmt.Sprintf("/queues/%s/current", queueID), nil, &result); err != nil { @@ -191,8 +182,7 @@ func (c *Client) GetCurrentTrack(ctx context.Context, queueID string) (*models.Q return &result, nil } -// GetQueueHistory gets the queue history (recently played tracks) -// GET /queues/{queue_id}/history +// GetQueueHistory gets the queue history (recently played tracks) (GET /queues/{queue_id}/history). func (c *Client) GetQueueHistory(ctx context.Context, queueID string, limit int) ([]*models.QueueItem, error) { params := map[string]string{ "limit": fmt.Sprintf("%d", limit), @@ -211,7 +201,7 @@ func (c *Client) GetQueueHistory(ctx context.Context, queueID string, limit int) return items, nil } -// GetPlayContexts gets play contexts +// GetPlayContexts gets play contexts (GET /play-contexts). func (c *Client) GetPlayContexts(ctx context.Context) ([]*models.PlayContext, error) { var result []models.PlayContext if err := c.request.Get(ctx, "/play-contexts", nil, &result); err != nil { @@ -226,7 +216,7 @@ func (c *Client) GetPlayContexts(ctx context.Context) ([]*models.PlayContext, er return contexts, nil } -// GetPlayContextsData gets play contexts data +// GetPlayContextsData gets play contexts data (GET /play-contexts/data). func (c *Client) GetPlayContextsData(ctx context.Context) (*models.PlayContextsData, error) { var result models.PlayContextsData if err := c.request.Get(ctx, "/play-contexts/data", nil, &result); err != nil { diff --git a/internal/client/radio.go b/internal/client/radio.go index a24952e..e29fb99 100644 --- a/internal/client/radio.go +++ b/internal/client/radio.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetRadioStations gets radio stations +// GetRadioStations gets radio stations (GET /radio/stations). func (c *Client) GetRadioStations(ctx context.Context) ([]*models.RadioStation, error) { var result []models.RadioStation if err := c.request.Get(ctx, "/radio/stations", nil, &result); err != nil { @@ -22,8 +23,7 @@ func (c *Client) GetRadioStations(ctx context.Context) ([]*models.RadioStation, return stations, nil } -// GetRadioStation gets a radio station by ID -// GET /rotor/station/{stationID}/info +// GetRadioStation gets a radio station by ID (GET /rotor/station/{stationID}/info). func (c *Client) GetRadioStation(ctx context.Context, stationID string) (*models.RadioStation, error) { var result models.RadioStation if err := c.request.Get(ctx, fmt.Sprintf("/rotor/station/%s/info", stationID), nil, &result); err != nil { @@ -33,8 +33,7 @@ func (c *Client) GetRadioStation(ctx context.Context, stationID string) (*models return &result, nil } -// GetStationTracks gets tracks for a radio station -// GET /rotor/station/{stationID}/tracks +// GetStationTracks gets tracks for a radio station (GET /rotor/station/{stationID}/tracks). func (c *Client) GetStationTracks(ctx context.Context, stationID string, limit int) (*models.StationTracksResult, error) { params := map[string]string{} if limit > 0 { @@ -48,7 +47,7 @@ func (c *Client) GetStationTracks(ctx context.Context, stationID string, limit i return &result, nil } -// GetRotorStations gets rotor stations (generative) +// GetRotorStations gets rotor stations (generative stations) (GET /rotor/stations). func (c *Client) GetRotorStations(ctx context.Context) ([]*models.RotorStation, error) { var result []models.RotorStation if err := c.request.Get(ctx, "/rotor/stations", nil, &result); err != nil { @@ -63,8 +62,7 @@ func (c *Client) GetRotorStations(ctx context.Context) ([]*models.RotorStation, return stations, nil } -// GetRotorStation gets a rotor station by ID -// GET /rotor/station/{stationID}/info +// GetRotorStation gets a rotor station by ID (GET /rotor/station/{stationID}/info). func (c *Client) GetRotorStation(ctx context.Context, stationID string) (*models.RotorStation, error) { var result models.RotorStation if err := c.request.Get(ctx, fmt.Sprintf("/rotor/station/%s/info", stationID), nil, &result); err != nil { @@ -74,8 +72,7 @@ func (c *Client) GetRotorStation(ctx context.Context, stationID string) (*models return &result, nil } -// GetRotorStationTracks gets tracks for a rotor station -// GET /rotor/station/{stationID}/tracks +// GetRotorStationTracks gets tracks for a rotor station (GET /rotor/station/{stationID}/tracks). func (c *Client) GetRotorStationTracks(ctx context.Context, stationID string, limit int) (*models.RotorStationTracksResult, error) { params := map[string]string{} if limit > 0 { @@ -89,8 +86,7 @@ func (c *Client) GetRotorStationTracks(ctx context.Context, stationID string, li return &result, nil } -// StartRotorSession starts a rotor session -// POST /rotor/station/{stationID}/session/start +// StartRotorSession starts a rotor session (POST /rotor/station/{stationID}/session/start). func (c *Client) StartRotorSession(ctx context.Context, stationID string) (*models.RotorSession, error) { var result models.RotorSession if err := c.request.Post(ctx, fmt.Sprintf("/rotor/station/%s/session/start", stationID), nil, &result); err != nil { @@ -100,8 +96,7 @@ func (c *Client) StartRotorSession(ctx context.Context, stationID string) (*mode return &result, nil } -// GetRotorSession gets rotor session info -// GET /rotor/session?session_id={sessionID} +// GetRotorSession gets rotor session info by session ID (GET /rotor/session). func (c *Client) GetRotorSession(ctx context.Context, sessionID string) (*models.RotorSession, error) { params := map[string]string{ "session_id": sessionID, @@ -115,8 +110,8 @@ func (c *Client) GetRotorSession(ctx context.Context, sessionID string) (*models return &result, nil } -// RotorSessionFeedback sends feedback for a rotor session track -// POST /rotor/station/{stationID}/feedback +// RotorSessionFeedback sends feedback for a rotor session track (POST /rotor/station/{stationID}/feedback). +// The feedbackType parameter can be "like", "dislike", or "skip". func (c *Client) RotorSessionFeedback(ctx context.Context, sessionID, trackID, feedbackType string) error { params := map[string]string{ "track_id": trackID, diff --git a/internal/client/request.go b/internal/client/request.go index 49a4653..53d941d 100644 --- a/internal/client/request.go +++ b/internal/client/request.go @@ -13,7 +13,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// Default values +// Default values for the Yandex Music API client. const ( DefaultBaseURL = "https://api.music.yandex.net" DefaultTimeout = 5 * time.Second @@ -21,7 +21,7 @@ const ( DefaultClientHeader = "YandexMusicAndroid/24023621" ) -// RequestConfig holds configuration for the request client +// RequestConfig holds configuration for the request client. type RequestConfig struct { BaseURL string Token string @@ -36,14 +36,16 @@ type RequestConfig struct { OnSchemaMismatch utils.SchemaMismatchHandler } -// Request handles HTTP requests to Yandex Music API +// Request handles HTTP requests to the Yandex Music API. +// It manages the HTTP client, authentication headers, and request signing. type Request struct { config RequestConfig client *http.Client schemaTracker *utils.SchemaMismatchTracker } -// NewRequest creates a new Request instance +// NewRequest creates a new Request instance with the given configuration. +// It sets up the HTTP client, default headers, and authentication if a token is provided. func NewRequest(config RequestConfig) *Request { if config.BaseURL == "" { config.BaseURL = DefaultBaseURL @@ -92,7 +94,8 @@ func NewRequest(config RequestConfig) *Request { return r } -// SetToken updates the authorization token +// SetToken updates the authorization token used for API requests. +// When a token is provided, it sets the Authorization header to "OAuth ". func (r *Request) SetToken(token string) { r.config.Token = token if token != "" { @@ -102,33 +105,38 @@ func (r *Request) SetToken(token string) { } } -// SetLanguage sets the Accept-Language header +// SetLanguage sets the Accept-Language header for API requests. func (r *Request) SetLanguage(lang string) { r.config.Language = lang r.config.Headers["Accept-Language"] = lang } -// Get performs a GET request +// Get performs a GET request to the given path with query parameters. +// The response is unmarshaled into the result pointer. func (r *Request) Get(ctx context.Context, path string, params map[string]string, result any) error { return r.doRequest(ctx, "GET", path, params, nil, result) } -// Post performs a POST request +// Post performs a POST request to the given path with a JSON body. +// The response is unmarshaled into the result pointer. func (r *Request) Post(ctx context.Context, path string, body any, result any) error { return r.doRequest(ctx, "POST", path, nil, body, result) } -// Put performs a PUT request +// Put performs a PUT request to the given path with a JSON body. +// The response is unmarshaled into the result pointer. func (r *Request) Put(ctx context.Context, path string, body any, result any) error { return r.doRequest(ctx, "PUT", path, nil, body, result) } -// Delete performs a DELETE request +// Delete performs a DELETE request to the given path with an optional JSON body. +// The response is unmarshaled into the result pointer. func (r *Request) Delete(ctx context.Context, path string, body any, result any) error { return r.doRequest(ctx, "DELETE", path, nil, body, result) } -// doRequest performs the actual HTTP request +// doRequest performs the actual HTTP request to the Yandex Music API. +// It handles URL building, request signing, response parsing, and error handling. func (r *Request) doRequest(ctx context.Context, method, path string, params map[string]string, body any, result any) error { // Build URL fullURL := r.config.BaseURL + path @@ -209,7 +217,7 @@ func (r *Request) doRequest(ctx context.Context, method, path string, params map return nil } -// handleErrorResponse handles HTTP error responses +// handleErrorResponse handles HTTP error responses by mapping status codes to typed errors. func (r *Request) handleErrorResponse(statusCode int, body []byte) error { var msg string apiResp, err := utils.DeJSON(body) @@ -235,7 +243,8 @@ func (r *Request) handleErrorResponse(statusCode int, body []byte) error { } } -// Download downloads a file from a URL +// Download downloads a file from the given URL and returns the raw response body. +// It is used for downloading track files and lyrics text. func (r *Request) Download(ctx context.Context, urlStr string) ([]byte, error) { req, err := http.NewRequestWithContext(ctx, "GET", urlStr, nil) if err != nil { diff --git a/internal/client/search.go b/internal/client/search.go index 38fcc57..566c627 100644 --- a/internal/client/search.go +++ b/internal/client/search.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -7,7 +8,8 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// Search performs a multi-type search +// Search performs a multi-type search (GET /search). +// The searchType parameter specifies what to search for (e.g., "track", "album", "artist"). func (c *Client) Search(ctx context.Context, query string, searchType string, page, pageSize int) (*models.SearchResult, error) { params := map[string]string{ "text": query, @@ -46,7 +48,7 @@ func (c *Client) Search(ctx context.Context, query string, searchType string, pa return &result, nil } -// SearchTracks searches for tracks +// SearchTracks searches for tracks using Search with type "track". func (c *Client) SearchTracks(ctx context.Context, query string, page, pageSize int) (*models.SearchTracksResult, error) { result, err := c.Search(ctx, query, "track", page, pageSize) if err != nil { @@ -55,7 +57,7 @@ func (c *Client) SearchTracks(ctx context.Context, query string, page, pageSize return result.Tracks, nil } -// SearchAlbums searches for albums +// SearchAlbums searches for albums using Search with type "album". func (c *Client) SearchAlbums(ctx context.Context, query string, page, pageSize int) (*models.SearchAlbumsResult, error) { result, err := c.Search(ctx, query, "album", page, pageSize) if err != nil { @@ -64,7 +66,7 @@ func (c *Client) SearchAlbums(ctx context.Context, query string, page, pageSize return result.Albums, nil } -// SearchArtists searches for artists +// SearchArtists searches for artists using Search with type "artist". func (c *Client) SearchArtists(ctx context.Context, query string, page, pageSize int) (*models.SearchArtistsResult, error) { result, err := c.Search(ctx, query, "artist", page, pageSize) if err != nil { @@ -73,7 +75,7 @@ func (c *Client) SearchArtists(ctx context.Context, query string, page, pageSize return result.Artists, nil } -// SearchPlaylists searches for playlists +// SearchPlaylists searches for playlists using Search with type "playlist". func (c *Client) SearchPlaylists(ctx context.Context, query string, page, pageSize int) (*models.SearchPlaylistsResult, error) { result, err := c.Search(ctx, query, "playlist", page, pageSize) if err != nil { @@ -82,7 +84,7 @@ func (c *Client) SearchPlaylists(ctx context.Context, query string, page, pageSi return result.Playlists, nil } -// SearchVideos searches for videos +// SearchVideos searches for videos using Search with type "video". func (c *Client) SearchVideos(ctx context.Context, query string, page, pageSize int) (*models.SearchVideosResult, error) { result, err := c.Search(ctx, query, "video", page, pageSize) if err != nil { @@ -91,7 +93,7 @@ func (c *Client) SearchVideos(ctx context.Context, query string, page, pageSize return result.Videos, nil } -// SearchUsers searches for users +// SearchUsers searches for users using Search with type "user". func (c *Client) SearchUsers(ctx context.Context, query string, page, pageSize int) (*models.SearchUsersResult, error) { result, err := c.Search(ctx, query, "user", page, pageSize) if err != nil { @@ -100,7 +102,7 @@ func (c *Client) SearchUsers(ctx context.Context, query string, page, pageSize i return result.Users, nil } -// SearchSuggestions gets search suggestions +// SearchSuggestions gets search suggestions for a query (GET /search/suggest?type=suggest). func (c *Client) SearchSuggestions(ctx context.Context, query string) ([]string, error) { params := map[string]string{ "text": query, @@ -116,7 +118,7 @@ func (c *Client) SearchSuggestions(ctx context.Context, query string) ([]string, return result.Suggestions, nil } -// SearchBanners gets search banners +// SearchBanners gets search banners for a query (GET /search/banner?type=banner). func (c *Client) SearchBanners(ctx context.Context, query string) ([]models.SearchBanner, error) { params := map[string]string{ "text": query, @@ -132,7 +134,7 @@ func (c *Client) SearchBanners(ctx context.Context, query string) ([]models.Sear return result.Banners, nil } -// SearchTags gets search tags +// SearchTags gets search tags for a query (GET /search/tag?type=tag). func (c *Client) SearchTags(ctx context.Context, query string) ([]models.Tag, error) { params := map[string]string{ "text": query, diff --git a/internal/client/settings.go b/internal/client/settings.go index 328364b..8e30a49 100644 --- a/internal/client/settings.go +++ b/internal/client/settings.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -6,7 +7,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" ) -// GetSettings gets user settings +// GetSettings gets user settings (GET /account/settings). func (c *Client) GetSettings(ctx context.Context) (*models.AccountSettings, error) { var result models.AccountSettings if err := c.request.Get(ctx, "/account/settings", nil, &result); err != nil { @@ -15,7 +16,7 @@ func (c *Client) GetSettings(ctx context.Context) (*models.AccountSettings, erro return &result, nil } -// UpdateSettings updates user settings +// UpdateSettings updates user settings (PUT /account/settings). func (c *Client) UpdateSettings(ctx context.Context, settings *models.AccountSettings) (*models.AccountSettings, error) { var result models.AccountSettings if err := c.request.Put(ctx, "/account/settings", settings, &result); err != nil { @@ -24,7 +25,7 @@ func (c *Client) UpdateSettings(ctx context.Context, settings *models.AccountSet return &result, nil } -// GetExperiments gets experiments +// GetExperiments gets experiments (GET /experiments). func (c *Client) GetExperiments(ctx context.Context) (*models.Experiments, error) { var result models.Experiments if err := c.request.Get(ctx, "/experiments", nil, &result); err != nil { @@ -33,7 +34,7 @@ func (c *Client) GetExperiments(ctx context.Context) (*models.Experiments, error return &result, nil } -// GetExperimentDetails gets experiment details +// GetExperimentDetails gets experiment details for the given experiment ID (GET /experiments/details). func (c *Client) GetExperimentDetails(ctx context.Context, experimentID string) (*models.ExperimentDetail, error) { params := map[string]string{ "experiment_id": experimentID, @@ -45,7 +46,7 @@ func (c *Client) GetExperimentDetails(ctx context.Context, experimentID string) return &result, nil } -// GetPermissions gets user permissions +// GetPermissions gets user permissions (GET /permissions). func (c *Client) GetPermissions(ctx context.Context) (*models.Permissions, error) { var result models.Permissions if err := c.request.Get(ctx, "/permissions", nil, &result); err != nil { @@ -54,7 +55,7 @@ func (c *Client) GetPermissions(ctx context.Context) (*models.Permissions, error return &result, nil } -// GetPermissionAlerts gets permission alerts +// GetPermissionAlerts gets permission alerts (GET /permission-alerts). func (c *Client) GetPermissionAlerts(ctx context.Context) (*models.PermissionAlerts, error) { var result models.PermissionAlerts if err := c.request.Get(ctx, "/permission-alerts", nil, &result); err != nil { @@ -63,7 +64,7 @@ func (c *Client) GetPermissionAlerts(ctx context.Context) (*models.PermissionAle return &result, nil } -// GetContentRestrictions gets content restrictions +// GetContentRestrictions gets content restrictions (GET /content-restrictions). func (c *Client) GetContentRestrictions(ctx context.Context) (*models.ContentRestrictions, error) { var result models.ContentRestrictions if err := c.request.Get(ctx, "/content-restrictions", nil, &result); err != nil { diff --git a/internal/client/supplements.go b/internal/client/supplements.go index cf4bc9b..41be01b 100644 --- a/internal/client/supplements.go +++ b/internal/client/supplements.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -9,8 +10,7 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// GetTrackSupplement gets supplement for a track -// GET /tracks/{track_id}/supplement +// GetTrackSupplement gets supplement for a track (GET /tracks/{track_id}/supplement). func (c *Client) GetTrackSupplement(ctx context.Context, trackID string) (*models.Supplement, error) { path := fmt.Sprintf("/tracks/%s/supplement", trackID) @@ -21,8 +21,9 @@ func (c *Client) GetTrackSupplement(ctx context.Context, trackID string) (*model return &result, nil } -// GetTrackLyrics gets lyrics for a track (new endpoint with signing) -// GET /tracks/{track_id}/lyrics +// GetTrackLyrics gets lyrics for a track (GET /tracks/{track_id}/lyrics). +// The format parameter specifies the lyrics format (e.g., "TEXT" or "LRC"). +// The request is signed using the default signing key. func (c *Client) GetTrackLyrics(ctx context.Context, trackID string, format string) (*models.TrackLyrics, error) { path := fmt.Sprintf("/tracks/%s/lyrics", trackID) @@ -42,7 +43,7 @@ func (c *Client) GetTrackLyrics(ctx context.Context, trackID string, format stri return &result, nil } -// GetTrackLyricsText fetches the full lyrics text from the download URL +// GetTrackLyricsText fetches the full lyrics text from the download URL provided in TrackLyrics. func (c *Client) GetTrackLyricsText(ctx context.Context, trackLyrics *models.TrackLyrics) (string, error) { data, err := c.request.Download(ctx, trackLyrics.DownloadURL) if err != nil { @@ -51,8 +52,7 @@ func (c *Client) GetTrackLyricsText(ctx context.Context, trackLyrics *models.Tra return string(data), nil } -// GetLyrics gets lyrics info for a track (legacy endpoint) -// GET /tracks/lyrics?track_id={track_id} +// GetLyrics gets lyrics info for a track using the legacy endpoint (GET /tracks/lyrics). func (c *Client) GetLyrics(ctx context.Context, trackID string) (*models.LyricsInfo, error) { params := map[string]string{ "track_id": trackID, @@ -65,8 +65,7 @@ func (c *Client) GetLyrics(ctx context.Context, trackID string) (*models.LyricsI return &result, nil } -// GetVideoSupplement gets video supplement for a track (legacy endpoint) -// GET /tracks/video-supplement?track_id={track_id} +// GetVideoSupplement gets video supplement for a track using the legacy endpoint (GET /tracks/video-supplement). func (c *Client) GetVideoSupplement(ctx context.Context, trackID string) (*models.VideoSupplement, error) { params := map[string]string{ "track_id": trackID, @@ -79,44 +78,43 @@ func (c *Client) GetVideoSupplement(ctx context.Context, trackID string) (*model return &result, nil } -// GetLyricsByTrackID is an alias for GetTrackLyrics for backward compatibility -// GET /tracks/{track_id}/lyrics +// GetLyricsByTrackID is an alias for GetTrackLyrics for backward compatibility (GET /tracks/{track_id}/lyrics). func (c *Client) GetLyricsByTrackID(ctx context.Context, trackID string, format string) (*models.TrackLyrics, error) { return c.GetTrackLyrics(ctx, trackID, format) } -// LyricsFormat represents the lyrics format +// LyricsFormat represents the lyrics format. type LyricsFormat string const ( - // LyricsFormatText is plain text format + // LyricsFormatText is plain text lyrics format. LyricsFormatText LyricsFormat = "TEXT" - // LyricsFormatLRC is LRC format with timestamps + // LyricsFormatLRC is LRC format lyrics with timestamps. LyricsFormatLRC LyricsFormat = "LRC" ) -// GetTrackLyricsWithOptions gets lyrics with options +// GetTrackLyricsWithOptions gets lyrics with options using a LyricsFormat value. func (c *Client) GetTrackLyricsWithOptions(ctx context.Context, trackID string, format LyricsFormat) (*models.TrackLyrics, error) { return c.GetTrackLyrics(ctx, trackID, string(format)) } -// SupplementOptions holds options for supplement requests +// SupplementOptions holds options for supplement requests. type SupplementOptions struct { TrackID string } -// GetSupplement gets track supplement with options +// GetSupplement gets track supplement with options. func (c *Client) GetSupplement(ctx context.Context, opts SupplementOptions) (*models.Supplement, error) { return c.GetTrackSupplement(ctx, opts.TrackID) } -// LyricsOptions holds options for lyrics requests +// LyricsOptions holds options for lyrics requests. type LyricsOptions struct { TrackID string Format LyricsFormat } -// GetLyricsWithOptions gets track lyrics with options +// GetLyricsWithOptions gets track lyrics with options. func (c *Client) GetLyricsWithOptions(ctx context.Context, opts LyricsOptions) (*models.TrackLyrics, error) { format := string(opts.Format) if format == "" { @@ -125,13 +123,14 @@ func (c *Client) GetLyricsWithOptions(ctx context.Context, opts LyricsOptions) ( return c.GetTrackLyrics(ctx, opts.TrackID, format) } -// Sign represents a request signature +// Sign represents a request signature for signed API requests. type Sign struct { Timestamp int64 Value string } -// GetSignRequest creates a signature for a track request (exported for external use) +// GetSignRequest creates a signature for a track request (exported for external use). +// It delegates to utils.GetSignRequest with the default signing key. func GetSignRequest(trackID string) Sign { h := utils.GetSignRequest(trackID, utils.DefaultSignKey) diff --git a/internal/client/tracks.go b/internal/client/tracks.go index d9dedd9..9c28cd4 100644 --- a/internal/client/tracks.go +++ b/internal/client/tracks.go @@ -1,3 +1,4 @@ +// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( @@ -8,7 +9,8 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// GetTracks gets tracks by IDs +// GetTracks gets tracks by their IDs (GET /tracks). +// Returns a slice of Track pointers, or nil if no IDs are provided. func (c *Client) GetTracks(ctx context.Context, trackIDs []string) ([]*models.Track, error) { if len(trackIDs) == 0 { return nil, nil @@ -31,7 +33,8 @@ func (c *Client) GetTracks(ctx context.Context, trackIDs []string) ([]*models.Tr return tracks, nil } -// GetTrack gets a single track by ID +// GetTrack gets a single track by ID using GetTracks. +// Returns an error if no track is found with the given ID. func (c *Client) GetTrack(ctx context.Context, trackID string) (*models.Track, error) { tracks, err := c.GetTracks(ctx, []string{trackID}) if err != nil { @@ -43,7 +46,8 @@ func (c *Client) GetTrack(ctx context.Context, trackID string) (*models.Track, e return tracks[0], nil } -// GetTrackDownloadInfo gets download info for a track +// GetTrackDownloadInfo gets download info for a track (GET /tracks/{track_id}/download-info). +// The quality parameter specifies the desired audio quality (e.g., "mp3"). func (c *Client) GetTrackDownloadInfo(ctx context.Context, trackID, quality string) ([]models.DownloadInfo, error) { // This requires signing - use the sign utility // For now, return basic implementation @@ -58,7 +62,8 @@ func (c *Client) GetTrackDownloadInfo(ctx context.Context, trackID, quality stri return result, nil } -// DownloadTrack downloads a track +// DownloadTrack downloads a track by ID. +// It first fetches download info, finds a matching format/bitrate, then downloads the file content. func (c *Client) DownloadTrack(ctx context.Context, trackID, format string, bitrate int) ([]byte, error) { info, err := c.GetTrackDownloadInfo(ctx, trackID, format) if err != nil { @@ -85,12 +90,12 @@ func (c *Client) DownloadTrack(ctx context.Context, trackID, format string, bitr return c.request.Download(ctx, url) } -// SearchResult represents search results +// SearchResult represents search results containing tracks. type SearchResult struct { Tracks *SearchTracksResult `json:"tracks"` } -// SearchTracksResult represents track search results +// SearchTracksResult represents track search results with total count and results list. type SearchTracksResult struct { Total int `json:"total"` Results []models.Track `json:"results"` diff --git a/internal/models/account.go b/internal/models/account.go index 06e614f..b5a753c 100644 --- a/internal/models/account.go +++ b/internal/models/account.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// AccountSettings represents account settings +// AccountSettings represents account settings from the Yandex Music API. type AccountSettings struct { BaseModel Language string `json:"language"` @@ -26,7 +27,7 @@ type AccountSettings struct { DownloadOnWifiOnly bool `json:"download_on_wifi_only"` } -// DeJSON deserializes AccountSettings from JSON +// DeJSON deserializes AccountSettings from JSON data. func (a *AccountSettings) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -90,7 +91,7 @@ func (a *AccountSettings) DeJSON(data []byte, c ClientInterface) (Model, error) return settings, nil } -// DeList deserializes a list of AccountSettings +// DeList deserializes a list of AccountSettings from JSON data. func (a *AccountSettings) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -108,7 +109,7 @@ func (a *AccountSettings) DeList(data []byte, c ClientInterface) ([]Model, error return result, nil } -// Subscription represents subscription info +// Subscription represents subscription info. type Subscription struct { BaseModel ID string `json:"id"` @@ -127,7 +128,7 @@ type Subscription struct { TrialUsed bool `json:"trial_used"` } -// DeJSON deserializes Subscription from JSON +// DeJSON deserializes Subscription from JSON data. func (s *Subscription) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -182,7 +183,7 @@ func (s *Subscription) DeJSON(data []byte, c ClientInterface) (Model, error) { return sub, nil } -// DeList deserializes a list of Subscriptions +// DeList deserializes a list of Subscriptions from JSON data. func (s *Subscription) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -200,7 +201,7 @@ func (s *Subscription) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// PlusInfo represents Plus subscription info (from /account/plus or account status) +// PlusInfo represents Plus subscription info. type PlusInfo struct { BaseModel HasPlus bool `json:"has_plus"` @@ -208,7 +209,7 @@ type PlusInfo struct { Migrated *bool `json:"migrated,omitempty"` } -// DeJSON deserializes PlusInfo from JSON +// DeJSON deserializes PlusInfo from JSON data. func (p *PlusInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -232,7 +233,7 @@ func (p *PlusInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { return plus, nil } -// DeList deserializes a list of PlusInfo +// DeList deserializes a list of PlusInfo from JSON data. func (p *PlusInfo) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -250,7 +251,7 @@ func (p *PlusInfo) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// PromoCodeStatus represents promo code status +// PromoCodeStatus represents promo code status. type PromoCodeStatus struct { BaseModel Code string `json:"code"` @@ -262,7 +263,7 @@ type PromoCodeStatus struct { Activated bool `json:"activated"` } -// DeJSON deserializes PromoCodeStatus from JSON +// DeJSON deserializes PromoCodeStatus from JSON data. func (p *PromoCodeStatus) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -296,7 +297,7 @@ func (p *PromoCodeStatus) DeJSON(data []byte, c ClientInterface) (Model, error) return promo, nil } -// DeList deserializes a list of PromoCodeStatus +// DeList deserializes a list of PromoCodeStatus from JSON data. func (p *PromoCodeStatus) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/album.go b/internal/models/album.go index a3e9acf..f16d4be 100644 --- a/internal/models/album.go +++ b/internal/models/album.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Album represents a full album +// Album represents a full album from the Yandex Music API. type Album struct { BaseModel ID string `json:"id"` @@ -34,7 +35,7 @@ type Album struct { Trailer *TrailerInfo `json:"trailer"` } -// DeJSON deserializes an Album from JSON +// DeJSON deserializes an Album from JSON data. func (a *Album) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -138,7 +139,7 @@ func (a *Album) DeJSON(data []byte, c ClientInterface) (Model, error) { return album, nil } -// DeList deserializes a list of Albums +// DeList deserializes a list of Albums from JSON data. func (a *Album) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -156,14 +157,14 @@ func (a *Album) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// AlbumMeta represents album metadata +// AlbumMeta represents album metadata. type AlbumMeta struct { BaseModel Availability *Availability `json:"availability"` Upsell *Upsell `json:"upsell"` } -// DeJSON deserializes an AlbumMeta from JSON +// DeJSON deserializes an AlbumMeta from JSON data. func (am *AlbumMeta) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -186,7 +187,7 @@ func (am *AlbumMeta) DeJSON(data []byte, c ClientInterface) (Model, error) { return meta, nil } -// DeList deserializes a list of AlbumMeta +// DeList deserializes a list of AlbumMeta from JSON data. func (am *AlbumMeta) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -204,24 +205,24 @@ func (am *AlbumMeta) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// Availability represents availability info +// Availability represents availability info for an album. type Availability struct { AvailableForPremiumUsers bool `json:"available_for_premium_users"` Territories []string `json:"territories"` } -// Upsell represents upsell info +// Upsell represents upsell info for an album. type Upsell struct { Type string `json:"type"` Description string `json:"description"` } -// Best represents best tracks info +// Best represents best tracks info for an album. type Best struct { Tracks []Track `json:"tracks"` } -// TrailerInfo represents album/track trailer info +// TrailerInfo represents album/track trailer info. type TrailerInfo struct { BaseModel PreviewURI string `json:"preview_uri"` @@ -230,7 +231,7 @@ type TrailerInfo struct { Duration int `json:"duration"` } -// DeJSON deserializes a TrailerInfo from JSON +// DeJSON deserializes a TrailerInfo from JSON data. func (ti *TrailerInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -255,7 +256,7 @@ func (ti *TrailerInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { return trailer, nil } -// DeList deserializes a list of TrailerInfo +// DeList deserializes a list of TrailerInfo from JSON data. func (ti *TrailerInfo) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/artist.go b/internal/models/artist.go index c84a45f..31253a1 100644 --- a/internal/models/artist.go +++ b/internal/models/artist.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Artist represents a full artist +// Artist represents a full artist from the Yandex Music API. type Artist struct { BaseModel ID string `json:"id"` @@ -34,7 +35,7 @@ type Artist struct { TracksData []Track `json:"tracks_data"` } -// DeJSON deserializes an Artist from JSON +// DeJSON deserializes an Artist from JSON data. func (a *Artist) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -146,7 +147,7 @@ func (a *Artist) DeJSON(data []byte, c ClientInterface) (Model, error) { return artist, nil } -// DeList deserializes a list of Artists +// DeList deserializes a list of Artists from JSON data. func (a *Artist) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -164,27 +165,27 @@ func (a *Artist) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// Ratings represents artist ratings +// Ratings represents artist ratings. type Ratings struct { Rating float64 `json:"rating"` Votes int `json:"votes"` } -// Counts represents artist counts +// Counts represents artist counts. type Counts struct { Tracks int `json:"tracks"` Albums int `json:"albums"` Folders int `json:"folders"` } -// SocialLink represents a social media link +// SocialLink represents a social media link. type SocialLink struct { URL string `json:"url"` Title string `json:"title"` Type string `json:"type"` } -// Cover represents cover image info +// Cover represents cover image info. type Cover struct { URI string `json:"uri"` Type string `json:"type"` @@ -193,13 +194,13 @@ type Cover struct { Background string `json:"background"` } -// ArtistBriefInfo represents brief artist info +// ArtistBriefInfo represents brief artist info. type ArtistBriefInfo struct { Description string `json:"description"` Available bool `json:"available"` } -// ArtistDonations represents artist donations info +// ArtistDonations represents artist donations info. type ArtistDonations struct { Items []DonationItem `json:"items"` Total int `json:"total"` @@ -207,7 +208,7 @@ type ArtistDonations struct { Raised int `json:"raised"` } -// DonationItem represents a donation item +// DonationItem represents a donation item. type DonationItem struct { ID string `json:"id"` Title string `json:"title"` @@ -218,7 +219,7 @@ type DonationItem struct { Currency string `json:"currency"` } -// ConcertShort represents a concert (minimal for artist) +// ConcertShort represents a concert (minimal for artist). type ConcertShort struct { BaseModel ID string `json:"id"` @@ -233,7 +234,7 @@ type ConcertShort struct { Available bool `json:"available"` } -// DeJSON deserializes a ConcertShort from JSON +// DeJSON deserializes a ConcertShort from JSON data. func (c *ConcertShort) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -276,7 +277,7 @@ func (c *ConcertShort) DeJSON(data []byte, client ClientInterface) (Model, error return concert, nil } -// DeList deserializes a list of ConcertShort +// DeList deserializes a list of ConcertShort from JSON data. func (c *ConcertShort) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -294,7 +295,7 @@ func (c *ConcertShort) DeList(data []byte, client ClientInterface) ([]Model, err return result, nil } -// ClipShort represents a clip (minimal for artist) +// ClipShort represents a clip (minimal for artist). type ClipShort struct { BaseModel ID string `json:"id"` @@ -308,7 +309,7 @@ type ClipShort struct { CreatedAt string `json:"created_at"` } -// DeJSON deserializes a ClipShort from JSON +// DeJSON deserializes a ClipShort from JSON data. func (c *ClipShort) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -348,7 +349,7 @@ func (c *ClipShort) DeJSON(data []byte, client ClientInterface) (Model, error) { return clip, nil } -// DeList deserializes a list of ClipShort +// DeList deserializes a list of ClipShort from JSON data. func (c *ClipShort) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/artist_albums.go b/internal/models/artist_albums.go index 17dec3a..e396e9e 100644 --- a/internal/models/artist_albums.go +++ b/internal/models/artist_albums.go @@ -1,17 +1,18 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// ArtistAlbums represents a page of albums by an artist +// ArtistAlbums represents a page of albums by an artist. type ArtistAlbums struct { BaseModel Albums []Album `json:"albums"` Pager *Pager `json:"pager"` } -// DeJSON deserializes an ArtistAlbums from JSON +// DeJSON deserializes an ArtistAlbums from JSON data. func (aa *ArtistAlbums) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -36,7 +37,7 @@ func (aa *ArtistAlbums) DeJSON(data []byte, c ClientInterface) (Model, error) { return albums, nil } -// DeList deserializes a list of ArtistAlbums +// DeList deserializes a list of ArtistAlbums from JSON data. func (aa *ArtistAlbums) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/artist_tracks.go b/internal/models/artist_tracks.go index 06fe22b..d8d755e 100644 --- a/internal/models/artist_tracks.go +++ b/internal/models/artist_tracks.go @@ -1,17 +1,18 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// ArtistTracks represents a page of tracks by an artist +// ArtistTracks represents a page of tracks by an artist. type ArtistTracks struct { BaseModel Tracks []Track `json:"tracks"` Pager *Pager `json:"pager"` } -// DeJSON deserializes an ArtistTracks from JSON +// DeJSON deserializes an ArtistTracks from JSON data. func (at *ArtistTracks) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -36,7 +37,7 @@ func (at *ArtistTracks) DeJSON(data []byte, c ClientInterface) (Model, error) { return tracks, nil } -// DeList deserializes a list of ArtistTracks +// DeList deserializes a list of ArtistTracks from JSON data. func (at *ArtistTracks) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/base.go b/internal/models/base.go index 46bd547..d5cb68d 100644 --- a/internal/models/base.go +++ b/internal/models/base.go @@ -8,35 +8,38 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) -// Model is the base interface for all models +// Model is the base interface for all models. +// All model types implement this interface for JSON deserialization and serialization. type Model interface { - // DeJSON deserializes from JSON + // DeJSON deserializes a model from JSON data. DeJSON(data []byte, c ClientInterface) (Model, error) - // DeList deserializes a list of models + // DeList deserializes a list of models from JSON data. DeList(data []byte, c ClientInterface) ([]Model, error) - // ToJSON serializes to JSON + // ToJSON serializes the model to JSON. ToJSON() ([]byte, error) - // ToMap converts to map + // ToMap converts the model to a map. ToMap() (map[string]any, error) } -// BaseModel provides common functionality for models +// BaseModel provides common functionality for models, including a client reference. type BaseModel struct { Client ClientInterface `json:"-"` } -// NewBaseModel creates a new BaseModel +// NewBaseModel creates a new BaseModel with the given client interface. func NewBaseModel(c ClientInterface) *BaseModel { return &BaseModel{Client: c} } -// DeJSON implements Model.DeJSON for basic models +// DeJSON implements Model.DeJSON for basic models. +// This should be overridden by concrete types. func (b *BaseModel) DeJSON(data []byte, c ClientInterface) (Model, error) { // This should be overridden by concrete types return nil, nil } -// DeList implements Model.DeList for basic models +// DeList implements Model.DeList for basic models. +// This should be overridden by concrete types. func (b *BaseModel) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -51,12 +54,12 @@ func (b *BaseModel) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// ToJSON serializes the model to JSON +// ToJSON serializes the model to JSON using the default JSON backend. func (b *BaseModel) ToJSON() ([]byte, error) { return utils.Marshal(b) } -// ToMap converts the model to a map +// ToMap converts the model to a map by serializing to JSON and unmarshaling into a map. func (b *BaseModel) ToMap() (map[string]any, error) { data, err := b.ToJSON() if err != nil { @@ -69,12 +72,12 @@ func (b *BaseModel) ToMap() (map[string]any, error) { return result, nil } -// SetClient sets the client on the model +// SetClient sets the client interface on the model. func (b *BaseModel) SetClient(c ClientInterface) { b.Client = c } -// GetClient returns the client +// GetClient returns the client interface associated with the model. func (b *BaseModel) GetClient() ClientInterface { return b.Client } diff --git a/internal/models/client.go b/internal/models/client.go index 441d0e9..f2228a9 100644 --- a/internal/models/client.go +++ b/internal/models/client.go @@ -1,19 +1,28 @@ +// Package models provides data models for the Yandex Music API. package models import ( "context" ) -// ClientInterface defines the minimal client interface needed by models +// ClientInterface defines the minimal client interface needed by models. +// Models use this to access the underlying request handler. type ClientInterface interface { + // GetRequest returns the underlying request handler. GetRequest() RequestInterface } -// RequestInterface defines the minimal request interface needed by models +// RequestInterface defines the minimal request interface needed by models. +// It provides methods for making HTTP requests to the Yandex Music API. type RequestInterface interface { + // Get performs a GET request to the given path with query parameters. Get(ctx context.Context, path string, params map[string]string, result any) error + // Post performs a POST request to the given path with a JSON body. Post(ctx context.Context, path string, body any, result any) error + // Put performs a PUT request to the given path with a JSON body. Put(ctx context.Context, path string, body any, result any) error + // Delete performs a DELETE request to the given path with an optional JSON body. Delete(ctx context.Context, path string, body any, result any) error + // Download downloads a file from the given URL and returns the raw response body. Download(ctx context.Context, url string) ([]byte, error) } diff --git a/internal/models/clip.go b/internal/models/clip.go index 0d8b773..36f30e7 100644 --- a/internal/models/clip.go +++ b/internal/models/clip.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Clip represents a clip (short video) +// Clip represents a clip (short video) from the Yandex Music API. type Clip struct { BaseModel ID string `json:"id"` @@ -24,7 +25,7 @@ type Clip struct { AspectRatio string `json:"aspect_ratio"` } -// DeJSON deserializes a Clip from JSON +// DeJSON deserializes a Clip from JSON data. func (c *Clip) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -89,7 +90,7 @@ func (c *Clip) DeJSON(data []byte, client ClientInterface) (Model, error) { return clip, nil } -// DeList deserializes a list of Clips +// DeList deserializes a list of Clips from JSON data. func (c *Clip) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -107,28 +108,28 @@ func (c *Clip) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// ClipsWillLike represents clips the user might like +// ClipsWillLike represents clips the user might like. type ClipsWillLike struct { BaseModel Clips []Clip `json:"clips"` Total int `json:"total"` } -// ArtistClipData represents artist clip data +// ArtistClipData represents artist clip data. type ArtistClipData struct { BaseModel Clips []Clip `json:"clips"` Total int `json:"total"` } -// ArtistClipItem represents an artist clip item +// ArtistClipItem represents an artist clip item. type ArtistClipItem struct { BaseModel Clip *Clip `json:"clip"` Index int `json:"index"` } -// Shot represents a shot (short video) +// Shot represents a shot (short video). type Shot struct { BaseModel ID string `json:"id"` @@ -150,7 +151,7 @@ type Shot struct { AspectRatio string `json:"aspect_ratio"` } -// DeJSON deserializes a Shot from JSON +// DeJSON deserializes a Shot from JSON data. func (s *Shot) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -219,7 +220,7 @@ func (s *Shot) DeJSON(data []byte, client ClientInterface) (Model, error) { return shot, nil } -// DeList deserializes a list of Shots +// DeList deserializes a list of Shots from JSON data. func (s *Shot) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -237,14 +238,14 @@ func (s *Shot) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// ShotData represents shot data +// ShotData represents shot data. type ShotData struct { BaseModel Shots []Shot `json:"shots"` Total int `json:"total"` } -// ShotEvent represents a shot event +// ShotEvent represents a shot event. type ShotEvent struct { BaseModel EventID string `json:"event_id"` @@ -254,7 +255,7 @@ type ShotEvent struct { Action string `json:"action"` } -// ShotType represents a shot type +// ShotType represents a shot type. type ShotType struct { BaseModel ID string `json:"id"` diff --git a/internal/models/concert.go b/internal/models/concert.go index 8adcb89..317ab8c 100644 --- a/internal/models/concert.go +++ b/internal/models/concert.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Concert represents a concert +// Concert represents a concert from the Yandex Music API. type Concert struct { BaseModel ID string `json:"id"` @@ -28,7 +29,7 @@ type Concert struct { Skeleton *ConcertSkeleton `json:"skeleton"` } -// DeJSON deserializes a Concert from JSON +// DeJSON deserializes a Concert from JSON data. func (c *Concert) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -111,7 +112,7 @@ func (c *Concert) DeJSON(data []byte, client ClientInterface) (Model, error) { return concert, nil } -// DeList deserializes a list of Concerts +// DeList deserializes a list of Concerts from JSON data. func (c *Concert) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -129,7 +130,7 @@ func (c *Concert) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// ConcertVenue represents a concert venue +// ConcertVenue represents a concert venue. type ConcertVenue struct { BaseModel ID string `json:"id"` @@ -141,7 +142,7 @@ type ConcertVenue struct { ImageURI string `json:"image_uri"` } -// ConcertLocation represents a concert location +// ConcertLocation represents a concert location. type ConcertLocation struct { BaseModel ID string `json:"id"` @@ -152,7 +153,7 @@ type ConcertLocation struct { Venues []ConcertVenue `json:"venues"` } -// ConcertLocations represents concert locations +// ConcertLocations represents concert locations. type ConcertLocations struct { BaseModel Locations []ConcertLocation `json:"locations"` @@ -161,7 +162,7 @@ type ConcertLocations struct { PageSize int `json:"page_size"` } -// ConcertFeed represents a concert feed +// ConcertFeed represents a concert feed. type ConcertFeed struct { BaseModel Concerts []Concert `json:"concerts"` @@ -170,14 +171,14 @@ type ConcertFeed struct { PageSize int `json:"page_size"` } -// ConcertInfo represents concert info +// ConcertInfo represents concert info. type ConcertInfo struct { BaseModel Concert *Concert `json:"concert"` Related []Concert `json:"related"` } -// ConcertEventInfo represents concert event info +// ConcertEventInfo represents concert event info. type ConcertEventInfo struct { BaseModel EventID string `json:"event_id"` @@ -186,7 +187,7 @@ type ConcertEventInfo struct { Data json.RawMessage `json:"data"` } -// ConcertDescription represents concert description +// ConcertDescription represents concert description. type ConcertDescription struct { BaseModel Text string `json:"text"` @@ -194,7 +195,7 @@ type ConcertDescription struct { ShortText string `json:"short_text"` } -// ConcertCashback represents concert cashback +// ConcertCashback represents concert cashback. type ConcertCashback struct { BaseModel Amount int `json:"amount"` @@ -203,14 +204,14 @@ type ConcertCashback struct { Expires string `json:"expires"` } -// ConcertMinPrice represents concert min price +// ConcertMinPrice represents concert min price. type ConcertMinPrice struct { BaseModel Price int `json:"price"` Currency string `json:"currency"` } -// ConcertTabConfig represents concert tab config +// ConcertTabConfig represents concert tab config. type ConcertTabConfig struct { BaseModel ID string `json:"id"` @@ -220,20 +221,20 @@ type ConcertTabConfig struct { Range *ConcertTabRange `json:"range"` } -// ConcertTabRange represents concert tab range +// ConcertTabRange represents concert tab range. type ConcertTabRange struct { BaseModel From string `json:"from"` To string `json:"to"` } -// ConcertSkeleton represents concert skeleton +// ConcertSkeleton represents concert skeleton. type ConcertSkeleton struct { BaseModel Blocks []ConcertSkeletonBlock `json:"blocks"` } -// ConcertSkeletonBlock represents a concert skeleton block +// ConcertSkeletonBlock represents a concert skeleton block. type ConcertSkeletonBlock struct { BaseModel ID string `json:"id"` diff --git a/internal/models/credits.go b/internal/models/credits.go index 9e6fee2..f9829b3 100644 --- a/internal/models/credits.go +++ b/internal/models/credits.go @@ -1,17 +1,18 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Credits represents track credits +// Credits represents track credits from the Yandex Music API. type Credits struct { BaseModel Items []Credit `json:"items"` Total int `json:"total"` } -// DeJSON deserializes Credits from JSON +// DeJSON deserializes Credits from JSON data. func (c *Credits) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -32,7 +33,7 @@ func (c *Credits) DeJSON(data []byte, client ClientInterface) (Model, error) { return credits, nil } -// DeList deserializes a list of Credits +// DeList deserializes a list of Credits from JSON data. from JSON data. func (c *Credits) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -50,7 +51,7 @@ func (c *Credits) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// Credit represents a credit +// Credit represents a credit. type Credit struct { BaseModel Role string `json:"role"` @@ -62,7 +63,7 @@ type Credit struct { AlbumID string `json:"album_id"` } -// DeJSON deserializes a Credit from JSON +// DeJSON deserializes a Credit from JSON data. func (c *Credit) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -114,7 +115,7 @@ func (c *Credit) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// LicenceTextPart represents a licence text part +// LicenceTextPart represents a licence text part. type LicenceTextPart struct { BaseModel Text string `json:"text"` @@ -124,7 +125,7 @@ type LicenceTextPart struct { IsMain bool `json:"is_main"` } -// DeJSON deserializes a LicenceTextPart from JSON +// DeJSON deserializes a LicenceTextPart from JSON data. func (ltp *LicenceTextPart) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -152,7 +153,7 @@ func (ltp *LicenceTextPart) DeJSON(data []byte, client ClientInterface) (Model, return part, nil } -// DeList deserializes a list of LicenceTextPart +// DeList deserializes a list of LicenceTextPart from JSON data. func (ltp *LicenceTextPart) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/feed.go b/internal/models/feed.go index cb46535..2569971 100644 --- a/internal/models/feed.go +++ b/internal/models/feed.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Feed represents the main feed +// Feed represents the main feed from the Yandex Music API. type Feed struct { BaseModel Days []Day `json:"days"` @@ -12,7 +13,7 @@ type Feed struct { PlayContexts []PlayContext `json:"play_contexts"` } -// DeJSON deserializes a Feed from JSON +// DeJSON deserializes a Feed from JSON data. func (f *Feed) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -40,7 +41,7 @@ func (f *Feed) DeJSON(data []byte, c ClientInterface) (Model, error) { return feed, nil } -// DeList deserializes a list of Feeds +// DeList deserializes a list of Feeds from JSON data. func (f *Feed) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -58,7 +59,7 @@ func (f *Feed) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// Day represents a day in the feed +// Day represents a day in the feed. type Day struct { BaseModel Date string `json:"date"` @@ -68,7 +69,7 @@ type Day struct { GeneratedPlaylists []GeneratedPlaylist `json:"generated_playlists"` } -// DeJSON deserializes a Day from JSON +// DeJSON deserializes a Day from JSON data. func (d *Day) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -100,7 +101,7 @@ func (d *Day) DeJSON(data []byte, c ClientInterface) (Model, error) { return day, nil } -// DeList deserializes a list of Days +// DeList deserializes a list of Days from JSON data. func (d *Day) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -118,7 +119,7 @@ func (d *Day) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// DayBlock represents a block in a day +// DayBlock represents a block in a day. type DayBlock struct { BaseModel ID string `json:"id"` @@ -128,7 +129,7 @@ type DayBlock struct { Data *DayBlockData `json:"data"` } -// DayBlockData represents data in a day block +// DayBlockData represents data in a day block. type DayBlockData struct { Tracks []Track `json:"tracks"` Playlists []Playlist `json:"playlists"` @@ -137,7 +138,7 @@ type DayBlockData struct { GeneratedPlaylist *GeneratedPlaylist `json:"generated_playlist"` } -// GeneratedPlaylist represents a generated playlist +// GeneratedPlaylist represents a generated playlist. type GeneratedPlaylist struct { BaseModel ID string `json:"id"` @@ -153,7 +154,7 @@ type GeneratedPlaylist struct { Tracks []Track `json:"tracks"` } -// DeJSON deserializes a GeneratedPlaylist from JSON +// DeJSON deserializes a GeneratedPlaylist from JSON data. func (gp *GeneratedPlaylist) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -201,7 +202,7 @@ func (gp *GeneratedPlaylist) DeJSON(data []byte, c ClientInterface) (Model, erro return playlist, nil } -// DeList deserializes a list of GeneratedPlaylists +// DeList deserializes a list of GeneratedPlaylists from JSON data. func (gp *GeneratedPlaylist) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -219,7 +220,7 @@ func (gp *GeneratedPlaylist) DeList(data []byte, c ClientInterface) ([]Model, er return result, nil } -// Event represents a feed event +// Event represents a feed event. type Event struct { BaseModel Timestamp string `json:"timestamp"` @@ -231,7 +232,7 @@ type Event struct { Action string `json:"action"` } -// AlbumEvent represents an album event +// AlbumEvent represents an album event. type AlbumEvent struct { BaseModel Album *Album `json:"album"` @@ -240,7 +241,7 @@ type AlbumEvent struct { Action string `json:"action"` } -// ArtistEvent represents an artist event +// ArtistEvent represents an artist event. type ArtistEvent struct { BaseModel Artist *Artist `json:"artist"` @@ -249,7 +250,7 @@ type ArtistEvent struct { Action string `json:"action"` } -// TrackWithAds represents a track with ads +// TrackWithAds represents a track with ads. type TrackWithAds struct { BaseModel Track *Track `json:"track"` @@ -257,7 +258,7 @@ type TrackWithAds struct { AdParams *AdParams `json:"ad_params"` } -// Ad represents an ad +// Ad represents an ad. type Ad struct { BaseModel ID string `json:"id"` @@ -269,7 +270,7 @@ type Ad struct { Duration int `json:"duration"` } -// AdParams represents ad parameters +// AdParams represents ad parameters. type AdParams struct { BaseModel Frequency int `json:"frequency"` diff --git a/internal/models/label.go b/internal/models/label.go index 6eb251a..e553865 100644 --- a/internal/models/label.go +++ b/internal/models/label.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Label represents a label +// Label represents a label from the Yandex Music API. type Label struct { BaseModel ID string `json:"id"` @@ -17,7 +18,7 @@ type Label struct { Owner *User `json:"owner"` } -// DeJSON deserializes a Label from JSON +// DeJSON deserializes a Label from JSON data. func (l *Label) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -58,7 +59,7 @@ func (l *Label) DeJSON(data []byte, client ClientInterface) (Model, error) { return label, nil } -// DeList deserializes a list of Labels +// DeList deserializes a list of Labels from JSON data. func (l *Label) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -76,7 +77,7 @@ func (l *Label) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// LabelAlbums represents label albums +// LabelAlbums represents label albums. type LabelAlbums struct { BaseModel Albums []Album `json:"albums"` @@ -85,7 +86,7 @@ type LabelAlbums struct { PageSize int `json:"page_size"` } -// LabelArtists represents label artists +// LabelArtists represents label artists. type LabelArtists struct { BaseModel Artists []Artist `json:"artists"` diff --git a/internal/models/landing.go b/internal/models/landing.go index cbb741c..f5823bf 100644 --- a/internal/models/landing.go +++ b/internal/models/landing.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Landing represents a landing page +// Landing represents a landing page from the Yandex Music API. type Landing struct { BaseModel ID string `json:"id"` @@ -16,7 +17,7 @@ type Landing struct { Available bool `json:"available"` } -// DeJSON deserializes a Landing from JSON +// DeJSON deserializes a Landing from JSON data. func (l *Landing) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -53,7 +54,7 @@ func (l *Landing) DeJSON(data []byte, c ClientInterface) (Model, error) { return landing, nil } -// DeList deserializes a list of Landings +// DeList deserializes a list of Landings from JSON data. func (l *Landing) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -71,7 +72,7 @@ func (l *Landing) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// LandingBlock represents a block in a landing +// LandingBlock represents a block in a landing. type LandingBlock struct { BaseModel ID string `json:"id"` @@ -81,7 +82,7 @@ type LandingBlock struct { Data *LandingBlockData `json:"data"` } -// LandingBlockData represents data in a landing block +// LandingBlockData represents data in a landing block. type LandingBlockData struct { Tracks []Track `json:"tracks"` Playlists []Playlist `json:"playlists"` @@ -90,7 +91,7 @@ type LandingBlockData struct { GeneratedPlaylist *GeneratedPlaylist `json:"generated_playlist"` } -// LandingList represents a list of landings +// LandingList represents a list of landings. type LandingList struct { BaseModel Landings []Landing `json:"landings"` @@ -99,7 +100,7 @@ type LandingList struct { PageSize int `json:"page_size"` } -// DeJSON deserializes a LandingList from JSON +// DeJSON deserializes a LandingList from JSON data. func (ll *LandingList) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -126,7 +127,7 @@ func (ll *LandingList) DeJSON(data []byte, c ClientInterface) (Model, error) { return list, nil } -// DeList deserializes a list of LandingLists +// DeList deserializes a list of LandingLists from JSON data. func (ll *LandingList) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/metatag.go b/internal/models/metatag.go index 3183005..419c985 100644 --- a/internal/models/metatag.go +++ b/internal/models/metatag.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Metatag represents a metatag +// Metatag represents a metatag from the Yandex Music API. type Metatag struct { BaseModel ID string `json:"id"` @@ -16,7 +17,7 @@ type Metatag struct { Children []Metatag `json:"children"` } -// DeJSON deserializes a Metatag from JSON +// DeJSON deserializes a Metatag from JSON data. func (m *Metatag) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -52,7 +53,7 @@ func (m *Metatag) DeJSON(data []byte, client ClientInterface) (Model, error) { return metatag, nil } -// DeList deserializes a list of Metatags +// DeList deserializes a list of Metatags from JSON data. func (m *Metatag) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -70,14 +71,14 @@ func (m *Metatag) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// MetatagTree represents a metatag tree +// MetatagTree represents a metatag tree. type MetatagTree struct { BaseModel Root *Metatag `json:"root"` Leaves []Metatag `json:"leaves"` } -// MetatagLeaf represents a metatag leaf +// MetatagLeaf represents a metatag leaf. type MetatagLeaf struct { BaseModel ID string `json:"id"` @@ -88,7 +89,7 @@ type MetatagLeaf struct { Position int `json:"position"` } -// MetatagArtists represents metatag artists +// MetatagArtists represents metatag artists. type MetatagArtists struct { BaseModel Artists []Artist `json:"artists"` @@ -97,7 +98,7 @@ type MetatagArtists struct { PageSize int `json:"page_size"` } -// MetatagAlbums represents metatag albums +// MetatagAlbums represents metatag albums. type MetatagAlbums struct { BaseModel Albums []Album `json:"albums"` @@ -106,7 +107,7 @@ type MetatagAlbums struct { PageSize int `json:"page_size"` } -// MetatagPlaylists represents metatag playlists +// MetatagPlaylists represents metatag playlists. type MetatagPlaylists struct { BaseModel Playlists []Playlist `json:"playlists"` @@ -115,27 +116,27 @@ type MetatagPlaylists struct { PageSize int `json:"page_size"` } -// MetatagTitle represents a metatag title +// MetatagTitle represents a metatag title. type MetatagTitle struct { BaseModel Title string `json:"title"` } -// MetatagSortByValue represents metatag sort by value +// MetatagSortByValue represents metatag sort by value. type MetatagSortByValue struct { BaseModel Value string `json:"value"` Label string `json:"label"` } -// MetatagArtistEntry represents a metatag artist entry +// MetatagArtistEntry represents a metatag artist entry. type MetatagArtistEntry struct { BaseModel Artist *Artist `json:"artist"` Score float64 `json:"score"` } -// Genre represents a genre +// Genre represents a genre from the Yandex Music API. type Genre struct { BaseModel ID string `json:"id"` @@ -147,7 +148,7 @@ type Genre struct { Children []Genre `json:"children"` } -// DeJSON deserializes a Genre from JSON +// DeJSON deserializes a Genre from JSON data. func (g *Genre) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -183,7 +184,7 @@ func (g *Genre) DeJSON(data []byte, client ClientInterface) (Model, error) { return genre, nil } -// DeList deserializes a list of Genres +// DeList deserializes a list of Genres from JSON data. func (g *Genre) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -201,7 +202,7 @@ func (g *Genre) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// Chart represents a chart +// Chart represents a chart from the Yandex Music API. type Chart struct { BaseModel ID string `json:"id"` @@ -212,7 +213,7 @@ type Chart struct { Items []ChartItem `json:"items"` } -// DeJSON deserializes a Chart from JSON +// DeJSON deserializes a Chart from JSON data. func (c *Chart) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -245,7 +246,7 @@ func (c *Chart) DeJSON(data []byte, client ClientInterface) (Model, error) { return chart, nil } -// DeList deserializes a list of Charts +// DeList deserializes a list of Charts from JSON data. func (c *Chart) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -263,14 +264,14 @@ func (c *Chart) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// ChartInfo represents chart info +// ChartInfo represents chart info. type ChartInfo struct { BaseModel Chart *Chart `json:"chart"` Menu []ChartInfoMenu `json:"menu"` } -// ChartItem represents a chart item +// ChartItem represents a chart item. type ChartItem struct { BaseModel Position int `json:"position"` @@ -282,7 +283,7 @@ type ChartItem struct { Trend string `json:"trend"` } -// ChartInfoMenu represents a chart info menu +// ChartInfoMenu represents a chart info menu. type ChartInfoMenu struct { BaseModel ID string `json:"id"` @@ -291,7 +292,7 @@ type ChartInfoMenu struct { Items []ChartInfoMenuItem `json:"items"` } -// ChartInfoMenuItem represents a chart info menu item +// ChartInfoMenuItem represents a chart info menu item. type ChartInfoMenuItem struct { BaseModel ID string `json:"id"` @@ -300,7 +301,7 @@ type ChartInfoMenuItem struct { Action string `json:"action"` } -// ChartItems represents chart items response +// ChartItems represents chart items response. type ChartItems struct { BaseModel Items []ChartItem `json:"items"` diff --git a/internal/models/music_history.go b/internal/models/music_history.go index 1c87f98..505ef6a 100644 --- a/internal/models/music_history.go +++ b/internal/models/music_history.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// MusicHistory represents music history +// MusicHistory represents music history from the Yandex Music API. type MusicHistory struct { BaseModel Tabs []MusicHistoryTab `json:"tabs"` @@ -13,7 +14,7 @@ type MusicHistory struct { Context *MusicHistoryContextFullModel `json:"context"` } -// DeJSON deserializes a MusicHistory from JSON +// DeJSON deserializes a MusicHistory from JSON data. func (mh *MusicHistory) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -46,7 +47,7 @@ func (mh *MusicHistory) DeJSON(data []byte, client ClientInterface) (Model, erro return history, nil } -// DeList deserializes a list of MusicHistory +// DeList deserializes a list of MusicHistory from JSON data. func (mh *MusicHistory) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -64,7 +65,7 @@ func (mh *MusicHistory) DeList(data []byte, client ClientInterface) ([]Model, er return result, nil } -// MusicHistoryTab represents a music history tab +// MusicHistoryTab represents a music history tab. type MusicHistoryTab struct { BaseModel ID string `json:"id"` @@ -75,7 +76,7 @@ type MusicHistoryTab struct { Position int `json:"position"` } -// MusicHistoryGroup represents a music history group +// MusicHistoryGroup represents a music history group. type MusicHistoryGroup struct { BaseModel ID string `json:"id"` @@ -85,7 +86,7 @@ type MusicHistoryGroup struct { Total int `json:"total"` } -// MusicHistoryItem represents a music history item +// MusicHistoryItem represents a music history item. type MusicHistoryItem struct { BaseModel ID string `json:"id"` @@ -100,7 +101,7 @@ type MusicHistoryItem struct { Context *MusicHistoryItemData `json:"context"` } -// MusicHistoryItemData represents music history item data +// MusicHistoryItemData represents music history item data. type MusicHistoryItemData struct { BaseModel Source string `json:"source"` @@ -112,14 +113,14 @@ type MusicHistoryItemData struct { Progress float64 `json:"progress"` } -// MusicHistoryItemID represents music history item ID +// MusicHistoryItemID represents music history item ID. type MusicHistoryItemID struct { BaseModel ID string `json:"id"` Type string `json:"type"` } -// MusicHistoryItems represents music history items +// MusicHistoryItems represents music history items. type MusicHistoryItems struct { BaseModel Items []MusicHistoryItem `json:"items"` @@ -128,7 +129,7 @@ type MusicHistoryItems struct { PageSize int `json:"page_size"` } -// MusicHistoryContextFullModel represents music history context full model +// MusicHistoryContextFullModel represents music history context full model. type MusicHistoryContextFullModel struct { BaseModel DeviceID string `json:"device_id"` diff --git a/internal/models/pin.go b/internal/models/pin.go index 807c717..bf0d1fe 100644 --- a/internal/models/pin.go +++ b/internal/models/pin.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Pin represents a pin +// Pin represents a pin from the Yandex Music API. type Pin struct { BaseModel ID string `json:"id"` @@ -22,7 +23,7 @@ type Pin struct { Active bool `json:"active"` } -// DeJSON deserializes a Pin from JSON +// DeJSON deserializes a Pin from JSON data. func (p *Pin) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -83,7 +84,7 @@ func (p *Pin) DeJSON(data []byte, client ClientInterface) (Model, error) { return pin, nil } -// DeList deserializes a list of Pins +// DeList deserializes a list of Pins from JSON data. func (p *Pin) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -101,14 +102,14 @@ func (p *Pin) DeList(data []byte, client ClientInterface) ([]Model, error) { return result, nil } -// PinData represents pin data +// PinData represents pin data. type PinData struct { BaseModel Pins []Pin `json:"pins"` Total int `json:"total"` } -// PinsList represents a list of pins +// PinsList represents a list of pins. type PinsList struct { BaseModel Pins []Pin `json:"pins"` @@ -117,7 +118,7 @@ type PinsList struct { PageSize int `json:"page_size"` } -// Presaves represents presaves +// Presaves represents presaves. type Presaves struct { BaseModel Presaves []Presave `json:"presaves"` @@ -126,7 +127,7 @@ type Presaves struct { PageSize int `json:"page_size"` } -// Presave represents a presave +// Presave represents a presave. type Presave struct { BaseModel ID string `json:"id"` @@ -142,7 +143,7 @@ type Presave struct { UpdatedAt string `json:"updated_at"` } -// DeJSON deserializes a Presave from JSON +// DeJSON deserializes a Presave from JSON data. func (p *Presave) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -195,7 +196,7 @@ func (p *Presave) DeJSON(data []byte, client ClientInterface) (Model, error) { return presave, nil } -// DeList deserializes a list of Presaves +// DeList deserializes a list of Presaves from JSON data. func (p *Presave) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/playlist.go b/internal/models/playlist.go index f3160ae..83e53de 100644 --- a/internal/models/playlist.go +++ b/internal/models/playlist.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Playlist represents a playlist +// Playlist represents a playlist from the Yandex Music API. type Playlist struct { BaseModel Kind int `json:"kind"` @@ -36,7 +37,7 @@ type Playlist struct { Trailer *TrailerInfo `json:"trailer"` } -// DeJSON deserializes a Playlist from JSON +// DeJSON deserializes a Playlist from JSON data. func (p *Playlist) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -142,7 +143,7 @@ func (p *Playlist) DeJSON(data []byte, c ClientInterface) (Model, error) { return playlist, nil } -// DeList deserializes a list of Playlists +// DeList deserializes a list of Playlists from JSON data. func (p *Playlist) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -160,7 +161,7 @@ func (p *Playlist) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// User represents a user (playlist owner) +// User represents a user (playlist owner) from the Yandex Music API. type User struct { BaseModel UID int64 `json:"uid"` @@ -184,7 +185,7 @@ type User struct { Counters *UserCounters `json:"counters"` } -// DeJSON deserializes a User from JSON +// DeJSON deserializes a User from JSON data. func (u *User) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -255,7 +256,7 @@ func (u *User) DeJSON(data []byte, c ClientInterface) (Model, error) { return user, nil } -// DeList deserializes a list of Users +// DeList deserializes a list of Users from JSON data. func (u *User) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -273,7 +274,7 @@ func (u *User) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// UserSettings represents user settings (from /account/settings) +// UserSettings represents user settings from /account/settings. type UserSettings struct { BaseModel UID int64 `json:"uid"` @@ -295,7 +296,7 @@ type UserSettings struct { ShowDiskTracksInLibrary *bool `json:"show_disk_tracks_in_library,omitempty"` } -// DeJSON deserializes UserSettings from JSON +// DeJSON deserializes UserSettings from JSON data. func (u *UserSettings) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -365,7 +366,7 @@ func (u *UserSettings) DeJSON(data []byte, c ClientInterface) (Model, error) { return settings, nil } -// DeList deserializes a list of UserSettings +// DeList deserializes a list of UserSettings from JSON data. func (u *UserSettings) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -383,7 +384,7 @@ func (u *UserSettings) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// UserCounters represents user counters +// UserCounters represents user counters. type UserCounters struct { Tracks int `json:"tracks"` Albums int `json:"albums"` @@ -393,7 +394,7 @@ type UserCounters struct { Likes int `json:"likes"` } -// Image represents an image with multiple sizes +// Image represents an image with multiple sizes. type Image struct { URI string `json:"uri"` Type string `json:"type"` diff --git a/internal/models/queue.go b/internal/models/queue.go index f73284d..efd8fed 100644 --- a/internal/models/queue.go +++ b/internal/models/queue.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Queue represents a playback queue +// Queue represents a playback queue from the Yandex Music API. type Queue struct { BaseModel ID string `json:"id"` @@ -20,7 +21,7 @@ type Queue struct { TotalDuration int `json:"total_duration_ms"` } -// DeJSON deserializes a Queue from JSON +// DeJSON deserializes a Queue from JSON data. func (q *Queue) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -71,7 +72,7 @@ func (q *Queue) DeJSON(data []byte, c ClientInterface) (Model, error) { return queue, nil } -// DeList deserializes a list of Queues +// DeList deserializes a list of Queues from JSON data. func (q *Queue) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -89,7 +90,7 @@ func (q *Queue) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// QueueItem represents a queue item +// QueueItem represents a queue item. type QueueItem struct { BaseModel TrackID string `json:"track_id"` @@ -101,7 +102,7 @@ type QueueItem struct { PlayContext *PlayContext `json:"play_context"` } -// DeJSON deserializes a QueueItem from JSON +// DeJSON deserializes a QueueItem from JSON data. func (qi *QueueItem) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -140,7 +141,7 @@ func (qi *QueueItem) DeJSON(data []byte, c ClientInterface) (Model, error) { return item, nil } -// DeList deserializes a list of QueueItems +// DeList deserializes a list of QueueItems from JSON data. func (qi *QueueItem) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -158,7 +159,7 @@ func (qi *QueueItem) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// PlayContext represents a play context +// PlayContext represents a play context. type PlayContext struct { BaseModel ID string `json:"id"` @@ -173,7 +174,7 @@ type PlayContext struct { Available bool `json:"available"` } -// DeJSON deserializes a PlayContext from JSON +// DeJSON deserializes a PlayContext from JSON data. func (pc *PlayContext) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -219,7 +220,7 @@ func (pc *PlayContext) DeJSON(data []byte, c ClientInterface) (Model, error) { return ctx, nil } -// DeList deserializes a list of PlayContexts +// DeList deserializes a list of PlayContexts from JSON data. func (pc *PlayContext) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -237,7 +238,7 @@ func (pc *PlayContext) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// PlayContextsData represents play contexts data +// PlayContextsData represents play contexts data. type PlayContextsData struct { BaseModel Contexts []PlayContext `json:"contexts"` @@ -246,7 +247,7 @@ type PlayContextsData struct { PageSize int `json:"page_size"` } -// DeJSON deserializes PlayContextsData from JSON +// DeJSON deserializes PlayContextsData from JSON data. func (pcd *PlayContextsData) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -273,7 +274,7 @@ func (pcd *PlayContextsData) DeJSON(data []byte, c ClientInterface) (Model, erro return result, nil } -// DeList deserializes a list of PlayContextsData +// DeList deserializes a list of PlayContextsData from JSON data. func (pcd *PlayContextsData) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/radio.go b/internal/models/radio.go index 274f6b0..35eb54e 100644 --- a/internal/models/radio.go +++ b/internal/models/radio.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// RadioStation represents a radio station +// RadioStation represents a radio station from the Yandex Music API. type RadioStation struct { BaseModel ID string `json:"id"` @@ -16,7 +17,7 @@ type RadioStation struct { IsPersonal bool `json:"is_personal"` } -// DeJSON deserializes a RadioStation from JSON +// DeJSON deserializes a RadioStation from JSON data. func (r *RadioStation) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -50,7 +51,7 @@ func (r *RadioStation) DeJSON(data []byte, client ClientInterface) (Model, error return station, nil } -// DeList deserializes a list of RadioStations +// DeList deserializes a list of RadioStations from JSON data. func (r *RadioStation) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -68,7 +69,7 @@ func (r *RadioStation) DeList(data []byte, client ClientInterface) ([]Model, err return result, nil } -// StationTracksResult represents station tracks result +// StationTracksResult represents station tracks result. type StationTracksResult struct { BaseModel Tracks []Track `json:"tracks"` @@ -76,7 +77,7 @@ type StationTracksResult struct { Sequence string `json:"sequence"` } -// DeJSON deserializes StationTracksResult from JSON +// DeJSON deserializes StationTracksResult from JSON data. func (s *StationTracksResult) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -100,7 +101,7 @@ func (s *StationTracksResult) DeJSON(data []byte, client ClientInterface) (Model return result, nil } -// DeList deserializes a list of StationTracksResult +// DeList deserializes a list of StationTracksResult from JSON data. func (s *StationTracksResult) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -118,7 +119,7 @@ func (s *StationTracksResult) DeList(data []byte, client ClientInterface) ([]Mod return result, nil } -// RotorStation represents a rotor (generative) station +// RotorStation represents a rotor (generative) station. type RotorStation struct { BaseModel ID string `json:"id"` @@ -131,7 +132,7 @@ type RotorStation struct { Settings *RotorSettings `json:"settings"` } -// DeJSON deserializes a RotorStation from JSON +// DeJSON deserializes a RotorStation from JSON data. func (r *RotorStation) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -170,7 +171,7 @@ func (r *RotorStation) DeJSON(data []byte, client ClientInterface) (Model, error return station, nil } -// DeList deserializes a list of RotorStations +// DeList deserializes a list of RotorStations from JSON data. func (r *RotorStation) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -188,7 +189,7 @@ func (r *RotorStation) DeList(data []byte, client ClientInterface) ([]Model, err return result, nil } -// RotorSettings represents rotor station settings +// RotorSettings represents rotor station settings. type RotorSettings struct { BaseModel Diversity float64 `json:"diversity"` @@ -201,7 +202,7 @@ type RotorSettings struct { Valence float64 `json:"valence"` } -// RotorStationTracksResult represents rotor station tracks result +// RotorStationTracksResult represents rotor station tracks result. type RotorStationTracksResult struct { BaseModel Tracks []Track `json:"tracks"` @@ -209,7 +210,7 @@ type RotorStationTracksResult struct { Sequence string `json:"sequence"` } -// DeJSON deserializes RotorStationTracksResult from JSON +// DeJSON deserializes RotorStationTracksResult from JSON data. func (r *RotorStationTracksResult) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -233,7 +234,7 @@ func (r *RotorStationTracksResult) DeJSON(data []byte, client ClientInterface) ( return result, nil } -// DeList deserializes a list of RotorStationTracksResult +// DeList deserializes a list of RotorStationTracksResult from JSON data. func (r *RotorStationTracksResult) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -251,7 +252,7 @@ func (r *RotorStationTracksResult) DeList(data []byte, client ClientInterface) ( return result, nil } -// RotorSession represents a rotor session +// RotorSession represents a rotor session. type RotorSession struct { BaseModel SessionID string `json:"session_id"` @@ -262,7 +263,7 @@ type RotorSession struct { CreatedAt string `json:"created_at"` } -// DeJSON deserializes a RotorSession from JSON +// DeJSON deserializes a RotorSession from JSON data. func (r *RotorSession) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -295,7 +296,7 @@ func (r *RotorSession) DeJSON(data []byte, client ClientInterface) (Model, error return session, nil } -// DeList deserializes a list of RotorSessions +// DeList deserializes a list of RotorSessions from JSON data. func (r *RotorSession) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -313,7 +314,7 @@ func (r *RotorSession) DeList(data []byte, client ClientInterface) ([]Model, err return result, nil } -// SessionFeedback represents session feedback +// SessionFeedback represents session feedback. type SessionFeedback struct { BaseModel TrackID string `json:"track_id"` @@ -321,7 +322,7 @@ type SessionFeedback struct { Timestamp string `json:"timestamp"` } -// SessionFeedbacks represents multiple session feedbacks +// SessionFeedbacks represents multiple session feedbacks. type SessionFeedbacks struct { BaseModel Feedbacks []SessionFeedback `json:"feedbacks"` diff --git a/internal/models/search.go b/internal/models/search.go index b45b64c..af731f2 100644 --- a/internal/models/search.go +++ b/internal/models/search.go @@ -1,6 +1,7 @@ +// Package models provides data models for the Yandex Music API. package models -// SearchResult represents search results +// SearchResult represents search results from the Yandex Music API. type SearchResult struct { Tracks *SearchTracksResult `json:"tracks"` Albums *SearchAlbumsResult `json:"albums"` @@ -10,43 +11,43 @@ type SearchResult struct { Users *SearchUsersResult `json:"users"` } -// SearchTracksResult represents track search results +// SearchTracksResult represents track search results. type SearchTracksResult struct { Total int `json:"total"` Results []Track `json:"results"` } -// SearchAlbumsResult represents album search results +// SearchAlbumsResult represents album search results. type SearchAlbumsResult struct { Total int `json:"total"` Results []Album `json:"results"` } -// SearchArtistsResult represents artist search results +// SearchArtistsResult represents artist search results. type SearchArtistsResult struct { Total int `json:"total"` Results []Artist `json:"results"` } -// SearchPlaylistsResult represents playlist search results +// SearchPlaylistsResult represents playlist search results. type SearchPlaylistsResult struct { Total int `json:"total"` Results []Playlist `json:"results"` } -// SearchVideosResult represents video search results +// SearchVideosResult represents video search results. type SearchVideosResult struct { Total int `json:"total"` Results []Video `json:"results"` } -// SearchUsersResult represents user search results +// SearchUsersResult represents user search results. type SearchUsersResult struct { Total int `json:"total"` Results []User `json:"results"` } -// SearchBanner represents a search banner +// SearchBanner represents a search banner. type SearchBanner struct { ID string `json:"id"` Title string `json:"title"` @@ -57,7 +58,7 @@ type SearchBanner struct { Type string `json:"type"` } -// Tag represents a search tag +// Tag represents a search tag. type Tag struct { ID string `json:"id"` Title string `json:"title"` @@ -66,7 +67,7 @@ type Tag struct { Type string `json:"type"` } -// Video represents a video (minimal) +// Video represents a video (minimal). type Video struct { BaseModel ID string `json:"id"` diff --git a/internal/models/settings.go b/internal/models/settings.go index 11f422d..a4c878f 100644 --- a/internal/models/settings.go +++ b/internal/models/settings.go @@ -1,17 +1,18 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Experiments represents experiments +// Experiments represents experiments from the Yandex Music API. type Experiments struct { BaseModel Experiments []ExperimentDetail `json:"experiments"` Total int `json:"total"` } -// DeJSON deserializes Experiments from JSON +// DeJSON deserializes Experiments from JSON data. func (e *Experiments) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -32,7 +33,7 @@ func (e *Experiments) DeJSON(data []byte, client ClientInterface) (Model, error) return experiments, nil } -// DeList deserializes a list of Experiments +// DeList deserializes a list of Experiments from JSON data. func (e *Experiments) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -50,7 +51,7 @@ func (e *Experiments) DeList(data []byte, client ClientInterface) ([]Model, erro return result, nil } -// ExperimentDetail represents experiment details +// ExperimentDetail represents experiment details. type ExperimentDetail struct { BaseModel ID string `json:"id"` @@ -62,7 +63,7 @@ type ExperimentDetail struct { EndDate string `json:"end_date"` } -// DeJSON deserializes ExperimentDetail from JSON +// DeJSON deserializes ExperimentDetail from JSON data. func (e *ExperimentDetail) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -96,7 +97,7 @@ func (e *ExperimentDetail) DeJSON(data []byte, client ClientInterface) (Model, e return detail, nil } -// DeList deserializes a list of ExperimentDetails +// DeList deserializes a list of ExperimentDetails from JSON data. func (e *ExperimentDetail) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -114,7 +115,7 @@ func (e *ExperimentDetail) DeList(data []byte, client ClientInterface) ([]Model, return result, nil } -// Permissions represents user permissions +// Permissions represents user permissions. type Permissions struct { BaseModel CanPlay bool `json:"can_play"` @@ -129,7 +130,7 @@ type Permissions struct { CanUseLossless bool `json:"can_use_lossless"` } -// DeJSON deserializes Permissions from JSON +// DeJSON deserializes Permissions from JSON data. func (p *Permissions) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -172,7 +173,7 @@ func (p *Permissions) DeJSON(data []byte, client ClientInterface) (Model, error) return perms, nil } -// DeList deserializes a list of Permissions +// DeList deserializes a list of Permissions from JSON data. func (p *Permissions) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -190,14 +191,14 @@ func (p *Permissions) DeList(data []byte, client ClientInterface) ([]Model, erro return result, nil } -// PermissionAlerts represents permission alerts +// PermissionAlerts represents permission alerts. type PermissionAlerts struct { BaseModel Alerts []PermissionAlert `json:"alerts"` Total int `json:"total"` } -// DeJSON deserializes PermissionAlerts from JSON +// DeJSON deserializes PermissionAlerts from JSON data. func (p *PermissionAlerts) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -218,7 +219,7 @@ func (p *PermissionAlerts) DeJSON(data []byte, client ClientInterface) (Model, e return alerts, nil } -// DeList deserializes a list of PermissionAlerts +// DeList deserializes a list of PermissionAlerts from JSON data. from JSON data. func (p *PermissionAlerts) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -236,7 +237,7 @@ func (p *PermissionAlerts) DeList(data []byte, client ClientInterface) ([]Model, return result, nil } -// PermissionAlert represents a permission alert +// PermissionAlert represents a permission alert. type PermissionAlert struct { BaseModel ID string `json:"id"` @@ -248,7 +249,7 @@ type PermissionAlert struct { CreatedAt string `json:"created_at"` } -// DeJSON deserializes PermissionAlert from JSON +// DeJSON deserializes PermissionAlert from JSON data. func (p *PermissionAlert) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -300,7 +301,7 @@ func (p *PermissionAlert) DeList(data []byte, client ClientInterface) ([]Model, return result, nil } -// ContentRestrictions represents content restrictions +// ContentRestrictions represents content restrictions. type ContentRestrictions struct { BaseModel HasExplicitContent bool `json:"has_explicit_content"` @@ -311,7 +312,7 @@ type ContentRestrictions struct { BlockedArtists []string `json:"blocked_artists"` } -// DeJSON deserializes ContentRestrictions from JSON +// DeJSON deserializes ContentRestrictions from JSON data. func (c *ContentRestrictions) DeJSON(data []byte, client ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -342,7 +343,7 @@ func (c *ContentRestrictions) DeJSON(data []byte, client ClientInterface) (Model return restrictions, nil } -// DeList deserializes a list of ContentRestrictions +// DeList deserializes a list of ContentRestrictions from JSON data. func (c *ContentRestrictions) DeList(data []byte, client ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/supplement.go b/internal/models/supplement.go index 4c7f80d..bea004f 100644 --- a/internal/models/supplement.go +++ b/internal/models/supplement.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// LyricsMajor represents a lyrics provider (e.g., Genius, Musixmatch) +// LyricsMajor represents a lyrics provider (e.g., Genius, Musixmatch). type LyricsMajor struct { BaseModel ID int `json:"id"` @@ -12,7 +13,7 @@ type LyricsMajor struct { PrettyName string `json:"pretty_name"` } -// DeJSON deserializes LyricsMajor from JSON +// DeJSON deserializes LyricsMajor from JSON data. func (lm *LyricsMajor) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -34,7 +35,7 @@ func (lm *LyricsMajor) DeJSON(data []byte, c ClientInterface) (Model, error) { return major, nil } -// DeList deserializes a list of LyricsMajor +// DeList deserializes a list of LyricsMajor from JSON data. func (lm *LyricsMajor) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -52,7 +53,7 @@ func (lm *LyricsMajor) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// TrackLyrics represents lyrics information from /tracks/{id}/lyrics endpoint +// TrackLyrics represents lyrics information from /tracks/{id}/lyrics endpoint. type TrackLyrics struct { BaseModel DownloadURL string `json:"download_url"` @@ -62,7 +63,7 @@ type TrackLyrics struct { Major *LyricsMajor `json:"major"` } -// DeJSON deserializes TrackLyrics from JSON +// DeJSON deserializes TrackLyrics from JSON data. func (tl *TrackLyrics) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -92,7 +93,7 @@ func (tl *TrackLyrics) DeJSON(data []byte, c ClientInterface) (Model, error) { return lyrics, nil } -// DeList deserializes a list of TrackLyrics +// DeList deserializes a list of TrackLyrics from JSON data. func (tl *TrackLyrics) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -110,7 +111,7 @@ func (tl *TrackLyrics) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// SupplementLyrics represents the actual lyrics content (from supplement) +// SupplementLyrics represents the actual lyrics content from supplement. type SupplementLyrics struct { BaseModel ID int `json:"id"` @@ -123,7 +124,7 @@ type SupplementLyrics struct { Major *LyricsMajor `json:"major"` } -// DeJSON deserializes SupplementLyrics from JSON +// DeJSON deserializes SupplementLyrics from JSON data. func (l *SupplementLyrics) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -162,7 +163,7 @@ func (l *SupplementLyrics) DeJSON(data []byte, c ClientInterface) (Model, error) return lyrics, nil } -// DeList deserializes a list of SupplementLyrics +// DeList deserializes a list of SupplementLyrics from JSON data. func (l *SupplementLyrics) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -180,7 +181,7 @@ func (l *SupplementLyrics) DeList(data []byte, c ClientInterface) ([]Model, erro return result, nil } -// LyricsInfo represents lyrics availability information +// LyricsInfo represents lyrics availability information. type LyricsInfo struct { BaseModel TrackID string `json:"track_id"` @@ -196,7 +197,7 @@ type LyricsInfo struct { HasAvailableTextLyrics bool `json:"has_available_text_lyrics"` } -// DeJSON deserializes LyricsInfo from JSON +// DeJSON deserializes LyricsInfo from JSON data. func (li *LyricsInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -247,7 +248,7 @@ func (li *LyricsInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { return info, nil } -// DeList deserializes a list of LyricsInfo +// DeList deserializes a list of LyricsInfo from JSON data. func (li *LyricsInfo) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -265,7 +266,7 @@ func (li *LyricsInfo) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// VideoSupplement represents a video supplement (from supplement endpoint) +// VideoSupplement represents a video supplement from supplement endpoint. type VideoSupplement struct { BaseModel Cover string `json:"cover"` @@ -277,7 +278,7 @@ type VideoSupplement struct { Embed string `json:"embed"` } -// DeJSON deserializes VideoSupplement from JSON +// DeJSON deserializes VideoSupplement from JSON data. func (vs *VideoSupplement) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -311,7 +312,7 @@ func (vs *VideoSupplement) DeJSON(data []byte, c ClientInterface) (Model, error) return supp, nil } -// DeList deserializes a list of VideoSupplements +// DeList deserializes a list of VideoSupplements from JSON data. func (vs *VideoSupplement) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -329,7 +330,7 @@ func (vs *VideoSupplement) DeList(data []byte, c ClientInterface) ([]Model, erro return result, nil } -// Supplement represents a track supplement +// Supplement represents a track supplement. type Supplement struct { BaseModel ID string `json:"id"` @@ -340,7 +341,7 @@ type Supplement struct { Available bool `json:"available"` } -// DeJSON deserializes Supplement from JSON +// DeJSON deserializes Supplement from JSON data. func (s *Supplement) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -376,7 +377,7 @@ func (s *Supplement) DeJSON(data []byte, c ClientInterface) (Model, error) { return supp, nil } -// DeList deserializes a list of Supplements +// DeList deserializes a list of Supplements from JSON data. func (s *Supplement) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/models/track.go b/internal/models/track.go index ca97977..0b02ef1 100644 --- a/internal/models/track.go +++ b/internal/models/track.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// Track represents a full track +// Track represents a full track from the Yandex Music API. type Track struct { BaseModel ID string `json:"id"` @@ -27,7 +28,7 @@ type Track struct { DownloadInfo []DownloadInfo `json:"download_info"` } -// DeJSON deserializes a Track from JSON +// DeJSON deserializes a Track from JSON data. func (t *Track) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -115,7 +116,7 @@ func (t *Track) DeJSON(data []byte, c ClientInterface) (Model, error) { return track, nil } -// DeList deserializes a list of Tracks +// DeList deserializes a list of Tracks from JSON data. func (t *Track) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -133,7 +134,7 @@ func (t *Track) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// GetDownloadInfo returns download info for a specific quality +// GetDownloadInfo returns download info for a specific quality, or nil if not found. func (t *Track) GetDownloadInfo(quality string) *DownloadInfo { for _, info := range t.DownloadInfo { if info.Quality == quality { @@ -146,14 +147,14 @@ func (t *Track) GetDownloadInfo(quality string) *DownloadInfo { // Note: Artist and Album types are defined in their respective files // These are imported automatically since they're in the same package -// Major represents major info +// Major represents major label info for a track. type Major struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description"` } -// TrackLyricsInfo represents minimal lyrics info for a track +// TrackLyricsInfo represents minimal lyrics info for a track. type TrackLyricsInfo struct { ID string `json:"id"` Text string `json:"text"` @@ -162,7 +163,7 @@ type TrackLyricsInfo struct { HasText bool `json:"has_text"` } -// DownloadInfo represents file download info +// DownloadInfo represents file download info for a track. type DownloadInfo struct { Quality string `json:"quality"` Codec string `json:"codec"` diff --git a/internal/models/track_short.go b/internal/models/track_short.go index e7f4d84..a50a886 100644 --- a/internal/models/track_short.go +++ b/internal/models/track_short.go @@ -1,10 +1,11 @@ +// Package models provides data models for the Yandex Music API. package models import ( "encoding/json" ) -// TrackShort represents a lightweight track (used in lists) +// TrackShort represents a lightweight track used in lists. type TrackShort struct { BaseModel ID string `json:"id"` @@ -31,7 +32,7 @@ type TrackShort struct { RingtoneID string `json:"ringtone_id"` } -// DeJSON deserializes a TrackShort from JSON +// DeJSON deserializes a TrackShort from JSON data. func (t *TrackShort) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -131,7 +132,7 @@ func (t *TrackShort) DeJSON(data []byte, c ClientInterface) (Model, error) { return track, nil } -// DeList deserializes a list of TrackShort +// DeList deserializes a list of TrackShort from JSON data. func (t *TrackShort) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { @@ -149,7 +150,7 @@ func (t *TrackShort) DeList(data []byte, c ClientInterface) ([]Model, error) { return result, nil } -// TracksList represents a list of tracks with metadata +// TracksList represents a list of tracks with metadata. type TracksList struct { BaseModel Tracks []TrackShort `json:"tracks"` @@ -159,7 +160,7 @@ type TracksList struct { Pager *Pager `json:"pager"` } -// DeJSON deserializes a TracksList from JSON +// DeJSON deserializes a TracksList from JSON data. func (t *TracksList) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { @@ -193,7 +194,7 @@ func (t *TracksList) DeJSON(data []byte, c ClientInterface) (Model, error) { return list, nil } -// DeList deserializes a list of TracksList +// DeList deserializes a list of TracksList from JSON data. func (t *TracksList) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { diff --git a/internal/utils/json.go b/internal/utils/json.go index f433c97..1b084ef 100644 --- a/internal/utils/json.go +++ b/internal/utils/json.go @@ -1,3 +1,4 @@ +// Package utils provides utility functions for the Yandex Music API client. package utils import ( @@ -6,42 +7,49 @@ import ( "strings" ) -// JSONBackend defines the interface for JSON encoding/decoding +// JSONBackend defines the interface for JSON encoding/decoding. +// Implementations can use encoding/json, json-iterator, or other backends. type JSONBackend interface { + // Marshal encodes a Go value to JSON. Marshal(v any) ([]byte, error) + // Unmarshal decodes JSON data into a Go value. Unmarshal(data []byte, v any) error } -// DefaultJSONBackend uses the standard library encoding/json +// DefaultJSONBackend uses the standard library encoding/json. type DefaultJSONBackend struct{} +// Marshal encodes a Go value to JSON using encoding/json. func (DefaultJSONBackend) Marshal(v any) ([]byte, error) { return json.Marshal(v) } +// Unmarshal decodes JSON data into a Go value using encoding/json. func (DefaultJSONBackend) Unmarshal(data []byte, v any) error { return json.Unmarshal(data, v) } -// GetDefaultJSONBackend returns the default JSON backend +// GetDefaultJSONBackend returns the default JSON backend (encoding/json). func GetDefaultJSONBackend() JSONBackend { return DefaultJSONBackend{} } -// RawMessage is a raw encoded JSON value +// RawMessage is a raw encoded JSON value. +// It is an alias for encoding/json.RawMessage. type RawMessage = json.RawMessage -// Marshal is a convenience function +// Marshal is a convenience function that marshals a value using the default JSON backend. func Marshal(v any) ([]byte, error) { return GetDefaultJSONBackend().Marshal(v) } -// Unmarshal is a convenience function +// Unmarshal is a convenience function that unmarshals data using the default JSON backend. func Unmarshal(data []byte, v any) error { return GetDefaultJSONBackend().Unmarshal(data, v) } -// ToSnakeCase converts camelCase to snake_case +// ToSnakeCase converts camelCase to snake_case. +// For example, "camelCase" becomes "camel_case". func ToSnakeCase(s string) string { if s == "" { return s @@ -60,7 +68,8 @@ func ToSnakeCase(s string) string { return result.String() } -// ToCamelCase converts snake_case to camelCase +// ToCamelCase converts snake_case to camelCase. +// For example, "snake_case" becomes "snakeCase". func ToCamelCase(s string) string { if s == "" { return s @@ -79,7 +88,7 @@ func ToCamelCase(s string) string { return result.String() } -// MapKeysToSnakeCase converts all keys in a map to snake_case +// MapKeysToSnakeCase converts all keys in a map to snake_case. func MapKeysToSnakeCase(m map[string]any) map[string]any { result := make(map[string]any, len(m)) for k, v := range m { @@ -88,7 +97,7 @@ func MapKeysToSnakeCase(m map[string]any) map[string]any { return result } -// MapKeysToCamelCase converts all keys in a map to camelCase +// MapKeysToCamelCase converts all keys in a map to camelCase. func MapKeysToCamelCase(m map[string]any) map[string]any { result := make(map[string]any, len(m)) for k, v := range m { @@ -97,7 +106,8 @@ func MapKeysToCamelCase(m map[string]any) map[string]any { return result } -// StructToMap converts a struct to a map using json tags +// StructToMap converts a struct to a map using json tags. +// The forRequest parameter is currently unused but reserved for future use. func StructToMap(v any, forRequest bool) (map[string]any, error) { data, err := Marshal(v) if err != nil { @@ -110,7 +120,8 @@ func StructToMap(v any, forRequest bool) (map[string]any, error) { return result, nil } -// GetJSONTag returns the json tag for a struct field +// GetJSONTag returns the json tag name for a struct field at the given index. +// It returns an empty string if the field has no json tag or the tag is "-". func GetJSONTag(t reflect.Type, fieldIndex int) string { if fieldIndex >= t.NumField() { return "" diff --git a/internal/utils/response.go b/internal/utils/response.go index 217e96d..23b0bb7 100644 --- a/internal/utils/response.go +++ b/internal/utils/response.go @@ -1,3 +1,4 @@ +// Package utils provides utility functions for the Yandex Music API client. package utils import ( @@ -5,19 +6,20 @@ import ( "errors" ) -// Response represents an API response +// Response represents an API response from the Yandex Music API. type Response struct { Result json.RawMessage `json:"result"` Error string `json:"error,omitempty"` ErrorDescription string `json:"errorDescription,omitempty"` } -// GetResult returns the result as raw JSON +// GetResult returns the result as raw JSON. func (r *Response) GetResult() json.RawMessage { return r.Result } -// GetError returns the error message +// GetError returns the error message from the response. +// It returns Error if set, otherwise ErrorDescription, or "Unknown error" if neither is set. func (r *Response) GetError() string { if r.Error != "" { return r.Error @@ -28,12 +30,13 @@ func (r *Response) GetError() string { return "Unknown error" } -// HasError returns true if the response contains an error +// HasError returns true if the response contains an error. func (r *Response) HasError() bool { return r.Error != "" || r.ErrorDescription != "" } -// UnmarshalJSON implements custom unmarshaling +// UnmarshalJSON implements custom unmarshaling for Response. +// If result is missing, the whole response is wrapped in result. func (r *Response) UnmarshalJSON(data []byte) error { // First try to unmarshal as a standard response type Alias Response @@ -53,7 +56,7 @@ func (r *Response) UnmarshalJSON(data []byte) error { return nil } -// DeJSON creates a Response from JSON data +// DeJSON creates a Response from JSON data. func DeJSON(data []byte) (*Response, error) { var resp Response if err := json.Unmarshal(data, &resp); err != nil { @@ -62,22 +65,30 @@ func DeJSON(data []byte) (*Response, error) { return &resp, nil } -// Error types +// Error types for the Yandex Music API client. var ( - ErrUnauthorized = errors.New("unauthorized") - ErrBadRequest = errors.New("bad request") - ErrNotFound = errors.New("not found") - ErrNetwork = errors.New("network error") - ErrTimeout = errors.New("timeout") + // ErrUnauthorized is returned when authentication fails (HTTP 401/403). + ErrUnauthorized = errors.New("unauthorized") + // ErrBadRequest is returned when the request is malformed (HTTP 400). + ErrBadRequest = errors.New("bad request") + // ErrNotFound is returned when the requested resource is not found (HTTP 404). + ErrNotFound = errors.New("not found") + // ErrNetwork is returned for network-related errors. + ErrNetwork = errors.New("network error") + // ErrTimeout is returned when a request times out. + ErrTimeout = errors.New("timeout") + // ErrSchemaMismatch is returned when the API response schema doesn't match expectations. ErrSchemaMismatch = errors.New("schema mismatch") ) -// YandexMusicError is the base error type +// YandexMusicError is the base error type for Yandex Music API errors. +// It wraps an underlying error with a descriptive message. type YandexMusicError struct { Message string Err error } +// Error returns the error message, including the wrapped error if present. func (e *YandexMusicError) Error() string { if e.Err != nil { return e.Message + ": " + e.Err.Error() @@ -85,16 +96,17 @@ func (e *YandexMusicError) Error() string { return e.Message } +// Unwrap returns the underlying error for compatibility with errors.Is and errors.As. func (e *YandexMusicError) Unwrap() error { return e.Err } -// NewYandexMusicError creates a new YandexMusicError +// NewYandexMusicError creates a new YandexMusicError with the given message and underlying error. func NewYandexMusicError(message string, err error) *YandexMusicError { return &YandexMusicError{Message: message, Err: err} } -// IsUnauthorizedError checks if error is unauthorized +// IsUnauthorizedError checks if an error is an unauthorized error. func IsUnauthorizedError(err error) bool { var yme *YandexMusicError if errors.As(err, &yme) { @@ -103,7 +115,7 @@ func IsUnauthorizedError(err error) bool { return errors.Is(err, ErrUnauthorized) } -// IsBadRequestError checks if error is bad request +// IsBadRequestError checks if an error is a bad request error. func IsBadRequestError(err error) bool { var yme *YandexMusicError if errors.As(err, &yme) { @@ -112,7 +124,7 @@ func IsBadRequestError(err error) bool { return errors.Is(err, ErrBadRequest) } -// IsNotFoundError checks if error is not found +// IsNotFoundError checks if an error is a not found error. func IsNotFoundError(err error) bool { var yme *YandexMusicError if errors.As(err, &yme) { @@ -121,7 +133,7 @@ func IsNotFoundError(err error) bool { return errors.Is(err, ErrNotFound) } -// IsNetworkError checks if error is network error +// IsNetworkError checks if an error is a network error. func IsNetworkError(err error) bool { var yme *YandexMusicError if errors.As(err, &yme) { @@ -130,7 +142,7 @@ func IsNetworkError(err error) bool { return errors.Is(err, ErrNetwork) } -// IsTimeoutError checks if error is timeout +// IsTimeoutError checks if an error is a timeout error. func IsTimeoutError(err error) bool { var yme *YandexMusicError if errors.As(err, &yme) { diff --git a/internal/utils/schema.go b/internal/utils/schema.go index adeec71..41ab124 100644 --- a/internal/utils/schema.go +++ b/internal/utils/schema.go @@ -9,16 +9,24 @@ import ( "sync" ) -// SchemaMismatch represents a mismatch between expected and actual API response +// SchemaMismatch represents a mismatch between expected and actual API response. +// It captures details about missing fields, unknown fields, and unknown values. type SchemaMismatch struct { - ModelName string - MissingFields []string - UnknownFields []string - UnknownValues map[string]any - Endpoint string + // ModelName is the name of the model that had the mismatch. + ModelName string + // MissingFields lists fields that were expected but not found in the response. + MissingFields []string + // UnknownFields lists fields that were not expected but found in the response. + UnknownFields []string + // UnknownValues maps unknown field names to their values. + UnknownValues map[string]any + // Endpoint is the API endpoint where the mismatch occurred. + Endpoint string + // LibraryVersion is the version of the library when the mismatch occurred. LibraryVersion string } +// Describe returns a human-readable description of the schema mismatch. func (sm *SchemaMismatch) Describe() string { var parts []string parts = append(parts, fmt.Sprintf("Model: %s", sm.ModelName)) @@ -36,17 +44,22 @@ func (sm *SchemaMismatch) Describe() string { return strings.Join(parts, "\n") } -// SchemaMismatchHandler is a callback for handling schema mismatches +// SchemaMismatchHandler is a callback for handling schema mismatches. +// It is invoked when a schema mismatch is detected, if configured. type SchemaMismatchHandler func(*SchemaMismatch) -// SchemaMismatchConfig holds configuration for schema mismatch handling +// SchemaMismatchConfig holds configuration for schema mismatch handling. type SchemaMismatchConfig struct { + // ReportUnknownFields indicates whether unknown fields should be reported. ReportUnknownFields bool - Strict bool - OnSchemaMismatch SchemaMismatchHandler + // Strict indicates whether schema mismatches should be treated as errors. + Strict bool + // OnSchemaMismatch is an optional callback for custom mismatch handling. + OnSchemaMismatch SchemaMismatchHandler } -// DefaultSchemaMismatchConfig returns the default configuration +// DefaultSchemaMismatchConfig returns the default configuration for schema mismatch handling. +// The default config does not report unknown fields, is not strict, and has no callback. func DefaultSchemaMismatchConfig() SchemaMismatchConfig { return SchemaMismatchConfig{ ReportUnknownFields: false, @@ -55,7 +68,9 @@ func DefaultSchemaMismatchConfig() SchemaMismatchConfig { } } -// ReportSchemaMismatch reports a schema mismatch according to config +// ReportSchemaMismatch reports a schema mismatch according to the provided config. +// If a callback is configured, it is invoked with the mismatch details. +// If strict mode is enabled, an error is returned. Otherwise, a warning is logged. func ReportSchemaMismatch(config SchemaMismatchConfig, modelName, endpoint string, missingFields, unknownFields []string, unknownValues map[string]any) error { mismatch := &SchemaMismatch{ ModelName: modelName, @@ -80,18 +95,22 @@ func ReportSchemaMismatch(config SchemaMismatchConfig, modelName, endpoint strin return nil } -// SchemaMismatchTracker tracks reported mismatches to avoid duplicates +// SchemaMismatchTracker tracks reported mismatches to avoid duplicate reports. +// It is safe for concurrent use. type SchemaMismatchTracker struct { mu sync.Mutex reported map[string]bool } +// NewSchemaMismatchTracker creates a new SchemaMismatchTracker. func NewSchemaMismatchTracker() *SchemaMismatchTracker { return &SchemaMismatchTracker{ reported: make(map[string]bool), } } +// ShouldReport returns true if the given model and fields have not been reported before. +// It marks them as reported so subsequent calls return false for the same key. func (t *SchemaMismatchTracker) ShouldReport(modelName string, fields []string) bool { t.mu.Lock() defer t.mu.Unlock() diff --git a/internal/utils/sign.go b/internal/utils/sign.go index d9ab993..deb5197 100644 --- a/internal/utils/sign.go +++ b/internal/utils/sign.go @@ -1,3 +1,4 @@ +// Package utils provides utility functions for the Yandex Music API client. package utils import ( @@ -10,21 +11,23 @@ import ( ) const ( - // DefaultSignKey is the signing key from the Android app + // DefaultSignKey is the signing key from the Android app. DefaultSignKey = "p93jhgh689SBReK6ghtw62" - // DesktopSignKey is the signing key from the desktop app + // DesktopSignKey is the signing key from the desktop app. DesktopSignKey = "kzqU4XhfCaY6B6JTHODeq5" - // DesktopClient is the X-Yandex-Music-Client header value for desktop + // DesktopClient is the X-Yandex-Music-Client header value for desktop. DesktopClient = "YandexMusicDesktopAppWindows/5.95.0" ) -// Sign represents a request signature +// Sign represents a request signature for signed API requests. type Sign struct { Timestamp int64 Value string } -// GetSignRequest creates a signature for a track request +// 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 @@ -43,7 +46,9 @@ func GetSignRequest(trackID string, key string) Sign { } } -// GetFileInfoSign creates a signature for file info requests +// 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 @@ -66,6 +71,7 @@ func GetFileInfoSign(trackID, quality string, codecs []string, transport, key st } } +// joinCodecs joins a list of codec strings into a single string. func joinCodecs(codecs []string) string { result := "" for _, c := range codecs { diff --git a/internal/ynison/client.go b/internal/ynison/client.go index 55702a7..3c1297d 100644 --- a/internal/ynison/client.go +++ b/internal/ynison/client.go @@ -1,5 +1,4 @@ -// Package ynison provides a WebSocket client for the Yandex Music Ynison protocol, -// enabling real-time player synchronization across devices. +// Package ynison provides a Ynison WebSocket client for player synchronization across devices. package ynison import ( @@ -14,7 +13,7 @@ import ( "github.com/gorilla/websocket" ) -// YnisonClient represents a Ynison WebSocket client +// YnisonClient represents a Ynison WebSocket client for player synchronization across devices. type YnisonClient struct { client *client.Client conn *websocket.Conn @@ -30,7 +29,7 @@ type YnisonClient struct { closeOnce sync.Once // Ensures doneCh is closed only once } -// DeviceConfig holds device configuration for Ynison +// DeviceConfig holds device configuration for Ynison WebSocket connections. type DeviceConfig struct { DeviceID string Title string @@ -42,7 +41,8 @@ type DeviceConfig struct { VolumeGran int } -// NewYnisonClient creates a new Ynison client +// NewYnisonClient creates a new Ynison client with the given client and device config. +// Default values are applied for empty fields. func NewYnisonClient(c *client.Client, config DeviceConfig) *YnisonClient { if config.DeviceID == "" { config.DeviceID = fmt.Sprintf("go-ynison-%d", time.Now().UnixNano()) @@ -69,7 +69,8 @@ func NewYnisonClient(c *client.Client, config DeviceConfig) *YnisonClient { } } -// Connect establishes a WebSocket connection to Ynison +// Connect establishes a WebSocket connection to the Ynison service. +// It sends an initial full state update after connecting. func (y *YnisonClient) Connect(ctx context.Context) error { token := y.client.GetToken() if token == "" { @@ -97,12 +98,12 @@ func (y *YnisonClient) Connect(ctx context.Context) error { return y.sendUpdateFullState(ctx) } -// overrideWSURL sets a custom WebSocket URL for testing +// overrideWSURL sets a custom WebSocket URL for testing purposes. func (y *YnisonClient) overrideWSURL(url string) { y.wsURL = url } -// Disconnect closes the WebSocket connection +// Disconnect closes the WebSocket connection and cleans up resources. func (y *YnisonClient) Disconnect() error { y.mu.Lock() defer y.mu.Unlock() @@ -119,7 +120,7 @@ func (y *YnisonClient) Disconnect() error { return nil } -// IsConnected returns true if the client is connected +// IsConnected returns true if the client is currently connected to the Ynison service. func (y *YnisonClient) IsConnected() bool { y.mu.Lock() defer y.mu.Unlock() @@ -278,21 +279,22 @@ func (y *YnisonClient) sendRequest(ctx context.Context, req *proto.PutYnisonStat return y.conn.WriteMessage(websocket.TextMessage, data) } -// RegisterHandler registers a response handler +// RegisterHandler registers a response handler for the given name. +// Handlers are invoked when a PutYnisonStateResponse is received from the server. func (y *YnisonClient) RegisterHandler(name string, handler func(*proto.PutYnisonStateResponse)) { y.mu.Lock() defer y.mu.Unlock() y.handlers[name] = handler } -// UnregisterHandler removes a response handler +// UnregisterHandler removes a previously registered response handler by name. func (y *YnisonClient) UnregisterHandler(name string) { y.mu.Lock() defer y.mu.Unlock() delete(y.handlers, name) } -// UpdatePlayingStatus updates the playing status +// UpdatePlayingStatus updates the playing status on the Ynison server. func (y *YnisonClient) UpdatePlayingStatus(ctx context.Context, status *proto.PlayingStatus) error { req := &proto.PutYnisonStateRequest{ UpdatePlayingStatus: &proto.UpdatePlayingStatus{ @@ -304,7 +306,7 @@ func (y *YnisonClient) UpdatePlayingStatus(ctx context.Context, status *proto.Pl return y.sendRequest(ctx, req) } -// UpdateVolume updates the volume +// UpdateVolume updates the volume for a device on the Ynison server. func (y *YnisonClient) UpdateVolume(ctx context.Context, deviceID string, volume float64, version *proto.UpdateVersion) error { req := &proto.PutYnisonStateRequest{ UpdateVolumeInfo: &proto.UpdateVolumeInfo{ @@ -320,7 +322,7 @@ func (y *YnisonClient) UpdateVolume(ctx context.Context, deviceID string, volume return y.sendRequest(ctx, req) } -// UpdateActiveDevice updates the active device +// UpdateActiveDevice updates the active device on the Ynison server. func (y *YnisonClient) UpdateActiveDevice(ctx context.Context, deviceID string) error { req := &proto.PutYnisonStateRequest{ UpdateActiveDevice: &proto.UpdateActiveDevice{ @@ -332,7 +334,7 @@ func (y *YnisonClient) UpdateActiveDevice(ctx context.Context, deviceID string) return y.sendRequest(ctx, req) } -// UpdatePlayerState updates the player state (queue, repeat, shuffle) +// UpdatePlayerState updates the player state (queue, repeat, shuffle) on the Ynison server. func (y *YnisonClient) UpdatePlayerState(ctx context.Context, state *proto.PlayerState) error { req := &proto.PutYnisonStateRequest{ UpdatePlayerState: &proto.UpdatePlayerState{ @@ -344,7 +346,7 @@ func (y *YnisonClient) UpdatePlayerState(ctx context.Context, state *proto.Playe return y.sendRequest(ctx, req) } -// UpdatePlayerQueueInject updates the injected queue entity +// UpdatePlayerQueueInject updates the injected queue entity on the Ynison server. func (y *YnisonClient) UpdatePlayerQueueInject(ctx context.Context, inject *proto.PlayerQueueInject) error { req := &proto.PutYnisonStateRequest{ UpdatePlayerQueueInject: &proto.UpdatePlayerQueueInject{ @@ -356,7 +358,7 @@ func (y *YnisonClient) UpdatePlayerQueueInject(ctx context.Context, inject *prot return y.sendRequest(ctx, req) } -// SyncStateFromEOV requests synchronization from EOV +// SyncStateFromEOV requests synchronization from EOV (End of Verification). func (y *YnisonClient) SyncStateFromEOV(ctx context.Context, actualQueueID string) error { req := &proto.PutYnisonStateRequest{ SyncStateFromEov: &proto.SyncStateFromEOV{ @@ -368,25 +370,25 @@ func (y *YnisonClient) SyncStateFromEOV(ctx context.Context, actualQueueID strin return y.sendRequest(ctx, req) } -// GetDevices returns the list of connected devices from the last response +// GetDevices returns the list of connected devices from the last response. func (y *YnisonClient) GetDevices() []*proto.Device { // This would need to be implemented with proper state tracking return nil } -// GetActiveDeviceID returns the active device ID from the last response +// GetActiveDeviceID returns the active device ID from the last response. func (y *YnisonClient) GetActiveDeviceID() string { // This would need to be implemented with proper state tracking return "" } -// GetPlayerState returns the current player state from the last response +// GetPlayerState returns the current player state from the last response. func (y *YnisonClient) GetPlayerState() *proto.PlayerState { // This would need to be implemented with proper state tracking return nil } -// WaitForConnection waits for the connection to be established or context to be done +// WaitForConnection waits for the connection to be established or the context to be done. func (y *YnisonClient) WaitForConnection(ctx context.Context) error { select { case <-ctx.Done(): diff --git a/internal/ynison/helpers.go b/internal/ynison/helpers.go index 15e7cf1..8bacc21 100644 --- a/internal/ynison/helpers.go +++ b/internal/ynison/helpers.go @@ -1,3 +1,4 @@ +// Package ynison provides a Ynison WebSocket client for player synchronization. package ynison import ( @@ -6,7 +7,8 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/ynison/proto" ) -// CreatePlayingStatus creates a playing status +// CreatePlayingStatus creates a playing status with the given parameters. +// The version timestamp is set to the current time. func CreatePlayingStatus(progressMs, durationMs int64, paused bool, playbackSpeed float64, deviceID string) *proto.PlayingStatus { return &proto.PlayingStatus{ ProgressMs: progressMs, @@ -21,7 +23,7 @@ func CreatePlayingStatus(progressMs, durationMs int64, paused bool, playbackSpee } } -// CreatePlayable creates a playable entity +// CreatePlayable creates a playable entity with the given parameters. func CreatePlayable(playableID, albumID, from, title, coverURL string, playableType proto.PlayablePlayableType) *proto.Playable { return &proto.Playable{ PlayableId: playableID, @@ -33,7 +35,7 @@ func CreatePlayable(playableID, albumID, from, title, coverURL string, playableT } } -// CreateTrackPlayable creates a track playable +// CreateTrackPlayable creates a track playable with the given parameters. func CreateTrackPlayable(playableID, albumID, from, title, coverURL string, trackSourceKey uint32, batchID string) *proto.Playable { return &proto.Playable{ PlayableId: playableID, @@ -49,7 +51,7 @@ func CreateTrackPlayable(playableID, albumID, from, title, coverURL string, trac } } -// CreateVideoClipPlayable creates a video clip playable +// CreateVideoClipPlayable creates a video clip playable with the given parameters. func CreateVideoClipPlayable(playableID, from, title, coverURL string, recommendationType proto.VideoClipInfoRecommendationType) *proto.Playable { return &proto.Playable{ PlayableId: playableID, @@ -63,7 +65,7 @@ func CreateVideoClipPlayable(playableID, from, title, coverURL string, recommend } } -// CreatePlayerQueue creates a player queue +// CreatePlayerQueue creates a player queue with the given parameters. func CreatePlayerQueue(entityID string, entityType proto.PlayerQueueEntityType, playables []*proto.Playable, currentIndex int32, deviceID string) *proto.PlayerQueue { return &proto.PlayerQueue{ EntityId: entityID, @@ -82,7 +84,7 @@ func CreatePlayerQueue(entityID string, entityType proto.PlayerQueueEntityType, } } -// CreateWaveQueue creates a wave queue +// CreateWaveQueue creates a wave queue with the given parameters. func CreateWaveQueue(recommended []*proto.Playable, liveIndex int32, sessionID string, deviceID string) *proto.PlayerQueueQueue { // Build track sources from playables var trackSources []*proto.PlayerQueueQueueWaveQueueEntityOptionsTrackSourceWithKey @@ -111,7 +113,7 @@ func CreateWaveQueue(recommended []*proto.Playable, liveIndex int32, sessionID s } } -// CreateGenerativeQueue creates a generative queue +// CreateGenerativeQueue creates a generative queue with the given ID. func CreateGenerativeQueue(id string) *proto.PlayerQueueQueue { return &proto.PlayerQueueQueue{ GenerativeQueue: &proto.PlayerQueueQueueGenerativeQueue{ diff --git a/yandexmusic/client.go b/yandexmusic/client.go index fb75546..98b7ac3 100644 --- a/yandexmusic/client.go +++ b/yandexmusic/client.go @@ -1,3 +1,5 @@ +// Package yandexmusic provides the public API for the Yandex Music Go client. +// It re-exports types and functions from the internal packages for convenient use. package yandexmusic import ( @@ -7,313 +9,313 @@ import ( "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/ynison" ) -// ClientConfig holds configuration for the Client +// ClientConfig holds configuration for the Client. type ClientConfig = client.ClientConfig -// Client is the main Yandex Music API client +// Client is the main Yandex Music API client. type Client = client.Client -// NewClient creates a new Yandex Music client +// NewClient creates a new Yandex Music client with the given configuration. func NewClient(config ClientConfig) *Client { return client.NewClient(config) } -// Request is the HTTP request handler +// Request is the HTTP request handler. type Request = client.Request -// DeviceCode represents the device authorization response +// DeviceCode represents the device authorization response. type DeviceCode = client.DeviceCode -// OAuthToken represents an OAuth token response +// OAuthToken represents an OAuth token response. type OAuthToken = client.OAuthToken -// Status represents account status +// Status represents account status. type Status = client.Status -// Account represents a user account +// Account represents a user account. type Account = client.Account -// Track represents a music track +// Track represents a music track. type Track = models.Track -// Artist represents an artist +// Artist represents an artist. type Artist = models.Artist -// Album represents an album +// Album represents an album. type Album = models.Album -// Playlist represents a playlist +// Playlist represents a playlist. type Playlist = models.Playlist -// User represents a user +// User represents a user. type User = models.User -// DownloadInfo represents file download info +// DownloadInfo represents file download info. type DownloadInfo = models.DownloadInfo -// SupplementLyrics represents lyrics content from supplement +// SupplementLyrics represents lyrics content from supplement. type SupplementLyrics = models.SupplementLyrics -// Major represents major label info +// Major represents major label info. type Major = models.Major -// Label represents a label +// Label represents a label. type Label = models.Label -// Availability represents availability info +// Availability represents availability info. type Availability = models.Availability -// Upsell represents upsell info +// Upsell represents upsell info. type Upsell = models.Upsell -// AlbumMeta represents album metadata +// AlbumMeta represents album metadata. type AlbumMeta = models.AlbumMeta -// Best represents best tracks info +// Best represents best tracks info. type Best = models.Best -// Ratings represents artist ratings +// Ratings represents artist ratings. type Ratings = models.Ratings -// Counts represents artist counts +// Counts represents artist counts. type Counts = models.Counts -// TrackShort represents a lightweight track +// TrackShort represents a lightweight track. type TrackShort = models.TrackShort -// TracksList represents a list of tracks with metadata +// TracksList represents a list of tracks with metadata. type TracksList = models.TracksList -// Pager represents pagination info +// Pager represents pagination info. type Pager = models.Pager -// TrackPosition represents track position +// TrackPosition represents track position. type TrackPosition = models.TrackPosition -// TrailerInfo represents trailer info +// TrailerInfo represents trailer info. type TrailerInfo = models.TrailerInfo -// Cover represents cover image info +// Cover represents cover image info. type Cover = models.Cover -// ArtistBriefInfo represents brief artist info +// ArtistBriefInfo represents brief artist info. type ArtistBriefInfo = models.ArtistBriefInfo -// ArtistDonations represents artist donations info +// ArtistDonations represents artist donations info. type ArtistDonations = models.ArtistDonations -// DonationItem represents a donation item +// DonationItem represents a donation item. type DonationItem = models.DonationItem -// Concert represents a concert (minimal) +// Concert represents a concert (minimal). type Concert = models.Concert -// Clip represents a clip (short video) +// Clip represents a clip (short video). type Clip = models.Clip -// SearchResult represents search results +// SearchResult represents search results. type SearchResult = models.SearchResult -// SearchTracksResult represents track search results +// SearchTracksResult represents track search results. type SearchTracksResult = models.SearchTracksResult -// SearchAlbumsResult represents album search results +// SearchAlbumsResult represents album search results. type SearchAlbumsResult = models.SearchAlbumsResult -// SearchArtistsResult represents artist search results +// SearchArtistsResult represents artist search results. type SearchArtistsResult = models.SearchArtistsResult -// SearchPlaylistsResult represents playlist search results +// SearchPlaylistsResult represents playlist search results. type SearchPlaylistsResult = models.SearchPlaylistsResult -// SearchVideosResult represents video search results +// SearchVideosResult represents video search results. type SearchVideosResult = models.SearchVideosResult -// SearchUsersResult represents user search results +// SearchUsersResult represents user search results. type SearchUsersResult = models.SearchUsersResult -// SearchBanner represents a search banner +// SearchBanner represents a search banner. type SearchBanner = models.SearchBanner -// Tag represents a search tag +// Tag represents a search tag. type Tag = models.Tag -// Video represents a video +// Video represents a video. type Video = models.Video -// ChartInfoMenu represents a chart info menu +// ChartInfoMenu represents a chart info menu. type ChartInfoMenu = models.ChartInfoMenu -// ChartInfoMenuItem represents a chart info menu item +// ChartInfoMenuItem represents a chart info menu item. type ChartInfoMenuItem = models.ChartInfoMenuItem -// ChartItems represents chart items response +// ChartItems represents chart items response. type ChartItems = models.ChartItems -// AccountSettings represents account settings +// AccountSettings represents account settings. type AccountSettings = models.AccountSettings -// Subscription represents subscription info +// Subscription represents subscription info. type Subscription = models.Subscription -// PlusInfo represents Plus subscription info +// PlusInfo represents Plus subscription info. type PlusInfo = models.PlusInfo -// PromoCodeStatus represents promo code status +// PromoCodeStatus represents promo code status. type PromoCodeStatus = models.PromoCodeStatus -// Queue represents a playback queue +// Queue represents a playback queue. type Queue = models.Queue -// QueueItem represents a queue item +// QueueItem represents a queue item. type QueueItem = models.QueueItem -// PlayContext represents a play context +// PlayContext represents a play context. type PlayContext = models.PlayContext -// PlayContextsData represents play contexts data +// PlayContextsData represents play contexts data. type PlayContextsData = models.PlayContextsData -// Feed represents the main feed +// Feed represents the main feed. type Feed = models.Feed -// Day represents a day in the feed +// Day represents a day in the feed. type Day = models.Day -// DayBlock represents a block in a day +// DayBlock represents a block in a day. type DayBlock = models.DayBlock -// DayBlockData represents data in a day block +// DayBlockData represents data in a day block. type DayBlockData = models.DayBlockData -// GeneratedPlaylist represents a generated playlist +// GeneratedPlaylist represents a generated playlist. type GeneratedPlaylist = models.GeneratedPlaylist -// Event represents a feed event +// Event represents a feed event. type Event = models.Event -// AlbumEvent represents an album event +// AlbumEvent represents an album event. type AlbumEvent = models.AlbumEvent -// ArtistEvent represents an artist event +// ArtistEvent represents an artist event. type ArtistEvent = models.ArtistEvent -// TrackWithAds represents a track with ads +// TrackWithAds represents a track with ads. type TrackWithAds = models.TrackWithAds -// Ad represents an ad +// Ad represents an ad. type Ad = models.Ad -// AdParams represents ad parameters +// AdParams represents ad parameters. type AdParams = models.AdParams -// Landing represents a landing page +// Landing represents a landing page. type Landing = models.Landing -// LandingBlock represents a block in a landing +// LandingBlock represents a block in a landing. type LandingBlock = models.LandingBlock -// LandingBlockData represents data in a landing block +// LandingBlockData represents data in a landing block. type LandingBlockData = models.LandingBlockData -// LandingList represents a list of landings +// LandingList represents a list of landings. type LandingList = models.LandingList -// LyricsInfo represents lyrics information +// LyricsInfo represents lyrics information. type LyricsInfo = models.LyricsInfo -// VideoSupplement represents video supplement +// VideoSupplement represents video supplement. type VideoSupplement = models.VideoSupplement -// Supplement represents track supplement +// Supplement represents track supplement. type Supplement = models.Supplement -// LyricsMajor represents a lyrics provider (e.g., Genius, Musixmatch) +// LyricsMajor represents a lyrics provider (e.g., Genius, Musixmatch). type LyricsMajor = models.LyricsMajor -// TrackLyrics represents lyrics information from /tracks/{id}/lyrics endpoint +// TrackLyrics represents lyrics information from /tracks/{id}/lyrics endpoint. type TrackLyrics = models.TrackLyrics -// Credits represents track credits +// Credits represents track credits. type Credits = models.Credits -// Credit represents a credit item +// Credit represents a credit item. type Credit = models.Credit -// ArtistTracks represents a page of tracks by an artist +// ArtistTracks represents a page of tracks by an artist. type ArtistTracks = models.ArtistTracks -// ArtistAlbums represents a page of albums by an artist +// ArtistAlbums represents a page of albums by an artist. type ArtistAlbums = models.ArtistAlbums -// RadioStation represents a radio station +// RadioStation represents a radio station. type RadioStation = models.RadioStation -// StationTracksResult represents station tracks result +// StationTracksResult represents station tracks result. type StationTracksResult = models.StationTracksResult -// RotorStation represents a rotor (generative) station +// RotorStation represents a rotor (generative) station. type RotorStation = models.RotorStation -// RotorSettings represents rotor station settings +// RotorSettings represents rotor station settings. type RotorSettings = models.RotorSettings -// RotorStationTracksResult represents rotor station tracks result +// RotorStationTracksResult represents rotor station tracks result. type RotorStationTracksResult = models.RotorStationTracksResult -// RotorSession represents a rotor session +// RotorSession represents a rotor session. type RotorSession = models.RotorSession -// SessionFeedback represents session feedback +// SessionFeedback represents session feedback. type SessionFeedback = models.SessionFeedback -// SessionFeedbacks represents multiple session feedbacks +// SessionFeedbacks represents multiple session feedbacks. type SessionFeedbacks = models.SessionFeedbacks -// Experiments represents experiments +// Experiments represents experiments. type Experiments = models.Experiments -// ExperimentDetail represents experiment details +// ExperimentDetail represents experiment details. type ExperimentDetail = models.ExperimentDetail -// Permissions represents user permissions +// Permissions represents user permissions. type Permissions = models.Permissions -// PermissionAlerts represents permission alerts +// PermissionAlerts represents permission alerts. type PermissionAlerts = models.PermissionAlerts -// PermissionAlert represents a permission alert +// PermissionAlert represents a permission alert. type PermissionAlert = models.PermissionAlert -// ContentRestrictions represents content restrictions +// ContentRestrictions represents content restrictions. type ContentRestrictions = models.ContentRestrictions -// JSONBackend defines the interface for JSON encoding/decoding +// JSONBackend defines the interface for JSON encoding/decoding. type JSONBackend = utils.JSONBackend -// GetDefaultJSONBackend returns the default JSON backend +// GetDefaultJSONBackend returns the default JSON backend. func GetDefaultJSONBackend() JSONBackend { return utils.GetDefaultJSONBackend() } -// SchemaMismatchConfig holds configuration for schema mismatch handling +// SchemaMismatchConfig holds configuration for schema mismatch handling. type SchemaMismatchConfig = utils.SchemaMismatchConfig -// DefaultSchemaMismatchConfig returns the default configuration +// DefaultSchemaMismatchConfig returns the default configuration. func DefaultSchemaMismatchConfig() SchemaMismatchConfig { return utils.DefaultSchemaMismatchConfig() } -// SchemaMismatchHandler is a callback for handling schema mismatches +// SchemaMismatchHandler is a callback for handling schema mismatches. type SchemaMismatchHandler = utils.SchemaMismatchHandler -// SchemaMismatch represents a mismatch between expected and actual API response +// SchemaMismatch represents a mismatch between expected and actual API response. type SchemaMismatch = utils.SchemaMismatch -// YnisonClient represents a Ynison WebSocket client +// YnisonClient represents a Ynison WebSocket client. type YnisonClient = ynison.YnisonClient -// DeviceConfig holds device configuration for Ynison +// DeviceConfig holds device configuration for Ynison. type DeviceConfig = ynison.DeviceConfig // Example usage: