• v1.2.0 b7ea4ae030

    v1.2.0
    All checks were successful
    CI / gate (push) Successful in 59s
    CI / lint (push) Successful in 55s
    CI / image (push) Successful in 53s
    Stable

    joeyr released this 2026-10-05 20:29:07 -05:00 | 20 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Added

    • A plain-text version of the email, sent alongside the HTML as
      multipart/alternative. It is rendered from the same data as the HTML
      theme: the titles, links to Jellyfin, the "and N more" lines, the
      library totals and the footer. Mail filters score HTML-only messages as
      more likely spam, and some readers show only text.
    • Date, Message-ID and List-Unsubscribe headers. The unsubscribe
      header is a mailto: to unsubscribe_email and is left out when that is
      empty. Missing Date and Message-ID headers also count against a
      message in spam filters (upstream issues #168 and #169).

    Fixed

    • Long lines in the HTML could break the email. SMTP allows at most 998
      characters per line, and the HTML was sent unencoded, so a long inline
      style or URL could get the message rejected or mangled. Both parts are
      now quoted-printable.
    • A subject or name with accents was sent as raw bytes in the headers,
      which only plain ASCII may contain. They are now encoded properly.
    Downloads
  • v1.1.0 5f7baae35a

    v1.1.0
    All checks were successful
    CI / gate (push) Successful in 58s
    CI / lint (push) Successful in 55s
    CI / image (push) Successful in 52s
    Stable

    joeyr released this 2026-10-05 20:20:10 -05:00 | 22 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Added

    • Secrets can live outside config.yml. The Jellyfin API token, the
      TMDB API key and the SMTP password are each read from the first of: a
      file named by <NAME>_FILE, a Docker secret at /run/secrets/<name>,
      the <NAME> env var, and finally config.yml as before. The names are
      jellyfin_api_token, tmdb_api_key and smtp_password (upper-case for
      the env vars). The startup log says where each one came from, never its
      value. Existing configs work unchanged.

    Changed

    • A missing secret is now reported after all those sources are checked,
      with a message naming each place it can go, instead of as a YAML
      validation error. A TMDB key that isn't a JWT now says to use TMDB's API
      Read Access Token.
    Downloads
  • v1.0.4 9474595f5b

    v1.0.4
    All checks were successful
    CI / gate (push) Successful in 57s
    CI / lint (push) Successful in 55s
    CI / image (push) Successful in 51s
    Stable

    joeyr released this 2026-10-05 20:12:04 -05:00 | 24 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Fixed

    • A rejected email was logged as sent. A mail server judges a message
      only after receiving all of it, and that verdict (a spam filter, a size
      limit, a policy) is the reply to the end of the message. It was never
      read, so a refused newsletter still logged "Successfully sent". It is now
      checked, and a rejection logs "Failed to send email to …" with the
      server's reply.
    Downloads
  • v1.0.3 8d61139228

    v1.0.3
    All checks were successful
    CI / gate (push) Successful in 1m1s
    CI / lint (push) Successful in 1m8s
    CI / image (push) Successful in 56s
    Stable

    joeyr released this 2026-10-05 19:37:33 -05:00 | 26 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Fixed

    • Empty movie folders were announced as new movies. Radarr keeps a folder
      for every film it is still waiting to download, and Jellyfin lists a folder
      with no video in it as a plain Folder item. The movie query asked for
      IsMovie items, but that filter lets through items that have no IsMovie
      flag at all, folders included. So each empty folder appeared in the email
      under its raw folder name, e.g. "Some Movie (2025) [tmdbid-12345]", usually
      with no poster. The query now asks Jellyfin for items of type Movie only.
      This is the real cause of what 1.0.2 tried to fix.

    Removed

    • The 1.0.2 title cleanup. It assumed those entries were movies Jellyfin
      hadn't identified yet. A real movie never carries the raw folder name, since
      Jellyfin strips the bracketed tags from it and reads the TMDB ID from the
      folder, so the cleanup had nothing left to do. The jellyfin package is
      back to upstream's code apart from the query fix.
    Downloads
  • v1.0.2 d54c084c38

    v1.0.2
    All checks were successful
    CI / gate (push) Successful in 59s
    CI / lint (push) Successful in 55s
    CI / image (push) Successful in 50s
    Stable

    joeyr released this 2026-10-05 19:17:53 -05:00 | 28 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Fixed

    • Movies and shows Jellyfin hasn't identified yet showed their raw folder
      name, and usually no poster.
      Right after Radarr or Sonarr renames a
      folder, Jellyfin re-creates the item with the folder name as its title,
      e.g. "Dune (2021) [tmdbid-438631]", and with no TMDB ID or year. The TMDB
      search for that literal text mostly finds nothing. The email now shows
      "Dune", and takes the year and the TMDB ID from the folder name wherever
      Jellyfin has none, so the right poster and description are found. In the
      2026-10-05 preview, 20 of 735 movies were affected and 14 of those had a
      placeholder poster.
    Downloads
  • v1.0.1 f7ac12751b

    v1.0.1
    All checks were successful
    CI / gate (push) Successful in 56s
    CI / lint (push) Successful in 55s
    CI / image (push) Successful in 50s
    Stable

    joeyr released this 2026-10-05 18:46:37 -05:00 | 30 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Changed

    • Every dependency is on its newest release. The ones the app itself runs
      on: gocron 2.19.1 → 2.22.0, validator 10.29.0 → 10.30.5, go-yaml
      1.19.0 → 1.19.2, zap 1.27.1 → 1.28.0, golang.org/x/text 0.37.0 → 0.42.0.
      Test-only: testify 1.11.1 → 1.12.1, testcontainers-go 0.41.0 → 0.44.0,
      go-vcr 4.0.6 → 4.0.7. All indirect modules were updated as well. Seven
      still show newer versions in go list -m -u all, but none is compiled into
      the app or any test, so there is nothing in them to patch.
    • CI lints with golangci-lint v2.14, the newest release, instead of
      upstream's v2.11. No new findings.
    Downloads
  • v1.0.0 a756b01f13

    v1.0.0
    All checks were successful
    CI / lint (push) Successful in 58s
    CI / gate (push) Successful in 56s
    CI / image (push) Successful in 1m6s
    Stable

    joeyr released this 2026-10-05 18:37:18 -05:00 | 32 commits to main since this release

    Based on upstream v2.0.0 (900faea).

    Added

    • CI on Forgejo Actions. Every push and pull request runs go vet, the
      unit tests and golangci-lint (the version and config upstream's CI uses).
      Every push to main also publishes the image to
      forgejo.jrendar.org/joeyr/jellyfin-newsletter as :latest, :1.0.0 and
      :<commit>. It is built on the Swarm's own Pis, so it is linux/arm64 only.
    • VERSION holds the release version. It is baked into the binary, so the
      startup log line reports it.

    Fixed

    • A movie or show found by name search could get another title's
      description.
      When the most popular TMDB result lacked a description (or a
      poster), the field was taken from a less popular result. Both now come from
      the same result, with the usual defaults for whatever it lacks.
    • max_displayed_items saved no work. Every new item was looked up on
      TMDB before the list was cut down, so a cap of 10 in a 500-item week still
      cost 500 lookups. Only the items the email shows are looked up now.
    • Dry-run could not save its preview with the default settings. The
      default output folder, /app/config/previews/, was never created. It is now
      created when missing.
    • A recipient address that couldn't be parsed was logged without the
      reason.
      The log line now carries the parse error.
    • The connection to the mail server was never closed after sending. The
      session now ends with QUIT, and the connection is dropped if the server
      doesn't answer it.
    Downloads