impex

package
v3.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package impex imports and exports playlists as local files (CSV in the common Exportify style, extended M3U, JSON) and resolves imported rows back to Deezer tracks (ISRC-first, then a fuzzy artist+title search). All file handling is local; only resolution/creation touches the Deezer API, through narrow interfaces so it stays fully testable offline.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExportCSV

func ExportCSV(w io.Writer, name string, tracks []deezer.Track) error

ExportCSV writes tracks as an Exportify-style CSV. The playlist name is not part of the CSV format (Exportify carries it in the filename), so name is unused here; it is kept for signature symmetry with the other exporters.

func ExportJSON

func ExportJSON(w io.Writer, name string, tracks []deezer.Track) error

ExportJSON writes tracks as a self-describing JSON document.

func ExportM3U

func ExportM3U(w io.Writer, name string, tracks []deezer.Track) error

ExportM3U writes an extended M3U playlist. Each entry's location is the track's public Deezer URL so the id survives a round-trip; #EXTINF carries duration and "Artist - Title" as usual.

Types

type ImportResult

type ImportResult struct {
	PlaylistID string
	Matched    []deezer.Track // resolved tracks, input order
	Unmatched  []Row          // rows that resolved to nothing
}

ImportResult is what ImportPlaylist produced.

func ImportPlaylist

func ImportPlaylist(ctx context.Context, r Resolver, pc PlaylistCreator, title string,
	rows []Row, progress func(i, total int, matched bool)) (*ImportResult, error)

ImportPlaylist resolves rows against Deezer (ISRC first, then a fuzzy artist+title search) and creates a playlist with everything that matched. progress, when non-nil, is called after each row with i = rows processed so far (1..total). Unmatched rows are collected, not fatal; only zero matches (or a creation failure) is an error — the partial result is still returned so the caller can show what went wrong.

type PlaylistCreator

type PlaylistCreator interface {
	CreatePlaylist(title string, trackIDs []string) (string, error)
}

PlaylistCreator creates the destination playlist. *deezer.Client satisfies it directly (CreatePlaylist in library.go).

type Resolver

type Resolver interface {
	ByISRC(isrc string) (deezer.Track, error)
	Search(artist, title string) ([]deezer.Track, error)
}

Resolver looks imported rows up on Deezer. Narrow so tests use a fake.

func NewClientResolver

func NewClientResolver(c *deezer.Client) Resolver

NewClientResolver adapts a *deezer.Client into a Resolver.

type Row

type Row struct {
	Title  string
	Artist string
	Album  string
	ISRC   string
}

Row is one imported playlist line, before resolution against Deezer.

func ParseCSV

func ParseCSV(r io.Reader) ([]Row, error)

ParseCSV reads a playlist from r. Two formats are accepted:

  • CSV with an Exportify-style header (Track Name / Artist Name(s) / Album Name / ISRC, with common aliases like Title/Artist/Album), in any column order, extra columns ignored;
  • a plain text fallback: one "Artist - Title" per line (comment lines starting with '#' — e.g. an M3U's directives — and blank lines are skipped; a line without " - " becomes a title-only row).

Rows without a title are dropped. An input yielding no rows is an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL