NAME

App::DrivePlayer::Scanner - Recursively scan a Google Drive folder and store tracks

SYNOPSIS

use App::DrivePlayer::Scanner;

my $scanner = App::DrivePlayer::Scanner->new(
    drive          => $drive_api,       # Google::RestApi::DriveApi3
    db             => $db,              # App::DrivePlayer::DB
    on_progress    => sub { say $_[0] },
    on_track_found => sub { my $track = shift; ... },
);

$scanner->scan_folder($root_folder_id, 'My Music');

# From within an on_progress callback:
$scanner->stop;

DESCRIPTION

Walks a Google Drive folder hierarchy depth-first, recording every audio file it finds into the DrivePlayer database. Non-audio files and Google Docs are silently ignored.

Metadata (title, artist, album, track number, year) is extracted from the filename using common naming conventions, and supplemented by inferring artist and album from the folder path when the filename alone is ambiguous.

Supported filename patterns:

NN - Artist - Title.ext
Artist - Title.ext          (en-dash also accepted)
NN - Title.ext
Title.ext

Year is extracted from a trailing (YYYY) or [YYYY] suffix.

A rescan of an existing folder replaces all previous data for that folder.

ATTRIBUTES

drive

is: ro, required: 1

A Google::RestApi::DriveApi3 instance (or any object with a list method matching that interface).

db

is: ro, required: 1

A App::DrivePlayer::DB instance used to persist scan results.

on_progress

is: ro, isa: CodeRef, optional

Called with a single string message as each folder is entered or when a Drive API error occurs. Calling "stop" from within this callback will prevent the current folder's Drive listing from being fetched.

on_track_found

is: ro, isa: CodeRef, optional

Called with a track hashref each time an audio file is successfully stored.

METHODS

new

my $scanner = App::DrivePlayer::Scanner->new(%args);

Constructor. drive and db are required.

scan_folder

$scanner->scan_folder($drive_folder_id, $folder_name);

Starts a recursive scan of the given Drive folder. Clears any previously stored data for that folder before scanning. Blocks until the scan completes or "stop" is called.

stop

$scanner->stop;

Signals the running scan to halt. Safe to call from within an on_progress callback; the current folder's Drive listing will not be fetched if stop is set before it is requested.