Fully automated media centre using Flexget, emby, Trakt and IMDb

Update Apr 24, 2019: Added latest config.
Update Jun 20, 2019: Current flexget config can be found on Github.

Further to my post back in 2014 about creating your own automated media centre, I’ve improved on a few aspects of this.

Improvements made:

  1. Replaced Serviio with Emby. Emby is better than Serviio by a long way, and continuously improved. I have a lifetime subscription.
  2. Enhanced my Flexget setup considerably with new private trackers, variables and IRC.
  3. Replaced e-mail notifications with Pushbullet push notifications to my iPhone.
  4. Added an NVIDIA Shield (not pro version, don’t need the HDD) with Emby Android App Kodi.
  5. Added Filebot to do automatic extraction and renaming of files into the relevant place for emby to consume. I used the Paid version of this software, well worth it.
  6. Added in 2019: Systemd unit replaces Upstart for auto start in current Ubuntu (18.04).

Let’s look at the changes one by one.

Emby

Not too much to say here, other than Emby is awesome. You can add multiple accounts for friends, and content and watch history is synced across devices. I have multiple devices accessing it including Android TV/Kodi, Roku, Samsung Smart TV, iPhone App, and Google Chrome. I’m not going to detail how to set it up as that is well documented, but suffice to say emby is a great product and I’m a lifetime premium subscriber.

In my setup, media is automatically extracted by Filebot (below) after being downloaded, indexed by emby using real-time file system monitoring, and relevant meta data is downloaded automatically.

Notable plugins that I have installed are:

  1. Emby.Kodi Sync Queue – very important, and provides instant updates to Kodi when new media is available and syncs library deltas to Kodi instead of the entire library. I now use the Emby Android App as it provides a better experience imho.
  2. CoverArt – make things look pretty.
  3. Rotten Tomatoes Reviews – self-explanatory.
  4. Trakt – syncs my libary and watch history with Trakt (cos I’m nerdy).

Flexget

Flexget is an amazingly powerful tool, and is the brains of the setup. Since my original post, I’ve cleaned up my config and updated it for more recent versions of Flexget, and refined my configuration to abstract some of the configuration using YAML alises. My current configuration is below:

variables: variables.yml

templates:
  anchors:
    _transmission: &transmission
      host: localhost
      port: 9091
      username: '{? transmission.username ?}'
      password: '{? transmission.password ?}'

    _iptorrents_credentials: &iptorrents_credentials
      rss_key: '{? ipt.passkey ?}'
      uid: '{? ipt.uid ?}'
      password: '{? ipt.password ?}'

    _torrentday_credentials: &torrentday_credentials
      uid: "'{? td.uid ?}'"
      cfduid: '{? td.cfduid ?}'
      passkey: '{? td.passkey ?}'
      rss_key: '{? td.rss_key ?}'

    _torrentleech_credentials: &torrentleech_credentials
      rss_key: '{? tl.rss_key ?}'
      username: '{? tl.username ?}'
      password: '{? tl.password ?}'

    _alpharatio_credentials: &alpharatio_credentials
      username: '{? ar.username ?}'
      password: '{? ar.password ?}'

    _alpharatio_irc: &alpharatio_irc
      nickname: '{? ar.nickname ?}'
      authkey: '{? ar.authkey ?}'
      torrent_pass: '{? ar.torrent_pass ?}'
      invite_message: '{? ar.invite_message ?}'

    _iptorrents_irc: &iptorrents_irc
      passkey: '{? ipt.passkey ?}'
      nickname: '{? ipt.nickname ?}'

    _tv_lookup: &tv_lookup
      thetvdb_lookup: yes
      trakt_lookup: yes

    _movie_lookup: &movie_lookup
      imdb_lookup: yes
      tmdb_lookup: yes

  trakt_tv_list: &trakt_tv_list
    trakt_list:
      username: '{? trakt.username ?}'
      account: '{? trakt.account ?}'
      list: Download List
      type: shows

  thetvdb_list: &thetvdb_list
    thetvdb_list:
      username: '{? thetvdb.username ?}'
      account_id: '{? thetvdb.account_id ?}'
      api_key: '{? thetvdb.api_key ?}'

  global:
    transmission:
      <<: *transmission
    free_space:
      path: /storage
      space: 20000
    pathscrub: windows
    include: reject.yml

  tv-settings:
    <<: *tv_lookup
    content_size:
      max: 10000
      min: 200
    configure_series:
      from:
        <<: *trakt_tv_list
        #<<: *thetvdb_list
      settings:
        exact: no
        target: 1080p hdtv+
        quality: 720p-1080p webrip+
        timeframe: 18 hours
        propers: 48 hours
        identified_by: ep

  movie-settings:
    <<: *movie_lookup
    proper_movies: no
    content_size:
      min: 1000
      max: 20000
      strict: no
    quality: 1080p webdl+ !truehd dts+
    list_match:
      from:
        - movie_list: Movies

tasks:

  monitor-rss:
    priority: 1
    inputs:
      - rss: '{? tl.rss ?}'
      - rss: '{? td.rss ?}'
    template:
      - global
      - tv-settings

  search-tv:
    priority: 2
    template:
      - global
      - tv-settings
    discover:
      what:
        - next_series_episodes: yes
      from:
        - alpharatio:
            <<: *alpharatio_credentials
            category: tvhd
        - torrentday:
            <<: *torrentday_credentials
            category: tvHDx264
        - iptorrents:
            <<: *iptorrents_credentials
            category: [22, 5, 99]
        - torrentleech:
            <<: *torrentleech_credentials
            category: [32]
      interval: 3 hours
    cfscraper: yes

  search-movies:
    priority: 3
    template:
      - global
      - movie-settings
    discover:
      release_estimations:
        optimistic: 30 days
      what:
        - movie_list: Movies
      from:
        - alpharatio:
            <<: *alpharatio_credentials
            category: moviehd
        - torrentday:
            <<: *torrentday_credentials
            category: movHD
        - torrentleech:
            <<: *torrentleech_credentials
            category: [14, 37]
        - iptorrents:
            <<: *iptorrents_credentials
            category: [48, 20, 100]
      interval: 3 hours
    cfscraper: yes

  update-movie-queue:
    priority: 30
    <<: *movie_lookup
    imdb_list:
      login: '{? imdb.login ?}'
      password: '{? imdb.password ?}'
      list: watchlist
    accept_all: yes
    list_add:
      - movie_list: Movies
    template: no_global
    no_entries_ok: yes

  cleanup-lists:
    priority: 100
    template: trakt_tv_list
    <<: *tv_lookup
    disable: seen
    if:
      - trakt_series_status in ['ended', 'cancelled']: accept
    list_remove:
      - <<: *trakt_tv_list

  cleanup-torrents:
    priority: 50
    from_transmission:
      <<: *transmission
    disable: [seen, seen_info_hash]
    if:
      - transmission_progress == 100: accept
      - "transmission_ratio < 1.0 and transmission_date_done > now - timedelta(days=15)": reject
    transmission:
      <<: *transmission
      action: purge

  irc-tv-dl:
    manual: yes
    template:
      - global
      - tv-settings

  irc-movie-dl:
    manual: yes
    template:
      - global
      - movie-settings

schedules:
  - tasks: 'monitor-rss'
    interval:
      minutes: 30
  - tasks: 'search-*'
    interval:
      hours: 6
  - tasks: ['update-movie-queue', 'cleanup-*']
    interval:
      hours: 12

web_server:
  run_v2: yes

irc:
  irc_ar:
    <<: *alpharatio_irc
    tracker_file: 'AlphaRatio.tracker'
    port: 7000
    use_ssl: yes
    invite_nickname: Voyager
    channels: ["#Announce"]
    task_re:
      - task: irc-tv-dl
        patterns:
          - regexp: TvHD
            field: irc_category
      - task: irc-movie-dl
        patterns:
          - regexp: MovieHD
            field: irc_category

  irc_ipt:
    <<: *iptorrents_irc
    tracker_file: 'IPTorrents.tracker'
    port: 6697
    use_ssl: yes
    channels: ["#ipt.announce2"]
    task_re:
      - task: irc-tv-dl
        patterns:
          - regexp: (TV\/x265|TV\/x264|TV\/Web-DL)
            field: irc_category
      - task: irc-movie-dl
        patterns:
          - regexp: (Movie\/HD\/Bluray|Movie\/Web-DL|Movie\/x265)
            field: irc_category

What this file is doing is:

  1. Setting up a bunch of templates to be used elsewhere in the config.
  2. Defining what TV series I am going to download based on a private Trakt list (Download list). This allows me to add a show to that list on Trakt and for Flexget to automatically start downloading it. You do not want to use the default Trakt watchlist, as it removes shows when watched for some stupid reason.
  3. Defining some settings for downloading movies (I want 1080p, better than Web-DL, no TrueHD and DTS audio or better) and TV (I want 1080p HDTV or better, but I’ll wait 18hr and then take the 720p version).
  4. Then I define my tasks. I’m monitoring the RSS feeds of 2 private trackers on a 30 minute interval (see schedules) for TV shows, and applying the global and tv-settings templates. I’m also using 4 Flexget search plugins to search those private trackers for missing TV episodes until they are found.
  5. For movies, I am using Flexget’s built-in movie queue to manage movies, and I am updating that movie queue from IMDb every 12 hours (I add a movie to watchlist on the mobile app, and it is added to movie queue and downloaded when available). I am then searching 4 private torrent trackers every 6hr for these movies using the Flexget Discover plugin.
  6. Finally, I’m seeding for 15 days (cos I’m nice) and then removing the torrent from Transmission completely to free up space (torrent has already been extracted to media library immediately upon download by Filebot).
  7. In this latest version of the config, I have replaced two private tracker RSS monitors with real-time IRC monitoring for new releases, meaning new releases that match my criteria are downloaded in real-time from the tracker.

My variables file looks like this (if you want a full setup).

transmission:
  username: xxx
  password: xxx

imdb:
  login: email
  password: password

trakt:
  account: xxx
  username: xxx

tl:
  rss: xxx
  rss_key: xxx
  username: xxx
  password: xxx

td: 
  rss: xxx
  uid: xxx
  cfduid: xxx
  passkey: xxx
  rss_key: xxx

ipt:
  rss: xxx
  rss_key: xxx
  uid: xxx
  password: xxx

ar:
  rss: xxx
  username: xxx
  password: xxx

Pushbullet & Filebot

You can just download the Pushbullet app from the App Store and set up Filebot to send push notifications (see below). I’ve chosen to send push notifications with Filebot (when extraction is complete), but you can also send push notifications of different types from Emby when new media is detected using plugins. I did this so I can see details about the actual torrent Fielbot processed, rather than the media indexed by Emby.

Once a torrent is complete, I have configured Transmission to call the following script by editing /etc/transmission-daemon/settings.json and adding the following line:

"script-torrent-done-filename": "/home/frank/torrent-postprocess.sh"

Next is the torrent-postprocess.sh script, where the magic happens. This calls Filebot to deal with the download (extract, copy, rename, create directories, etc).

#!/bin/bash

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export JAVA_OPTS="-DuseGVFS=false"
export FILEBOT_OPTS="-Dnet.filebot.Archive.extractor=SevenZipExecutable"

filebot -script fn:amc --log-file "/home/frank/.filebot/amc.log" --def clean=y --output "/tmp" --action copy --conflict override -non-strict --def artwork=n "ut_dir=$TR_TORRENT_DIR/$TR_TORRENT_NAME" "ut_kind=multi" "ut_title=$TR_TORRENT_NAME" --def "seriesFormat=/storage/TV/{n}/{'S'+s.pad(2)}/{n.replaceAll(/[!?.]+$/).space('.')}.{'s'+s.pad(2)}e{e.pad(2)}.{vf}.{source}.{vc}.{ac}" "movieFormat=/storage/Movies/{n.upperInitial().replaceAll(/[!?.]+$/).space('.')}.{y}.{vf}.{source}.{vc}.{ac}" --def pushbullet=mykey --def reportError=y > /home/frank/.filebot/output.txt 2>&1

After setting a bunch of environment variables, we call Filebot using the automated media centre (amc) script. This script places all downloaded media into the relevant location in my filesystem (either my Emby TV library or Movie library).

For details on these options, you can refer to the Filebot AMC reference guide, but the short version is that it creates a nice folder structure and renames all files in a consistent manner based on title, year, source, video quality, audio quality. After a few seconds, they appear in Emby ready for watching. Don’t forget to have the correct permissions set – Filebot runs as the debian-transmission user in this setup, so you’ll have to adjust accordingly.

Systemd Unit

Update Feb 24, 2019:This is used to auto start Flexget and replaces Upstart config on newer versions of Ubuntu.

/lib/systemd/system/flexget.service

[Unit]
Description=Flexget Daemon
After=network.target

[Service]
Type=simple
User=frank
Group=frank
UMask=000
WorkingDirectory=/home/frank/.flexget
RemainAfterExit=yes

ExecStart=/home/frank/flexget/bin/flexget --loglevel info daemon start
ExecStop=/home/frank/flexget/bin/flexget daemon stop
ExecReload=/home/frank/flexget/bin/flexget daemon reload

[Install]
WantedBy=multi-user.target

And there you have it, the lazy man’s approach to downloading media 🙂

Frank W

I'm a tech junkie and SaaS product manager living in Toronto, Canada. This is my personal website, and I occasionally write on this blog. Read more the about me.

3 thoughts to “Fully automated media centre using Flexget, emby, Trakt and IMDb”

  1. Great setup! I’ll try to install in my home PC, and test how it works. Too many variables and scripts, but I hope success!

    Thanks for the post!

  2. Hey Frank!

    Excellent work. I want to report that the URL that links your original guide/post from 2014 no longer works.
    Could you re-post that or point to somewhere that does?

    Also, with it being 2+ years later, do you expect any of your code to possibly be outdated? ie version history etc..

    Thanks again!
    Jay

    1. Hi Jay,

      Check the link now, think WordPress somehow messed it up.

      With respect to the config, I am still running pretty much the exact same setup. The only thing that has changed is the Flexget config, as Flexget gets updated and the syntax changes. I’ve updated this post with the latest config for you. Lmk if you have any questions.

      F

Leave a Reply

Your email address will not be published. Required fields are marked *