|
#!/bin/bash
|
|
|
|
# Transmission BitTorrent blocklist downloader
|
|
# Copyright (C) 2018 Pekka Helenius
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
###########################################################################
|
|
|
|
# TODO Remove duplicate IP's from list files (does Transmission do this automatically?)
|
|
|
|
# TODO Support more archive/text formats
|
|
# Only zip & gz archives are currently supported
|
|
|
|
# TODO "Older than XX days" check not always working?
|
|
|
|
###########################################################################
|
|
|
|
# Usage:
|
|
|
|
# bash transmission_blocklists.sh
|
|
# bash transmission_blocklists.sh -y
|
|
|
|
# where -y parameter passes all Yes/No questions with auto-yes answer
|
|
# Exception: internet connection test
|
|
|
|
# Requirements:
|
|
|
|
# Unix-based OS
|
|
# Bash shell 4.0 or above
|
|
# Internet connection
|
|
# Transmission client installed
|
|
# gzip
|
|
|
|
###########################################################################
|
|
|
|
# BLOCKLISTS
|
|
typeset -A BLOCKLISTS
|
|
|
|
#####################################
|
|
# Blocklist syntax:
|
|
|
|
# [list_1-friendly-name]="list_1_URL"
|
|
# [list_2-friendly-name]="list_2_URL"
|
|
# ...
|
|
|
|
# where list_URL must point to some of the following archive types: zip, gz
|
|
|
|
# For example:
|
|
|
|
# [Yoyo-adservers]="http://list.iblocklist.com/?list=zhogegszwduurnvsyhdf&fileformat=p2p&archiveformat=gz"
|
|
|
|
#####################################
|
|
|
|
BLOCKLISTS=(
|
|
[Yoyo-adservers]="http://list.iblocklist.com/?list=zhogegszwduurnvsyhdf&fileformat=p2p&archiveformat=gz"
|
|
)
|
|
|
|
###########################################################################
|
|
|
|
# Basic configuration
|
|
|
|
# Older blocklist files than this should be updated. Value in days.
|
|
UPDATELIMIT_DAYS=15
|
|
|
|
# Timeout for wget in getfile function, seconds
|
|
WGET_TIMEOUT=30
|
|
|
|
# Transmission client blocklist directory for the current user
|
|
TRANSMISSION_BLOCKLISTDIR=$HOME/.config/transmission/blocklists/
|
|
|
|
# We need to make internet connection test. The following URL is used for
|
|
# testing.
|
|
TEST_PROVIDER="www.github.com"
|
|
|
|
###########################################################################
|
|
|
|
if [[ $1 == "-y" ]]; then
|
|
autoyes=''
|
|
fi
|
|
|
|
###########################################################################
|
|
|
|
# Commands required by this script
|
|
|
|
COMMANDS=(bash transmission-cli wget gzip date find kill awk sed grep ping unzip mv wc)
|
|
|
|
for command in "${COMMANDS[@]}"; do
|
|
|
|
if [[ $(echo $(which "${command}" &>/dev/null)$?) -ne 0 ]]; then
|
|
echo "Command ${command} not found. Can't run the script."
|
|
exit 1
|
|
fi
|
|
|
|
done
|
|
|
|
###########################################################################
|
|
|
|
for transmission_bin in transmission-qt transmission-gtk; do
|
|
|
|
if [[ $(pidof $transmission_bin | wc -l) -ne 0 ]]; then
|
|
echo -e "\nClose all running Transmission client instances and run this script again.\n"
|
|
exit 1
|
|
fi
|
|
|
|
done
|
|
|
|
DAYS_AGO=$(date -d "now - $UPDATELIMIT_DAYS days" +%s)
|
|
|
|
###########################################################################
|
|
|
|
# Check bash version
|
|
|
|
BASH_CHECK=$(ps | grep `echo $$` | awk '{ print $4 }')
|
|
if [ ${BASH_CHECK} != "bash" ]; then
|
|
echo "
|
|
Please run this script using bash (/usr/bin/bash).
|
|
"
|
|
exit 1
|
|
else
|
|
if [[ $(bash --version | sed -n '1p' | awk '{print $4}' | sed 's/\..*$//g') -lt 4 ]]; then
|
|
echo "Use bash version 4 or newer."
|
|
exit
|
|
fi
|
|
fi
|
|
|
|
###########################################################################
|
|
|
|
# Internet connection test
|
|
|
|
CONNECTION=false
|
|
|
|
while [[ $CONNECTION == "false" ]]; do
|
|
|
|
INTERNET_TEST=$(ping -c 1 ${TEST_PROVIDER} 2>&1 | grep -c "Name or service not known")
|
|
if [[ ! $INTERNET_TEST -eq 0 ]]; then
|
|
echo -e "\nCan't connect to ${TEST_PROVIDER}. Please check your internet connection and try again.\n"
|
|
read -r -p "Retry connection? [y/N] " connect_answer
|
|
if [[ ! $(echo $connect_answer | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
exit
|
|
fi
|
|
else
|
|
CONNECTION="true"
|
|
fi
|
|
done
|
|
|
|
###########################################################################
|
|
|
|
# Delete all old bin files which are not in the list above
|
|
|
|
if [[ $(find "${TRANSMISSION_BLOCKLISTDIR}" -type f -iname "*.bin") ]]; then
|
|
|
|
p=0
|
|
for oldfile in $(find "${TRANSMISSION_BLOCKLISTDIR}" -type f -iname "*.bin"); do
|
|
COMPLISTS[$p]=$(echo ${oldfile} | sed 's/.*\///; s/\.[^.]*$//')
|
|
let p++
|
|
done
|
|
|
|
typeset -A DIFFARRAY
|
|
a=0
|
|
for olditem in "${COMPLISTS[@]}"; do
|
|
skip=
|
|
for item in "${!BLOCKLISTS[@]}"; do
|
|
if [[ ${olditem} == ${item} ]]; then
|
|
skip=1
|
|
break
|
|
fi
|
|
done
|
|
[[ -n $skip ]] || DIFFARRAY[$a]=${olditem}
|
|
let a++
|
|
done
|
|
|
|
if [[ "${#DIFFARRAY[@]}" -ne 0 ]]; then
|
|
for delfile in "${DIFFARRAY[@]}"; do
|
|
rm "${TRANSMISSION_BLOCKLISTDIR}/${delfile}.bin"
|
|
echo -e "Deleted old blocklist '${delfile}'."
|
|
done
|
|
fi
|
|
|
|
fi
|
|
############################################################
|
|
|
|
i=1
|
|
itemcount="${#BLOCKLISTS[@]}"
|
|
|
|
for listfile in "${!BLOCKLISTS[@]}"; do
|
|
|
|
listfile_bin=$(printf '%s%s.bin' "${TRANSMISSION_BLOCKLISTDIR}" "${listfile}")
|
|
listfile_url=$(printf '%s' "${BLOCKLISTS[$listfile]}")
|
|
|
|
function getfile() {
|
|
|
|
# TODO check existence of '&' symbol?
|
|
if [[ $(wget -S --timeout=${WGET_TIMEOUT} --spider $(echo "${listfile_url}" | awk -F "&" '{print $1}') 2>&1 | grep 'Remote file exists' | wc -l) -ge 1 ]]; then
|
|
echo "$i/$itemcount - Downloading blocklist '${listfile}'"
|
|
wget -q --show-progress -O - "$listfile_url" > "${TRANSMISSION_BLOCKLISTDIR}/${listfile}"
|
|
|
|
MIMETYPE=$(mimetype "${TRANSMISSION_BLOCKLISTDIR}/$listfile" | awk '{print $2}')
|
|
if [[ $MIMETYPE == "application/gzip" ]]; then
|
|
#This is only for gzip...
|
|
mv "${TRANSMISSION_BLOCKLISTDIR}"/$listfile "${TRANSMISSION_BLOCKLISTDIR}/$listfile.gz"
|
|
gzip -d "${TRANSMISSION_BLOCKLISTDIR}/$listfile.gz"
|
|
|
|
elif [[ $MIMETYPE == "application/zip" ]]; then
|
|
unzip -o -qq "${TRANSMISSION_BLOCKLISTDIR}/$listfile" -d "${TRANSMISSION_BLOCKLISTDIR}"
|
|
fi
|
|
|
|
else
|
|
echo "$i/$itemcount - Couldn't find blocklist '$listfile'. Please check and either update or delete URL of this file."
|
|
|
|
if [[ ! -v autoyes ]]; then
|
|
read -r -p "Continue? [y/N] " response
|
|
else
|
|
response="y"
|
|
fi
|
|
|
|
if [[ ! $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
exit
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Check existence of old blocklist files.
|
|
if [[ -f "${listfile_bin}" ]]; then
|
|
|
|
# File creation time
|
|
listfiletime=$(date -r "${listfile_bin}" +%s)
|
|
|
|
if [[ $listfiletime -le $DAYS_AGO ]]; then
|
|
echo -e "$i/$itemcount - Blocklist '$listfile' is older than $UPDATELIMIT_DAYS days.\nChecking if newer version exists."
|
|
getfile
|
|
else
|
|
echo -e "$i/$itemcount - Blocklist '$listfile' is already updated."
|
|
fi
|
|
|
|
else
|
|
getfile
|
|
fi
|
|
let i++
|
|
|
|
done
|
|
|
|
# Generates blocklist.bin
|
|
# Transmission doesn't have any internal switch to generate only blocklists so
|
|
# we launch the client with invalid torrent parameter 'dummy'
|
|
# Blocklist gets generated automatically after which the torrent file gets loaded
|
|
# into the program. Because there is no an actual torrent file, we get
|
|
# "Unrecognized torrent" error, in which case we kill the program
|
|
# Before this error is reached, Transmission has generated a correct blocklist file.
|
|
# This is just a dirty workaround.
|
|
#
|
|
transmission-cli -b dummytorrent |& while read -r line; do
|
|
if [[ $(echo ${line} | grep "Unrecognized torrent" | wc -l) -eq 1 ]]; then
|
|
kill $(pidof transmission-cli) 2> /dev/null
|
|
fi
|
|
done
|
|
|
|
#for listfile in "${!BLOCKLISTS[@]}"; do
|
|
# if [[ -f $TRANSMISSION_BLOCKLISTDIR/$listfile ]]; then
|
|
# rm $TRANSMISSION_BLOCKLISTDIR/$listfile
|
|
# fi
|
|
#done
|
|
|
|
# If not a bin file...
|
|
find $TRANSMISSION_BLOCKLISTDIR -type f ! -iname '*.bin' -delete
|
|
|
|
for file in $(ls $TRANSMISSION_BLOCKLISTDIR/*.bin); do
|
|
# If bin files are empty...
|
|
if [[ ! -s ${file} ]]; then
|
|
rm ${file}
|
|
fi
|
|
|
|
# Delete the following patterns in the names of existing .bin files. This is just because the names must match with the array LISTS keys
|
|
# For example ipfilter_AAA.p2p.bin -> ipfilter_AAA.bin -> ipfilter_AAA -> matches BLOCKLISTS array key
|
|
#
|
|
pattern=".p2p"
|
|
if [[ ${file} =~ $pattern ]]; then
|
|
mv ${file} $(echo ${file} | sed 's/\.p2p//g')
|
|
fi
|
|
done
|
|
|
|
unset autoyes
|
|
unset response
|
|
unset connect_answer
|
|
unset BLOCKLISTS
|