ArrTop::ImportWatch
Reads live import (copy) progress off disk. The *arr API reports an import as
importing with sizeleft: 0 and no copy progress, so the only way to show
how far the copy has gotten is to watch the destination file grow on disk.
This works only when arrtop runs *on the arr host (or on a mount of its
library). Off-host — the folder does not exist or cannot be read — it
degrades to "unknown" (nil) and never raises.
Constants
Video-file extensions (lower-case, with dot) that count as an import's
destination file. Anything else in the folder (.nfo, .srt, artwork,
...) is ignored.
Class methods
A case-insensitive regex matching a filename's SxxEyy token for the given
season/episode, tolerant of zero-padding (S2E3 == S02E03). The
leading \b anchors the season, the optional (E\d+)*? run lets an earlier
episode in a multi-episode file (S02E03E04) be skipped so BOTH episode 3
and episode 4 match their own token, and the trailing (\b|E) accepts a
boundary or the next E in that run.
Public so TorrentSizes matches a torrent's cached file names to an episode
with the exact same rule the disk-watch uses on on-disk file names.
Episode-aware watch for a Sonarr season pack. Finds this episode's file
(by its SxxEyy token) under dest_folder and reports both its live copy
progress and whether that file is the folder's newest-mtime video — the
one Sonarr is actively copying right now.
Returns nil (nothing to show) under the same conditions as .progress
(off-host / blank folder / non-positive target / no matching file yet).
Otherwise returns {ImportProgress, active} where active == true means
this episode's file is the folder-wide newest video: a season pack is copied
one file at a time, so already-copied episodes have older mtimes (active == false, i.e. done) and only the file being written is newest.
Two walks: one filtered to this episode's token (its bytes/path), one
folder-wide (the newest video's path). All the walk's off-host / vanished-
file / unreadable guarantees are inherited from newest_video_file/walk.
Live copy progress for an Importing row, or nil when there is nothing
to show.
Returns nil (unwatchable / nothing yet) when: dest_folder is nil or
blank; target is <= 0; the folder does not exist or cannot be read; or
no candidate video file exists yet (the import may not have created it).
Otherwise it walks dest_folder recursively, picks the most recently
modified video file (the one actively being written — see below), reads its
size, and returns an ImportProgress.
The destination is a folder: Radarr's movie folder, or Sonarr's series
folder (where the file lands in a Season NN/ subfolder), so the walk is
recursive. Selection is by most-recent mtime, not largest size: during
an upgrade a full old file sits beside the new partial one, and the
largest-size heuristic would wrongly pick the old file — the freshly
written file is the one with the newest mtime.
When season and episode are both given (Sonarr episode rows), only the
video file whose name carries that episode's SxxEyy token is considered —
a season pack drops N episodes into ONE series folder, so without this
filter every episode row would watch the same single newest file. Movies
(nil season/episode) keep the folder-wide "newest video file" behaviour.