Skip to content

Instantly share code, notes, and snippets.

@CodyKochmann
Last active September 16, 2023 16:35
Show Gist options
  • Save CodyKochmann/b6ea601ec0f95e395b7439bd2b4c2eb7 to your computer and use it in GitHub Desktop.
Save CodyKochmann/b6ea601ec0f95e395b7439bd2b4c2eb7 to your computer and use it in GitHub Desktop.
Makefile for managing a directory of .magnet files for isolated parallel torrenting sessions using aria2c
# Author: Cody Kochmann
# Date Created: 2023-09-16
# Last Modified: 2023-09-16
# License: MIT
#
# This makefile spins up an aria2c process for every .magnet file in the current directory.
#
# It assumes it will be only one magnet link per each .magnet file.
#
# The benefit of this over just having a single aria2c call pull multiple magnet links from
# a single file is each magnet becomes individually monitorable both through the enhanced
# log files and through individual pid inspection. It also allows linux to handle any type
# of scaling, to fully utilize all cpu cores if needed, and keeps each download balanced
# using the linux congestion algorithms and process scheduler.
#
# As a last note, it also uses flocks to ensure two aria2c processes are never managing the
# same torrent. This allows the user to use mechanisms as simple as cronjobs to ensure
# specific directories are always being torrented from.
#
# tweaks to ensure correct shell is used
SHELL := /bin/bash
SHELLFLAGS := -euxo pipefail
# set the default target so simply calling "make" does the job
.DEFAULT_GOAL := torrent
# command to find all of the local magnet files in this directory
FIND_MAGNETS = find . -type f -name '*.magnet' -maxdepth 1 2>/dev/null
# generate metadata needed to guide make
MAGNET_FILES = $(shell $(FIND_MAGNETS))
MAGNET_FILE_COUNT = $(shell $(FIND_MAGNETS) | grep . -c)
MAGNET_LOG_FILES = $(subst .magnet,.magnet.log,$(MAGNET_FILES))
# log the metadata for debug purposes
$(info MAGNET_FILES=$(MAGNET_FILES))
$(info MAGNET_FILE_COUNT=$(MAGNET_FILE_COUNT))
$(info MAGNET_LOG_FILES=$(MAGNET_LOG_FILES))
# string templates to get data from magnet files using the target log files as reference
GET_MAGNET_FILE_FROM_LOG_FILE = $(subst .magnet.log,.magnet,$@)
GET_MAGNET_FROM_LOG_FILE = $(shell grep $(GET_MAGNET_FILE_FROM_LOG_FILE) -e '^magnet' | tr -d ' \n\t')
# string template to flock the log file to ensure duplicate downloads are not started
LOCK_MAGNET_FILE = flock --exclusive --nonblock $(GET_MAGNET_FILE_FROM_LOG_FILE)
# string template to configure what options aria2c will be executed with
ARIA2C_DOWNLOAD = aria2c --check-integrity=true --allow-overwrite=true --bt-force-encryption=true
# string template to add further context to the log files
LOGGER = logger --rfc5424=notq --socket-errors=off -t 'aria2-$(GET_MAGNET_FILE_FROM_LOG_FILE)' --stderr
# target to refresh the log files
clean-logs:
rm -fv $(MAGNET_LOG_FILES)
# primary mechanism that fires aria2c by making the log files for each torrent the easy to manage make target
$(MAGNET_LOG_FILES):
$(LOCK_MAGNET_FILE) $(ARIA2C_DOWNLOAD) '$(GET_MAGNET_FROM_LOG_FILE)' 2>&1 | $(LOGGER) 2>&1 | tee '$@'
# singleton make target that puts all the log files into a single target for make to plan around
_torrents: $(MAGNET_LOG_FILES)
# primary target for the user to operate with that forks make into as many parallel jobs as it needs to host every magnet
torrent:
$(MAKE) -j $(MAGNET_FILE_COUNT) _torrents
# define phony targets for make to know about
.PHONY: _torrents torrent clean-logs $(MAGNET_LOG_FILES)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment