Download and set up multiple blocklists for your Transmission BitTorrent client in a simple way (Linux)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
9.1 KiB

5 years ago
  1. #!/bin/bash
  2. # Transmission BitTorrent blocklist downloader
  3. # Copyright (C) 2018 Pekka Helenius
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. ###########################################################################
  18. # TODO Remove duplicate IP's from list files (does Transmission do this automatically?)
  19. # TODO Support more archive/text formats
  20. # Only zip & gz archives are currently supported
  21. # TODO "Older than XX days" check not always working?
  22. ###########################################################################
  23. # Usage:
  24. # bash transmission_blocklists.sh
  25. # bash transmission_blocklists.sh -y
  26. # where -y parameter passes all Yes/No questions with auto-yes answer
  27. # Exception: internet connection test
  28. # Requirements:
  29. # Unix-based OS
  30. # Bash shell 4.0 or above
  31. # Internet connection
  32. # Transmission client installed
  33. # gzip
  34. ###########################################################################
  35. # BLOCKLISTS
  36. typeset -A BLOCKLISTS
  37. #####################################
  38. # Blocklist syntax:
  39. # [list_1-friendly-name]="list_1_URL"
  40. # [list_2-friendly-name]="list_2_URL"
  41. # ...
  42. # where list_URL must point to some of the following archive types: zip, gz
  43. # For example:
  44. # [Yoyo-adservers]="http://list.iblocklist.com/?list=zhogegszwduurnvsyhdf&fileformat=p2p&archiveformat=gz"
  45. #####################################
  46. BLOCKLISTS=(
  47. [Yoyo-adservers]="http://list.iblocklist.com/?list=zhogegszwduurnvsyhdf&fileformat=p2p&archiveformat=gz"
  48. )
  49. ###########################################################################
  50. # Basic configuration
  51. # Older blocklist files than this should be updated. Value in days.
  52. UPDATELIMIT_DAYS=15
  53. # Timeout for wget in getfile function, seconds
  54. WGET_TIMEOUT=30
  55. # Transmission client blocklist directory for the current user
  56. TRANSMISSION_BLOCKLISTDIR=$HOME/.config/transmission/blocklists/
  57. # We need to make internet connection test. The following URL is used for
  58. # testing.
  59. TEST_PROVIDER="www.github.com"
  60. ###########################################################################
  61. if [[ $1 == "-y" ]]; then
  62. autoyes=''
  63. fi
  64. ###########################################################################
  65. # Commands required by this script
  66. COMMANDS=(bash transmission-cli wget gzip date find kill awk sed grep ping unzip mv wc)
  67. for command in "${COMMANDS[@]}"; do
  68. if [[ $(echo $(which "${command}" &>/dev/null)$?) -ne 0 ]]; then
  69. echo "Command ${command} not found. Can't run the script."
  70. exit 1
  71. fi
  72. done
  73. ###########################################################################
  74. for transmission_bin in transmission-qt transmission-gtk; do
  75. if [[ $(pidof $transmission_bin | wc -l) -ne 0 ]]; then
  76. echo -e "\nClose all running Transmission client instances and run this script again.\n"
  77. exit 1
  78. fi
  79. done
  80. DAYS_AGO=$(date -d "now - $UPDATELIMIT_DAYS days" +%s)
  81. ###########################################################################
  82. # Check bash version
  83. BASH_CHECK=$(ps | grep `echo $$` | awk '{ print $4 }')
  84. if [ ${BASH_CHECK} != "bash" ]; then
  85. echo "
  86. Please run this script using bash (/usr/bin/bash).
  87. "
  88. exit 1
  89. else
  90. if [[ $(bash --version | sed -n '1p' | awk '{print $4}' | sed 's/\..*$//g') -lt 4 ]]; then
  91. echo "Use bash version 4 or newer."
  92. exit
  93. fi
  94. fi
  95. ###########################################################################
  96. # Internet connection test
  97. CONNECTION=false
  98. while [[ $CONNECTION == "false" ]]; do
  99. INTERNET_TEST=$(ping -c 1 ${TEST_PROVIDER} 2>&1 | grep -c "Name or service not known")
  100. if [[ ! $INTERNET_TEST -eq 0 ]]; then
  101. echo -e "\nCan't connect to ${TEST_PROVIDER}. Please check your internet connection and try again.\n"
  102. read -r -p "Retry connection? [y/N] " connect_answer
  103. if [[ ! $(echo $connect_answer | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  104. exit
  105. fi
  106. else
  107. CONNECTION="true"
  108. fi
  109. done
  110. ###########################################################################
  111. # Delete all old bin files which are not in the list above
  112. if [[ $(find "${TRANSMISSION_BLOCKLISTDIR}" -type f -iname "*.bin") ]]; then
  113. p=0
  114. for oldfile in $(find "${TRANSMISSION_BLOCKLISTDIR}" -type f -iname "*.bin"); do
  115. COMPLISTS[$p]=$(echo ${oldfile} | sed 's/.*\///; s/\.[^.]*$//')
  116. let p++
  117. done
  118. typeset -A DIFFARRAY
  119. a=0
  120. for olditem in "${COMPLISTS[@]}"; do
  121. skip=
  122. for item in "${!BLOCKLISTS[@]}"; do
  123. if [[ ${olditem} == ${item} ]]; then
  124. skip=1
  125. break
  126. fi
  127. done
  128. [[ -n $skip ]] || DIFFARRAY[$a]=${olditem}
  129. let a++
  130. done
  131. if [[ "${#DIFFARRAY[@]}" -ne 0 ]]; then
  132. for delfile in "${DIFFARRAY[@]}"; do
  133. rm "${TRANSMISSION_BLOCKLISTDIR}/${delfile}.bin"
  134. echo -e "Deleted old blocklist '${delfile}'."
  135. done
  136. fi
  137. fi
  138. ############################################################
  139. i=1
  140. itemcount="${#BLOCKLISTS[@]}"
  141. for listfile in "${!BLOCKLISTS[@]}"; do
  142. listfile_bin=$(printf '%s%s.bin' "${TRANSMISSION_BLOCKLISTDIR}" "${listfile}")
  143. listfile_url=$(printf '%s' "${BLOCKLISTS[$listfile]}")
  144. function getfile() {
  145. # TODO check existence of '&' symbol?
  146. 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
  147. echo "$i/$itemcount - Downloading blocklist '${listfile}'"
  148. wget -q --show-progress -O - "$listfile_url" > "${TRANSMISSION_BLOCKLISTDIR}/${listfile}"
  149. MIMETYPE=$(mimetype "${TRANSMISSION_BLOCKLISTDIR}/$listfile" | awk '{print $2}')
  150. if [[ $MIMETYPE == "application/gzip" ]]; then
  151. #This is only for gzip...
  152. mv "${TRANSMISSION_BLOCKLISTDIR}"/$listfile "${TRANSMISSION_BLOCKLISTDIR}/$listfile.gz"
  153. gzip -d "${TRANSMISSION_BLOCKLISTDIR}/$listfile.gz"
  154. elif [[ $MIMETYPE == "application/zip" ]]; then
  155. unzip -o -qq "${TRANSMISSION_BLOCKLISTDIR}/$listfile" -d "${TRANSMISSION_BLOCKLISTDIR}"
  156. fi
  157. else
  158. echo "$i/$itemcount - Couldn't find blocklist '$listfile'. Please check and either update or delete URL of this file."
  159. if [[ ! -v autoyes ]]; then
  160. read -r -p "Continue? [y/N] " response
  161. else
  162. response="y"
  163. fi
  164. if [[ ! $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  165. exit
  166. fi
  167. fi
  168. }
  169. # Check existence of old blocklist files.
  170. if [[ -f "${listfile_bin}" ]]; then
  171. # File creation time
  172. listfiletime=$(date -r "${listfile_bin}" +%s)
  173. if [[ $listfiletime -le $DAYS_AGO ]]; then
  174. echo -e "$i/$itemcount - Blocklist '$listfile' is older than $UPDATELIMIT_DAYS days.\nChecking if newer version exists."
  175. getfile
  176. else
  177. echo -e "$i/$itemcount - Blocklist '$listfile' is already updated."
  178. fi
  179. else
  180. getfile
  181. fi
  182. let i++
  183. done
  184. # Generates blocklist.bin
  185. # Transmission doesn't have any internal switch to generate only blocklists so
  186. # we launch the client with invalid torrent parameter 'dummy'
  187. # Blocklist gets generated automatically after which the torrent file gets loaded
  188. # into the program. Because there is no an actual torrent file, we get
  189. # "Unrecognized torrent" error, in which case we kill the program
  190. # Before this error is reached, Transmission has generated a correct blocklist file.
  191. # This is just a dirty workaround.
  192. #
  193. transmission-cli -b dummytorrent |& while read -r line; do
  194. if [[ $(echo ${line} | grep "Unrecognized torrent" | wc -l) -eq 1 ]]; then
  195. kill $(pidof transmission-cli) 2> /dev/null
  196. fi
  197. done
  198. #for listfile in "${!BLOCKLISTS[@]}"; do
  199. # if [[ -f $TRANSMISSION_BLOCKLISTDIR/$listfile ]]; then
  200. # rm $TRANSMISSION_BLOCKLISTDIR/$listfile
  201. # fi
  202. #done
  203. # If not a bin file...
  204. find $TRANSMISSION_BLOCKLISTDIR -type f ! -iname '*.bin' -delete
  205. for file in $(ls $TRANSMISSION_BLOCKLISTDIR/*.bin); do
  206. # If bin files are empty...
  207. if [[ ! -s ${file} ]]; then
  208. rm ${file}
  209. fi
  210. # Delete the following patterns in the names of existing .bin files. This is just because the names must match with the array LISTS keys
  211. # For example ipfilter_AAA.p2p.bin -> ipfilter_AAA.bin -> ipfilter_AAA -> matches BLOCKLISTS array key
  212. #
  213. pattern=".p2p"
  214. if [[ ${file} =~ $pattern ]]; then
  215. mv ${file} $(echo ${file} | sed 's/\.p2p//g')
  216. fi
  217. done
  218. unset autoyes
  219. unset response
  220. unset connect_answer
  221. unset BLOCKLISTS