Automated media pipeline that monitors a Telegram group for torrent tracker posts, parses release metadata, and presents everything in a review-ready web dashboard.
Most posts are fine, and stopping to approve each one is the slow part. Set
AUTO_APPROVE_ENABLED=true and the service decides for itself, keeping only
the items worth thinking about.
First the service has to be sure it is looking at the right title. TMDB is searched with the parsed title and year, and the record that comes back is only accepted when the parsed title is at least 85% alike the record's title or its original title, accents and punctuation ignored, and the years agree within one. A record found only by dropping the year is never accepted: it names a title, not necessarily this one. Everything below reads that record's data, including the IMDb id the parental guide is fetched with, so a wrong match would judge one film on another film's content.
With the match confirmed, a film or series downloads by itself when all of this holds:
MIN_GUIDE_VOTES votes;MIN_GUIDE_VOTES votes;MIN_GUIDE_VOTES votes;The 40% rule exists because the winning label hides a split vote. A category labelled Mild can have nearly half its voters calling it Moderate or worse, and IMDb publishes the breakdown.
Trip one of those rules and the item goes to the review queue with the reason
written out. Miss the data instead, and the item waits. It is re-checked once
an hour and handed back to you after AUTO_APPROVE_MAX_WAIT_HOURS with the
reason "no parental guide data after N hours". Missing data never counts as
clean: an unrated category cannot pass a threshold, and an empty keyword list
is silence, not a clean bill of health.
A match that cannot be confirmed goes straight to the review queue saying "could not confirm this is the same title". It never waits, because waiting would not make a wrong match right.
Always approved, and a post is only a magazine when it carries the written header the group puts on one. An emoji never decides a type on its own, and a post naming a video quality and a source is a film or a series whatever else it mentions.
Off by default. The catalogues have almost nothing for the Spanish titles this group posts, which leaves the decision resting on one coarse Google Books category, and "Fiction" rules nothing out.
Add them to AUTO_APPROVE_TYPES and the title is looked up on
Open Library, with
Google Books as a second
opinion, and classified by the subjects those catalogues carry. One downloads
by itself only when the title and the author both match a record, the record
carries at least three subjects, and none of them mention politics, sex or
magic. Anything less is "could not classify", which is a review, not an
approval.
Always reviewed by hand. The duplicate check runs again at re-check time, so a title approved by hand in the meantime is not downloaded twice.
Every automatic decision is written onto the item, with the reasons and the time. The web UI and the Telegram bot both show it.
An item can be rejected right up to the moment the download finishes, and while it is being content-checked. Rejecting it drops the torrent only when this item is what added it: qBittorrent answers an add with the hash of a torrent it was already holding, and deleting that would take a library copy that was there beforehand. The download row is marked cancelled either way, so nothing brings the item back as completed later.
Notes and links to Instagram, TikTok, YouTube, X or Facebook land in the same
group. They are marked ignored and then left alone for good: never reviewed,
never re-parsed, never deleted from the group.
That status is deliberately hard to earn. A request typed in plain words is not a release post either, and it stays in the review queue where you can act on it. A bare title in capitals and a sentence saying which book you want are both in this group's history. A message is only finished with when every link in it points somewhere nothing is downloaded from, or when there is nothing in it that could be the name of anything: no capital where grammar does not need one, no year, no shouted word, no quoted phrase, no word like "peli" or "libro", and no line short enough to be a title.
Defaults live in .env.example.
| Variable | Default | What it does |
|---|---|---|
AUTO_APPROVE_ENABLED | false | The master switch. Off means nothing is ever approved automatically. |
AUTO_APPROVE_TYPES | movie,series,magazine | Which types may be approved automatically. Add ebook,audiobook,comic to include books. |
MIN_GUIDE_VOTES | 5 | Parental-guide votes a severity needs before it is trusted. |
AUTO_APPROVE_MAX_WAIT_HOURS | 24 | How long an item waits for that data before you are asked. |
The schema is managed with Alembic. The service runs alembic upgrade head on
start-up, so a new image brings its own columns with it. The migrations in
alembic/versions/ only ever add things and are safe to
re-run.
The migration adds enum labels, and an older image cannot load a label it has never heard of. Move the rows off the new labels before starting the old image:
UPDATE media_items SET status = 'PENDING_REVIEW'
WHERE status IN ('AWAITING_DATA', 'IGNORED');
UPDATE downloads SET status = 'ERROR' WHERE status = 'CANCELLED';
The columns themselves can stay: the old code simply does not read them.
Content type
Image
Digest
sha256:dba79195e…
Size
81.9 MB
Last updated
5 months ago
docker pull drumsergio/media-triage