Skip to content

[BUG] {Book SeriesPosition} ignores :customFormat, can't zero-pad #72

Description

@davidgibbons

Describe the bug

{Book SeriesPosition} in ebook naming patterns (ebookStandardBookFormat) ignores any :customFormat suffix, so zero-padding like {Book SeriesPosition:00} silently has no effect. This makes it impossible to match the padded series-index convention several other library tools use (e.g. Kavita/Calibre-style 01 - Title), so multi-book series import with inconsistent, non-zero-padded folder names (1 - Title, 2 - Title, ... 10 - Title), which sorts wrong lexicographically.

The generic :customFormat capture already exists in FileNameBuilder.TitleRegex and is honored by {PartNumber}/{PartCount} via FormatPartToken() (value.ToString(customFormat), with a smart mode that pads to the width of the sibling PartCount). But the {Book SeriesPosition} handler in AddBookTokens never reads TokenMatch.CustomFormat at all:

// src/NzbDrone.Core/Organizer/FileNameBuilder.cs, AddBookTokens
tokenHandlers["{Book SeriesPosition}"] = m =>
    seriesPosition ?? m.DefaultValue("");

I'd guess this is because Book.SeriesPosition is a string (to allow values like "2.5" for novellas), so it can't just reuse int.ToString(customFormat) the way PartNumber does — it needs to parse the numeric part first and pad only that, while still passing non-numeric/fractional values through unpadded (or pad only the integer part, e.g. 02.5).

To Reproduce

  1. Settings → Metadata Profiles/Naming (or the naming/examples API) → set ebookStandardBookFormat to include {Book SeriesPosition:00 - }{Book Title}.
  2. Import or preview a book at series position 1.
  3. Rendered folder/file name is 1 - Title, not 01 - Title.

Verified via the naming preview API directly:

GET /api/v1/config/naming/examples?...&standardBookFormat={Book%20Series}/{Book%20SeriesPosition:00%20-%20}{Book%20Title}
→ "singleBookExample": "Series Title/1 - The Edition Title"

(:0, :00, and made-up suffixes all render identically to no suffix — confirms the token handler discards CustomFormat entirely rather than rejecting an invalid format.)

Expected behavior

{Book SeriesPosition:00} should zero-pad the integer part of the series position to at least 2 digits (101, 1010, 2.502.5), mirroring how {PartNumber:00} / {PartNumber:smart} behave.

System Information

  • Chaptarr Version: 0.9.929 (also reproduced by reading FileNameBuilder.cs at current develop HEAD)
  • Installation Method: Docker

Additional context

Happy to send a PR — the fix looks like a small, self-contained addition to AddBookTokens that parses the leading integer from seriesPosition, applies int.ToString(customFormat) (or a smart mode) to it, and reattaches any fractional/non-numeric remainder, falling back to the raw string when it isn't a recognizable number. Let me know if that approach sounds right before I put up a PR.

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