Skip to content

Series position from Audnexus is lost when it isn't a plain number (locale-dependent parse; non-numeric positions dropped into the track number) #764

Description

@m4bard

Summary

Audnexus reports a series position as a string, and it is not always a number. Squeezing it through a decimal loses it in two different ways, and the loss reaches the filename.

Evidence

Real positions from the Audible catalogue (all public domain, all verifiable against api.audnex.us):

Book ASIN position
The Father Brown Collection: Books 1-4 B0F84DFZ66 "1-4" — one ASIN, four books
The Thirty-Nine Steps B002V1PLZK "1-2" — the product also ships Greenmantle
She and Allan B00CQ5WAXW "0" — a prequel slot
a novella between two books "1.5"

1. The parse uses the server's culture

Audiobook.CreateBasicAudioMetadata calls decimal.TryParse(SeriesNumber, out var sp) with no CultureInfo, so it uses CurrentCulture — while FileNamingService formats the result back with InvariantCulture. The source value always uses . as the decimal separator, so where . is the group separator the number silently changes:

en-US      "1.5" -> 1.5     "0.5" -> 0.5
de-DE      "1.5" -> 15      "0.5" -> 5
fr-FR      "1.5" -> null    "0.5" -> null
invariant  "1.5" -> 1.5     "0.5" -> 0.5

On a German-locale server a novella at position 1.5 becomes book 15.

DownloadImportService is worse — it formats with a bare .ToString(), which writes 1,5 (with a comma) into a filename. The two naming sites don't agree with each other.

2. A position that doesn't parse is silently discarded

A position that fails the parse becomes null, which is indistinguishable from a book with no series position. Naming then falls through to the track number:

{ "SeriesNumber", FirstNonEmpty(metadata.SeriesPosition?.ToString(...),
                                metadata.TrackNumber?.ToString()) },

So a book at position "1-4" is renamed using an unrelated track number — no error, nothing in the log, wrong name on disk.

Expected

A real series position should survive to the filename, whatever the server's locale, and whether or not it happens to be a decimal. A book with genuinely no position should still fall back to the track number, as it does today.

Notes

PR #763 implements this: parses are pinned to InvariantCulture, and AudioMetadata carries the position as the source gave it so a non-numeric-but-real position is not lost. Opened after the fact — my apologies, I should have raised the issue first per CONTRIBUTING.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions