mirror of
				https://github.com/9001/copyparty.git
				synced 2025-10-31 04:32:20 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			129 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| # coding: utf-8
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import json
 | |
| import shutil
 | |
| import subprocess as sp
 | |
| 
 | |
| 
 | |
| _ = r"""
 | |
| start downloading a torrent by POSTing a magnet URL to copyparty,
 | |
| for example using 📟 (message-to-server-log) in the web-ui
 | |
| 
 | |
| by default it will download the torrent to the folder you were in
 | |
| when you pasted the magnet into the message-to-server-log field
 | |
| 
 | |
| you can optionally specify another location by adding a whitespace
 | |
| after the magnet URL followed by the name of the subfolder to DL into,
 | |
| or for example "anime/airing" would download to /srv/media/anime/airing
 | |
| because the keyword "anime" is in the DESTS config below
 | |
| 
 | |
| needs python3
 | |
| 
 | |
| example usage as global config (not a good idea):
 | |
|     python copyparty-sfx.py --xm aw,f,j,t60,bin/hooks/qbittorrent-magnet.py
 | |
| 
 | |
| parameters explained,
 | |
|     xm = execute on message (📟)
 | |
|     aw = only users with write-access can use this
 | |
|     f = fork; don't delay other hooks while this is running
 | |
|     j = provide message information as json (not just the text)
 | |
|     t60 = abort if qbittorrent has to think about it for more than 1 min
 | |
| 
 | |
| example usage as a volflag (per-volume config, much better):
 | |
|     -v srv/qb:qb:A,ed:c,xm=aw,f,j,t60,bin/hooks/qbittorrent-magnet.py
 | |
|                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | |
| 
 | |
|     (share filesystem-path srv/qb as volume /qb with Admin for user 'ed',
 | |
|      running this plugin on all messages with the params explained above)
 | |
| 
 | |
| example usage as a volflag in a copyparty config file:
 | |
|     [/qb]
 | |
|       srv/qb
 | |
|       accs:
 | |
|         A: ed
 | |
|       flags:
 | |
|         xm: aw,f,j,t60,bin/hooks/qbittorrent-magnet.py
 | |
| 
 | |
| the volflag examples only kicks in if you send the torrent magnet
 | |
| while you're in the /qb folder (or any folder below there)
 | |
| """
 | |
| 
 | |
| 
 | |
| # list of usernames to allow
 | |
| ALLOWLIST = [ "ed", "morpheus" ]
 | |
| 
 | |
| 
 | |
| # list of destination aliases to translate into full filesystem
 | |
| # paths; takes effect if the first folder component in the
 | |
| # custom download location matches anything in this dict
 | |
| DESTS = {
 | |
|     "iso": "/srv/pub/linux-isos",
 | |
|     "anime": "/srv/media/anime",
 | |
| }
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     inf = json.loads(sys.argv[1])
 | |
|     url = inf["txt"]
 | |
|     if not url.lower().startswith("magnet:?"):
 | |
|         # not a magnet, abort
 | |
|         return
 | |
| 
 | |
|     if inf["user"] not in ALLOWLIST:
 | |
|         print("🧲 denied for user", inf["user"])
 | |
|         return
 | |
| 
 | |
|     # might as well run the command inside the filesystem folder
 | |
|     # which matches the URL that the magnet message was sent to
 | |
|     os.chdir(inf["ap"])
 | |
| 
 | |
|     # is there is a custom download location in the url?
 | |
|     dst = ""
 | |
|     if " " in url:
 | |
|         url, dst = url.split(" ", 1)
 | |
| 
 | |
|         # is the location in the predefined list of locations?
 | |
|         parts = dst.replace("\\", "/").split("/")
 | |
|         if parts[0] in DESTS:
 | |
|             dst = os.path.join(DESTS[parts[0]], *(parts[1:]))
 | |
| 
 | |
|     else:
 | |
|         # nope, so download to the current folder instead;
 | |
|         # comment the dst line below to instead use the default
 | |
|         # download location from your qbittorrent settings
 | |
|         dst = inf["ap"]
 | |
|         pass
 | |
| 
 | |
|     # archlinux has a -nox suffix for qbittorrent if headless
 | |
|     # so check if we should be using that
 | |
|     if shutil.which("qbittorrent-nox"):
 | |
|         torrent_bin = "qbittorrent-nox"
 | |
|     else:
 | |
|         torrent_bin = "qbittorrent"
 | |
| 
 | |
|     # the command to add a new torrent, adjust if necessary
 | |
|     cmd = [torrent_bin, url]
 | |
|     if dst:
 | |
|         cmd += ["--save-path=%s" % (dst,)]
 | |
| 
 | |
|     # if copyparty and qbittorrent are running as different users
 | |
|     # you may have to do something like the following
 | |
|     # (assuming qbittorrent* is nopasswd-allowed in sudoers):
 | |
|     #
 | |
|     # cmd = ["sudo", "-u", "qbitter"] + cmd
 | |
| 
 | |
|     print("🧲", cmd)
 | |
| 
 | |
|     try:
 | |
|         sp.check_call(cmd)
 | |
|     except:
 | |
|         print("🧲 FAILED TO ADD", url)
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 | |
| 
 |