Deluge
This is a howto for setting up Deluge on a headless Ubuntu(natty) server with RSS automatic feeds for TV shows with multiple trackers and fallback video qualities. The RSS feeder also will pull out the actual TV show file, rename it, and put it in a named directory structure.
Deluge Install
- Version 1.3.3 is in the repo as of this writing(20111011)
sudo add-apt-repository ppa:deluge-team/ppa sudo apt-get update && sudo apt-get install deluged deluge-web
Startup Script
I run deluge as root to make it easier, I know it's insecure, I don't care.
Default file
- nano /etc/default/deluge-daemon
#Configuration for /etc/init.d/deluge-daemon # The init.d script will only run if this variable non-empty. DELUGED_USER="root" # Should we run at startup? RUN_AT_STARTUP="YES"
- Create log directories
mkdir -p /var/log/deluge/daemon mkdir -p /var/log/deluge/web chown -R user:user /var/log/deluge
SystemD deluged
[Unit] Description=Deluge Bittorrent Client Daemon After=network-online.target [Service] Type=simple User=root Group=root UMask=000 ExecStart=/bin/ip netns exec vpn /usr/bin/deluged -d -i 0.0.0.0 -u 10.1.1.2 -l /var/log/deluged.log -L info Restart=on-failure # Configures the time to wait before service is stopped forcefully. TimeoutStopSec=300 [Install] WantedBy=multi-user.target
SystemD deluge-web
[Unit] Description=Deluge Bittorrent Client Web Interface After=network-online.target [Service] Type=simple User=root Group=root UMask=027 ExecStart=/usr/bin/deluge-web -i 127.0.0.1 -l /var/log/deluge/deluge-web.log -L info -d Restart=on-failure [Install] WantedBy=multi-user.target
Init.d file
- nano /etc/init.d/deluge-daemon
#!/bin/sh
### BEGIN INIT INFO
# Provides: deluge-daemon
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Daemonized version of deluge and webui.
# Description: Starts the deluge daemon with the user specified in
# /etc/default/deluge-daemon.
### END INIT INFO
# Author: Adolfo R. Brandes
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Deluge Daemon"
NAME1="deluged"
NAME2="deluge"
DAEMON1=/usr/bin/deluged
DAEMON1_ARGS="-d -L warning -l /var/log/deluge/daemon/warning.log" # Consult `man deluged` for more options
DAEMON2=/usr/bin/deluge-web
DAEMON2_ARGS="-L warning -l /var/log/deluge/web/warning.log -b /deluge" # Consult `man deluge-web` for more options
PIDFILE1=/var/run/$NAME1.pid
PIDFILE2=/var/run/$NAME2.pid
UMASK=022 # Change this to 0 if running deluged as its own user
PKGNAME=deluge-daemon
SCRIPTNAME=/etc/init.d/$PKGNAME
# Exit if the package is not installed
[ -x "$DAEMON1" -a -x "$DAEMON2" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$PKGNAME ] && . /etc/default/$PKGNAME
# Load the VERBOSE setting and other rcS variables
[ -f /etc/default/rcS ] && . /etc/default/rcS
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
if [ -z "$RUN_AT_STARTUP" -o "$RUN_AT_STARTUP" != "YES" ]
then
log_warning_msg "Not starting $PKGNAME, edit /etc/default/$PKGNAME to start it."
exit 0
fi
if [ -z "$DELUGED_USER" ]
then
log_warning_msg "Not starting $PKGNAME, DELUGED_USER not set in /etc/default/$PKGNAME."
exit 0
fi
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --background --quiet --pidfile $PIDFILE1 --exec $DAEMON1 \
--chuid $DELUGED_USER --user $DELUGED_USER --umask $UMASK --test > /dev/null
RETVAL1="$?"
start-stop-daemon --start --background --quiet --pidfile $PIDFILE2 --exec $DAEMON2 \
--chuid $DELUGED_USER --user $DELUGED_USER --umask $UMASK --test > /dev/null
RETVAL2="$?"
[ "$RETVAL1" = "0" -a "$RETVAL2" = "0" ] || return 1
start-stop-daemon --start --background --quiet --pidfile $PIDFILE1 --make-pidfile --exec $DAEMON1 \
--chuid $DELUGED_USER --user $DELUGED_USER --umask $UMASK -- $DAEMON1_ARGS
RETVAL1="$?"
sleep 2
start-stop-daemon --start --background --quiet --pidfile $PIDFILE2 --make-pidfile --exec $DAEMON2 \
--chuid $DELUGED_USER --user $DELUGED_USER --umask $UMASK -- $DAEMON2_ARGS
RETVAL2="$?"
[ "$RETVAL1" = "0" -a "$RETVAL2" = "0" ] || return 2
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user $DELUGED_USER --pidfile $PIDFILE2
RETVAL2="$?"
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user $DELUGED_USER --pidfile $PIDFILE1
RETVAL1="$?"
[ "$RETVAL1" = "2" -o "$RETVAL2" = "2" ] && return 2
rm -f $PIDFILE1 $PIDFILE2
[ "$RETVAL1" = "0" -a "$RETVAL2" = "0" ] && return 0 || return 1
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME1"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME1"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME1"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:
- Make file executable
CHMOD 755 /etc/init.d/deluge-daemon
- Auto start after reboot
update-rc.d deluge-daemon defaults
- View Web Interface
- Default password is deluge
http://servername:8112/
Configuration
The configuration through the web interface doesn't always work. I found it easier and more reliable to manually edit the core.conf file.
This configuration file is also currently setup for Private Trackers, so DHT/PEX options are disabled.
- nano /root/.config/deluge/core.conf
{
"file": 1,
"format": 1
}{
"info_sent": 0.0,
"lsd": false,
"send_info": false,
"move_completed_path": "/root",
"enc_in_policy": 1,
"queue_new_to_top": false,
"ignore_limits_on_local_network": true,
"rate_limit_ip_overhead": true,
"daemon_port": 58846,
"natpmp": false,
"max_active_limit": 8,
"utpex": false,
"max_active_downloading": 3,
"max_active_seeding": 5,
"allow_remote": false,
"max_half_open_connections": 50,
"download_location": "/var/local/torrents",
"compact_allocation": false,
"max_upload_speed": 400.0,
"cache_expiry": 60,
"prioritize_first_last_pieces": false,
"auto_managed": true,
"enc_level": 2,
"max_connections_per_second": 20,
"dont_count_slow_torrents": false,
"random_outgoing_ports": true,
"max_upload_slots_per_torrent": -1,
"new_release_check": false,
"enc_out_policy": 1,
"outgoing_ports": [
12345,
12346
],
"seed_time_limit": 180,
"cache_size": 512,
"share_ratio_limit": 2.0,
"max_download_speed": 1200.0,
"geoip_db_location": "/usr/share/GeoIP/GeoIP.dat",
"torrentfiles_location": "/root",
"stop_seed_at_ratio": false,
"peer_tos": "0x00",
"listen_interface": "",
"upnp": false,
"max_download_speed_per_torrent": -1,
"max_upload_slots_global": 6,
"enabled_plugins": [
"AutoAdd",
"Blocklist"
],
"random_port": false,
"autoadd_enable": false,
"max_connections_global": 300,
"enc_prefer_rc4": true,
"listen_ports": [
12345,
12346
],
"dht": false,
"stop_seed_ratio": 2.0,
"seed_time_ratio_limit": 7.0,
"max_upload_speed_per_torrent": -1,
"copy_torrent_file": false,
"del_copy_torrent_file": false,
"move_completed": false,
"proxies": {
"peer": {
"username": "",
"password": "",
"type": 0,
"hostname": "",
"port": 8080
},
"web_seed": {
"username": "",
"password": "",
"type": 0,
"hostname": "",
"port": 8080
},
"tracker": {
"username": "",
"password": "",
"type": 0,
"hostname": "",
"port": 8080
},
"dht": {
"username": "",
"password": "",
"type": 0,
"hostname": "",
"port": 8080
}
},
"add_paused": false,
"max_connections_per_torrent": -1,
"remove_seed_at_ratio": false,
"autoadd_location": "/root",
"plugins_location": "/root/.config/deluge/plugins"
}
Apache Proxy Setup
This reverse proxy allows you to view the web interface without using the :8112/ definition. It makes it easier for the wife.
- Enable Modules
a2enmod proxy a2enmod proxy_http
- nano /etc/apache2/conf.d/deluge.conf
# Reverse-proxy deluge server into main server space ProxyRequests off ProxyPass /deluge/ http://127.0.0.1:8112/ <Location /deluge/> ProxyPassReverse http://127.0.0.1:8112/deluge/ ProxyPassReverseCookieDomain 127.0.0.1 localhost ProxyPassReverseCookiePath / /deluge/ Order allow,deny Allow from all </Location>
- View new deluge URL
http://servername/deluge/
FlexGet Install
TheTVDB PreConfig
This is the online website that will actually be telling your RSS feeder what shows to look for.
- Go signup for an account and then go back to your "Account" and get your "Account Identifier". Write it down, you will need it in a little bit.
http://thetvdb.com/
Installation
These instructions are based upon http://flexget.com/wiki/InstallWizard/Linux
- Verify python installed
sudo apt-get install python2.6
- Install setup tools
sudo apt-get install python-setuptools
- Install FlexGet
sudo easy_install flexget
- Verify Install
flexget -V
- Setup Cron
I run it every 15 minutes, trackers can tolerate that.
crontab -l
# FlexGet RSS torrent download 00,15,30,45 * * * * /usr/local/bin/flexget --cron
TVDB.com Configuration
This configuration style was based upon http://flexget.com/wiki/Cookbook/Series/DelugeThetvdbSeries
- spaces are extremely important
- nano /root/.flexget/config.yml
presets:
tv:
import_series:
from:
thetvdb_favorites:
account_id: C221005D4E1F6B79
settings:
min_quality: hdtv
max_quality: 720p
exists_series:
- /var/local/storage/TV_Shows
- /var/local/storage/torrents/.incomplete
thetvdb_lookup: yes
set:
path: /var/local/storage/torrents/.incomplete
movedone: "/var/local/storage/TV_Shows/{{ series_name }}/Season {{ series_season }}"
content_filename: |
{{ series_name }}.{{ series_id }}
{% if ep_name|default(False) %}.{{ ep_name }} {% endif %}.{{ quality|upper }}
{% if proper_count %} - proper{% if proper_count > 1 %}{{ proper_count }}{% endif %}{% endif %}
deluge:
main_file_only: yes
feeds:
feed1:
rss: https://rssfeed1.com
priority: 1
preset: tv
feed2:
rss: http://rss.site2.com
priority: 2
preset: tv
feed3:
headers:
cookie: uid=123456; pass=sdf651a651df84a98dg8r4g
rss: http://www.feed3.org/rss.php
priority: 3
preset: tv
TRAKT.TV/IMDB Configuration
This configuration is for monitoring your favorites on http://trakt.tv/ and/or http://imdb.com/
feeds:
seed_watchlist:
# priority plugin is used so that this feed runs before the actual download feed
priority: 1
interval: 2 hours
trakt_list:
api_key: myapikey
username: myusername
movies: watchlist
imdb_list:
list: watchlist
username: me@somewhere.com
password: mypassword
accept_all: yes
queue_movies:
quality: 720p bluray
force: no
Full Configuration
presets:
global:
deluge:
main_file_only: yes
path: /var/local/storage/torrents/.incomplete
email:
active: True
from: mailer@nowhere.com
to: toemail@mail.com
smtp_host: smtp.gmail.com
smtp_port: 587
smtp_login: true
smtp_username: user@gmail.com
smtp_password: password
smtp_tls: true
tv:
#series_premiere: yes
import_series:
from:
thetvdb_favorites:
account_id: Csdfh516fghB79
settings:
quality: hdtv
#min_quality: hdtv
#max_quality: 720p
propers: no
exists_series:
- /var/local/storage/TV_Shows
- /var/local/storage/torrents/.incomplete
thetvdb_lookup: yes
set:
#path: /var/local/storage/torrents/.incomplete
movedone: "/var/local/storage/TV_Shows/{{ series_name }}/Season {{ series_season }}"
content_filename: |
{{ series_name }}.{{ series_id }}
{% if ep_name|default(False) %}.{{ ep_name }} {% endif %}.{{ quality|upper }}
{% if proper_count %} - proper{% if proper_count > 1 %}{{ proper_count }}{% endif %}{% endif %}
label: tv
movies:
imdb:
min_score: 7.5
min_votes: 10000
min_year: 2009
reject_genres:
- News
- Documentary
- Horror
- Biography
- Reality-Tv
accept_languages:
- english
- swedish
reject_mpaa_ratings:
- X
content_filter:
reject:
- '*.rar'
- '*.wmv'
quality:
max: 1080p
min: 720p bluray
content_size:
max: 8000
min: 1200
regexp:
from: title
reject:
- ts
- hindi
- german
imdb_required: yes
seen_movies: strict
limit_new: 1
exists_movie:
- /var/local/storage/torrents/.incomplete
- /var/local/storage/Movies/Feature_Films
- "/var/local/storage/Movies/Disney Movies"
set:
movedone: /var/local/storage/torrents
label: movie
addpaused: yes
ratio: 1
feeds:
feed1:
rss: https://rssfeed1.com
priority: 1
preset: tv
feed2:
rss: http://rss.site2.com
priority: 2
preset: tv
feed3:
headers:
cookie: uid=123456; pass=sdf651a651df84a98dg8r4g
rss: http://www.feed3.org/rss.php
priority: 3
preset: tv
feed3:
rss: http://rss.feed4.org/207
priority: 4
preset: movies
Troubleshooting
- Check config
#flexget -v --check
- Test config
#flexget -v --test
- Manual run
#flexget
- Flexget Options
Usage: flexget [options]
Options:
-h, --help show this help message and exit
-V, --version Print FlexGet version and exit.
--bugreport Use this option to create a detailed bug report, note
that the output might contain PRIVATE data, so edit
that out
-c CONFIG Specify configuration file. Default is config.yml
--test Verbose what would happen on normal execution.
--check Validate configuration file and print errors.
--learn Matches are not downloaded but will be skipped in the
future.
--no-cache Disable caches. Works only in plugins that have
explicit support.
--reset DANGEROUS. Obliterates the database and runs with
learn in order to to regain useful state.
--cron Disables stdout and stderr output, log file used.
Reduces logging level slightly.
--db-cleanup Forces the database cleanup event to run right now.
--archive-search=TXT Search from the archive.
--archive-inject Inject entries from the archive into a feed where it
was archived from. Usage: ID[,ID] [FORCE]
--search-plugins List supported search plugins.
--preset=NAME Execute feeds with given preset.
-v, --verbose Verbose undecided entries.
--try-regexp Try regular expressions interactively.
--stop-waiting=NAME Stop timeframe for a given series.
--disable-advancement
Disable episode advancement for this run.
--history List 50 latest accepted entries.
--dl-path=PATH Override path for download plugin. Applies to all
executed feeds.
--dump Display all feed entries
--inject Injects entry to all executed feeds: <TITLE> [URL]
[ACCEPT] [FORCE]
--tail-reset=FILE Reset tail position for a file.
--cli-config=PARAMS Configuration parameters trough commandline. See --doc
cli_config.
--series Display series summary.
--series-forget Remove complete series or single episode from
database: <NAME> [EPISODE]
--plugins Print registered plugins summary
--doc=PLUGIN Display plugin documentation. See also --plugins.
--movie-queue (add|del|list|downloaded)
[NAME|IMDB_ID|tmdb_id=TMDB_ID] [QUALITY] [FORCE]
--now Ignore interval(s)
--feed=FEED Run only specified feed.
--forget=FEED|VALUE Forget feed (completely) or given title or url.
--seen=VALUE Add title or url to what has been seen in feeds.
--seen-search=VALUE Search given text from seen database.
--repair-seen-movies Repair seen movies database (required only when
upgrading from old problematic version)
--failed List recently failed entries.
--clear Clear recently failed list.
--forget-rejected Forget all previous rejections so entries can be
processed again.
XBMC Notifications
- Goal is to send notifications to XBMC interface when a torrent is finished and ready to watch.
- must use URL syntax, white space=%20
exec: curl -G "'http://localhost:8080/xbmcCmds/xbmcHttp?command=ExecBuiltIn(Notification(FLEXGET,New%20Torrent%20Downloaded!,20000))'"