Coder Social home page Coder Social logo

kannibalox / pyrosimple Goto Github PK

View Code? Open in Web Editor NEW
43.0 6.0 5.0 5.03 MB

An overhauled fork of the pyrocore tools for rTorrent

Home Page: https://kannibalox.github.io/pyrosimple/

License: GNU General Public License v3.0

Python 99.68% Dockerfile 0.16% Shell 0.16%
python rtorrent rtorrent-ps

pyrosimple's People

Contributors

chros73 avatar jeremymahieu avatar johnflowerful avatar jonesman avatar kannibalox avatar nosubstitute avatar pyroscope avatar qtlunya avatar tmd20 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pyrosimple's Issues

Moving completed torrents

If I run this command:

rtcontrol alias=TRK realpath="$HOME/torrents/rtorrent" --move-and-set "$HOME/torrents/TRK"

nothing gets moved and there is no output.

If I run the this one:

mkdir -p $HOME/torrents/TRK
rtcontrol --to-view=trk-to-move alias=TRK realpath=$HOME/torrents/rtorrent is_complete=yes
rtcontrol --from-view=trk-to-move // --yes \
  --stop \
  --spawn "mv {{item.path}} /$HOME/torrents/TRK" \
  --exec "directory.set=$HOME/torrents/TRK" \
  --flush \
  --start
rtcontrol --modify-view=trk-to-move --alter=remove realpath=$HOME/torrents/TRK

I get this:

Filtered 0 out of 10391 torrents using [ OrNode["AndNode['PatternFilter', 'PatternFilter', 'BoolFilter']"] ]

and nothing gets moved.

I've missed something, but I can't figured out what it is. Could you tell me what I'm missing to get the completed torrents moved.

Thanks

pyrotorque crashes

Hi,
Not really sure what I'm doing wrong here.

If relevant, my platform is 32 bit ARM so perhaps that is going to be no bueno.

➜  ~ pyrotorque --restart --fg --debug 
DEBUG:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:Options: adopt_stale_pid_file=False, dry_run=False, log_file=None, log_level=10, no_fork=True, pid_file=None, print_completion=None, restart=True, run_once=None, status=False, stop=False, url=None
DEBUG:pyrosimple.config:Configuration file '/home/alzheimers/.config/pyrosimple/config.py' not found.
INFO:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:No pid file '/run/user/1000/pyrotorque.pid'
/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/tzlocal/unix.py:192: UserWarning: Can not find any timezone configuration, defaulting to UTC.
  warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
2023-09-18 06:57:06,514 DEBUG pyrosimple.config: Loading rtorrent config from '/home/alzheimers/.rtorrent.rc'
2023-09-18 06:57:06,518 DEBUG pyrosimple.config: rtorrent.rc: network.scgi.open_local = /home/alzheimers/rpc.socket
2023-09-18 06:57:06,519 DEBUG pyrosimple.pyrotorque.jobs.tv: pyrosimple.job.base:tv created with config {'handler': 'pyrocore.job.watch:TreeWatch', 'schedule': {'minute': '*/1'}, 'check_unhandled': True, 'path': '/home/alzheimers/data/torrents/watch/tv', 'started': False, 'cmd_download_directory': 'd.directory.set=/home/alzheimers/data/torrents/tv', 'dry_run': False}
2023-09-18 06:57:06,520 DEBUG pyrosimple.util.rpc: method 'system.multicall', params ([{'methodName': 'system.client_version', 'params': []}, {'methodName': 'system.library_version', 'params': []}, {'methodName': 'system.time_usec', 'params': []}, {'methodName': 'session.name', 'params': []}, {'methodName': 'session.path', 'params': []}, {'methodName': 'system.cwd', 'params': []}],)
2023-09-18 06:57:06,523 DEBUG pyrosimple.util.rpc: method 'startup_time', params ()
2023-09-18 06:57:06,526 DEBUG pyrosimple.torrent.rtorrent.RtorrentEngine: RtorrentEngine connected to alarm:707 [rTorrent 0.13.8/0.9.8] via 'scgi+unix:///home/alzheimers/rpc.socket'
2023-09-18 06:57:06,531 DEBUG pyrosimple.util.rpc: method 'd.hash', params ('03A10CC1C3BA2235B017264693261C1E7FDB6B3C',)
2023-09-18 06:57:06,534  INFO pyrosimple.pyrotorque.jobs.tv: Hash 03A10CC1C3BA2235B017264693261C1E7FDB6B3C already found in client, skipping
2023-09-18 06:57:06,536 DEBUG pyrosimple.util.rpc: method 'd.hash', params ('97C055B0E73C1BC751B37267AFE12C54E2391CED',)
2023-09-18 06:57:06,538  INFO pyrosimple.pyrotorque.jobs.tv: Hash 97C055B0E73C1BC751B37267AFE12C54E2391CED already found in client, skipping
2023-09-18 06:57:06,550 DEBUG pyrosimple.pyrotorque.jobs.queue: pyrosimple.job.base:queue created with config {'handler': 'pyrocore.job.queue:QueueManager', 'schedule': {'minute': '*/1'}, 'start_at_once': 1, 'downloading': 'is_active=yes is_complete=no down>0', 'downloading_max': 1, 'dry_run': False}
2023-09-18 06:57:06,551  INFO pyrosimple.scripts.pyrotorque.RtorrentQueueManager: Shutting down scheduler...
2023-09-18 06:57:06,551  INFO pyrosimple.scripts.pyrotorque.RtorrentQueueManager: Total time: 0.586 seconds.
Traceback (most recent call last):
  File "/home/alzheimers/.local/bin/pyrotorque", line 8, in <module>
    sys.exit(run())
             ^^^^^
  File "/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/pyrotorque.py", line 349, in run
    RtorrentQueueManager().run()
  File "/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/base.py", line 178, in run
    self.mainloop()
  File "/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/pyrotorque.py", line 339, in mainloop
    self.add_jobs()
  File "/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/pyrotorque.py", line 144, in add_jobs
    self.classes[name] = params["__handler"](params)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/job/queue.py", line 22, in __init__
    super().__init__(config)
  File "/home/alzheimers/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/job/base.py", line 57, in __init__
    query_tree = matching.QueryGrammar.parse(self.config["matcher"])
                                             ~~~~~~~~~~~^^^^^^^^^^^
KeyError: 'matcher'
[TORQUE]
 
[TORQUE.tv]
handler = "pyrocore.job.watch:TreeWatch"
schedule = "minute=*/1"
check_unhandled = true
path = "/home/alzheimers/data/torrents/watch/tv"
started = false
cmd_download_directory = "d.directory.set=/home/alzheimers/data/torrents/tv"
 
[TORQUE.queue]
handler         = "pyrocore.job.queue:QueueManager"
schedule        = "minute=*/1"
start_at_once   = 1
downloading     = "is_active=yes is_complete=no down>0"
downloading_max = 1

pyrotorque multiple clients

Is it possible to setup per client pyrosimple
jobs

I'm going to try to move my pyrotorque config from pyrocore to pyrosimple
Previously I had two different clients, both with their own config files.

However now everything lives in one config file. So from what I can see all my client have to share the same jobs. Along with the console outputs those jobs bring with them

"Copy Session Metafiles by Category" example

Is the below code from https://kannibalox.github.io/pyrosimple/advanced/#copy-session-metafiles-by-category supposed to work? It gives me jinja2.exceptions.TemplateSyntaxError: unexpected char '\\' at 45. It seems it was copied as is from pyrocore documentation and I don't feel like decoding this clutter of quotes and escapes.

target="/tmp/metafiles"
rm -rf "$target"
rtcontrol // \
    --spawn "mkdir -p \"$target/"'{{i.fetch(1) or \"_NOLABEL\"}}"' \
    --spawn 'cp {{i.sessionfile}} "'"$target"'/{{item.fetch(1) or \"_NOLABEL\"}}/{{item.name}}-{{item.hash[:7]}}.torrent"'

chtor error KeyError: <class 'pyrosimple.util.metafile.Metafile'>

Hi, I am trying to use chtor. This worked when using pyroscope. Not sure what I'm doing wrong?

data@data:~/src/dotfiles$ chtor -RC -o /tmp /tor/data1/session/some.torrent
Traceback (most recent call last):
  File "/home/data/bin/chtor", line 8, in <module>
    sys.exit(run())
             ^^^^^
  File "/home/data/.venv/lib/python3.11/site-packages/pyrosimple/scripts/chtor.py", line 458, in run
    MetafileChanger().run()
  File "/home/data/.venv/lib/python3.11/site-packages/pyrosimple/scripts/base.py", line 173, in run
    self.mainloop()
  File "/home/data/.venv/lib/python3.11/site-packages/pyrosimple/scripts/chtor.py", line 405, in mainloop
    fh.write(bencode.bencode(torrent))
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/data/.venv/lib/python3.11/site-packages/bencodepy/__init__.py", line 85, in encode
    return self.encoder.encode(value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/data/.venv/lib/python3.11/site-packages/bencodepy/encoder.py", line 85, in encode
    self.encode_func[type(value)](value, r)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: <class 'pyrosimple.util.metafile.Metafile'>```

`hashcheck` is not available

I just found out that hashcheck from pyrocore is not present in pyrosimple. Now I am wondering whether this omission is intentional.

Inverse conditions do not match documentation

I have a group of incomplete items that I'm using to test tag filtering.
All incomplete items have been tagged with testtag.

rtcontrol is_complete=no tagged=\!'testtag' -o tagged,name -q works and no results are returned (as expected).
rtcontrol is_complete=no tagged!='testtag' -o tagged,name -q returns all incomplete items including testtag items.
rtcontrol is_complete=no 'tagged!=testtag' -o tagged,name -q returns all incomplete items including testtag items.

The last two are puzzling because I thought when multiple filters are used it defaults to AND but it's behaving as if it's OR.
rtcontrol tagged="" doesn't appear to work as documented but rtcontrol tagged=\"\" does.

Using rtorrent-ps with pyrosimple?

Hi,

Thanks for porting this to python3!

Reading the docs, I am lost on how to get rtorrent-ps working with pyrosimple

Pyroscope + rtorrent-ps sets up a bunch of torrent config files and imports.. Does pyrosimple do the same ?

When starting, it fails as the pyroadmin command has changed. For example, the existing rtorrent.rc has

But that does not work with pyrosimple as the command has changed and --create-import no longer exists?

I then tried to follow https://kannibalox.github.io/pyrosimple/rtorrent-config/#rtorrent-installation but --create-rtorrent-rc also does not seem to exist?

Hoping you can point me in the right direction.

Thanks!

No error message produced by rtcontrol when querying for unknown field.

Hello,

I just noticed this issue in your fork of rtcontrol.

When I issued this command in the OG version of pyrocore's tools

rtcontrol name=Blah -o random_unknown_field
ERROR    Unknown field name 'random_unknown_field'

When I run this in pyrosimple, I get this.

rtcontrol name=Blah -o random_unknown_field
Traceback (most recent call last):
  File "/home/foobar/.venv/lib/python3.11/site-packages/pyrosimple/scripts/base.py", line 181, in run
    self.mainloop()
  File "/home/foobar/.venv/lib/python3.11/site-packages/pyrosimple/scripts/rtcontrol.py", line 774, in mainloop
    self.validate_output_format(default_output_format)
  File "/home/foobar/.venv/lib/python3.11/site-packages/pyrosimple/scripts/rtcontrol.py", line 624, in validate_output_format
    for field in rtorrent.validate_field_list(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/foobar/.venv/lib/python3.11/site-packages/pyrosimple/torrent/rtorrent.py", line 975, in validate_field_list
    raise error.UserError(f"Unknown field name {name!r}")
pyrosimple.error.UserError: Unknown field name 'random_unkown_field'

Did I not install pyrosimple properly?

Thank you!

Issue with query

I'm trying to get this query to work
rtcontrol -U media [ratio=-1 OR seedtime=-1 ] custom_1=TV => does not work
ultimately the goal is to get this to work
rtcontrol -U media [ratio=+1 OR seedtime=+8d ] custom_1=TV => does not work

The first query should always return something if custom_1=TV has result

In my attempts to see what is going on I have tried
rtcontrol -U media ratio=-1 OR seedtime=-1 => does not work
strangely this does work
rtcontrol -U media ratio=-1 seedtime=-1 => works

The first query should always work if the second query works, unless the first query is a XOR

Lastly here is a query that has all three elements
rtcontrol -U media ratio=-1 seedtime=-1 custom_1=TV => works

However trying to do or between ratio and seedtime fails
rtcontrol -U media ratio=-1 OR seedtime=-1 custom_1=TV => does not work

custom fields

I'm been looking through this code for a bit.

I think I'm starting to understand how it works a little bit.
From what I can tell
There is a class called torrentproxy, that stores some information on how to retrieve data from rtorrent via a descriptor class

The issue that I am seeing is that the fielddescriptor object created for a custom class . Does not have the right query setup

For example

command
rtcontrol ratio=+0 custom_1=TV


At this line I added a print statement
        if rpc_fields is not None:
            self._rpc_cache.update(rpc_fields)
        if "hash" not in fields:
            self._fields["hash"] = self.rpc_call("d.hash")
        print(rpc_fields)

{'d.complete': 0, 'd.completed_bytes': 0, 'd.custom=1': '', 'd.custom=memo_alias': '', 'd.down.rate': 0, 'd.hash': '2345D93204EA6A904D0CAF60791D79C20E270943', 'd.is_active': 0, 'd.is_open': 0, 'd.is_private': 1, 'd.name': 'Vengeance.2022.BluRay.1080p.DTS-HD.MA.5.1.AVC.REMUX-FraMeSToR', 'd.priority': 0, 'd.ratio': 0, 'd.size_bytes': 30879977086, 'd.throttle_name': '', 'd.up.rate': 0}

d.custom=1 is not being set for some reason

`            for item in raw_items:
                ritem = RtorrentItem(
                    self,
                    fields={},
                    rpc_fields=dict(zip(args, item)),
                )

                if view.matcher:
                    if view.matcher.match(ritem):
                        items.append(ritem)
                        yield items[-1]
                else:
                    items.append(ritem)
                    yield items[-1]`

This ends up with no items being added
The end result is an empty list

I can get it to work by switching this line
accessor=lambda o: o.rpc_call("d.custom", [custom_name]),
to
accessor=lambda o: o.rpc_call(f"d.custom{custom_name}"),

Unable to delete torrent

Hello,

I was attempting a simple deletion of a torrent and I got this, am I doing something wrong?

someuser@node:~/bin$ rtcontrol hash=<hash> // --purge
2023-09-10 10:06:49 purge        <somefile>
purge? [Y)es, n)o, a)ll yes, q)uit]: Y
Traceback (most recent call last):
  File "/home/someuser/.local/bin/rtcontrol", line 8, in <module>
    sys.exit(run())
  File "/home/someuser/.local/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 1047, in run
    RtorrentControl().run()
  File "/home/someuser/.local/lib/python3.10/site-packages/pyrosimple/scripts/base.py", line 181, in run
    self.mainloop()
  File "/home/someuser/.local/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 944, in mainloop
    getattr(item, action["method"])(*args)
  File "/home/someuser/.local/lib/python3.10/site-packages/pyrosimple/torrent/rtorrent.py", line 529, in purge
    self.cull(file_filter=partial_file, attrs=["completed_chunks", "size_chunks"])
  File "/home/someuser/.local/lib/python3.10/site-packages/pyrosimple/torrent/rtorrent.py", line 568, in cull
    self._engine.logger.debug("Cleaning up directory '%s'", fullpath)
UnboundLocalError: local variable 'fullpath' referenced before assignment

incompatible with rtorrent 0.9.6 or 0.9.7 new

pyrosimple.error.EngineError: While getting download items from RtorrentEngine connected to 0bf35a9044ef:29 [rTorrent 0.13.7/0.9.7, up 0s] via 'scgi+unix:///downloads/.rtorrent/socket': <Fault -506: "Method 'd.multicall.filtered' not defined">

Seems like this function in only added in rtorrent 0.9.8...

rtorrent 0..9.6
latest pryosimple 2.4.0.

Custom field doesn't return results with another condition

When I run rtcontrol custom_1=tvshows I get output like I'd expect. If I run rtcontrol completed=+2w I also get output as expected.
However when I combine these two using rtcontrol custom_1=tvshows completed=+2w I get no results.

I believe the syntax is correct on combining the two conditions, but anytime I use custom_1 and an additional conditional it returns no results.

Adding tags throws an attribute error

This behavior is happening when trying to add a tag. rtcontrol --tag "processed" completed=-12h

Traceback (most recent call last):
  File "/home/youser/.local/bin/rtcontrol", line 8, in <module>
    sys.exit(run())
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/scripts/rtcontrol.py", line 908, in run
    RtorrentControl().run()
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/scripts/base.py", line 180, in run
    self.mainloop()
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/scripts/rtcontrol.py", line 806, in mainloop
    getattr(item, action["method"])(*args)
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/torrent/rtorrent.py", line 309, in tag
    tagset = previous.copy()
AttributeError: 'str' object has no attribute 'copy'

Don't require rtorrent.rc file if we don't want to interact with rtorrent

Commands such as mktor and chtor complain that ~/.rtorrent.rc doesn't exist even if I don't want to interface with rtorrent at all. As a workaround, PYRO_RTORRENT_RC=/dev/null seems to work, but it would be better to not have to do that.

❯ chtor --version
chtor 2.0.0rc4 on Python 3.10.4

❯ git rev-parse HEAD
d713a2aed82b1a50e98dc4915ebbade47d75aa5a

❯ chtor
Traceback (most recent call last):
  File "/home/nyuszika7h/src/pyrosimple/src/pyrosimple/scripts/base.py", line 181, in run
    self.get_options()
  File "/home/nyuszika7h/src/pyrosimple/src/pyrosimple/scripts/base.py", line 235, in get_options
    self.engine = rtorrent.RtorrentEngine()
  File "/home/nyuszika7h/src/pyrosimple/src/pyrosimple/torrent/rtorrent.py", line 616, in __init__
    config.autoload_scgi_url()
  File "/home/nyuszika7h/src/pyrosimple/src/pyrosimple/config.py", line 105, in autoload_scgi_url
    raise error.UserError(f"rTorrent RC file '{rcfile}' doesn't exist!")
pyrosimple.error.UserError: rTorrent RC file '/home/nyuszika7h/.rtorrent.rc' doesn't exist!

❯ PYRO_RTORRENT_RC=/dev/null chtor
usage: chtor [options] <metafile>...

chtor 2.0.0rc4 on Python 3.10.4

Change attributes of a bittorrent metafile.

For more details, see the full documentation at

    https://kannibalox.github.io/pyrosimple/
chtor: error: No metafiles given, nothing to do!

pyrotorque in detach mode exits during startup

When running pyrotorque in default daemon/detached mode it simply just exits and doesn't start:

rtorrent [ / ]$ pyrotorque --debug --verbose
INFO:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:Writing pid to <TimeoutPIDLockFile: PosixPath('/opt/rtorrent/.pyrosimple/run/pyrotorque.pid') -- PosixPath('/opt/rtorrent/.pyrosimple/run/pyrotorque.pid')> and detaching process...
INFO:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:Logging stderr/stdout to None
rtorrent [ / ]$ pyrotorque --status
ERROR:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:No pyrotorque process found.
rtorrent [ / ]$ ps -a
    PID TTY          TIME CMD
     54 pts/1    00:00:00 bash
     59 pts/1    00:03:10 rtorrent main
     99 pts/2    00:00:00 ps
rtorrent [ / ]$

--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=90, si_uid=1001, si_status=0, si_utime=0, si_stime=0} ---
newfstatat(4, "", {st_mode=S_IFIFO|0600, st_size=0, ...}, AT_EMPTY_PATH) = 0
read(4, "139 libs found in cache `/etc/ld"..., 8192) = 8192
read(4, "g (GNU libc) stable release vers"..., 8448) = 41
read(4, "", 8407)                       = 0
close(4)                                = 0
wait4(90, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 90
uname({sysname="Linux", nodename="b382caa8a5d2", ...}) = 0
getpid()                                = 89
getuid()                                = 1001
getgid()                                = 1002
getpid()                                = 89
write(2, "INFO:pyrosimple.scripts.pyrotorq"..., 237INFO:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:Writing pid to <TimeoutPIDLockFile: PosixPath('/opt/rtorrent/.pyrosimple/run/pyrotorque.pid') -- PosixPath('/opt/rtorrent/.pyrosimple/run/pyrotorque.pid')> and detaching process...
) = 237
getpid()                                = 89
write(2, "INFO:pyrosimple.scripts.pyrotorq"..., 86INFO:pyrosimple.scripts.pyrotorque.RtorrentQueueManager:Logging stderr/stdout to None
) = 86
prlimit64(0, RLIMIT_CORE, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_CORE, {rlim_cur=0, rlim_max=0}, NULL) = 0
umask(000)                              = 022
chdir("/")                              = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(3)                                = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(3)                                = 0
newfstatat(AT_FDCWD, "/etc/nsswitch.conf", {st_mode=S_IFREG|0644, st_size=199, ...}, 0) = 0
newfstatat(AT_FDCWD, "/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=199, ...}, AT_EMPTY_PATH) = 0
read(3, "#       Begin /etc/nsswitch.conf"..., 4096) = 199
read(3, "", 4096)                       = 0
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=199, ...}, AT_EMPTY_PATH) = 0
close(3)                                = 0
openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=759, ...}, AT_EMPTY_PATH) = 0
lseek(3, 0, SEEK_SET)                   = 0
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 759
close(3)                                = 0
setgid(1002)                            = 0
setuid(1001)                            = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f222c17da10) = 91
exit_group(0)                           = ?
+++ exited with 0 +++

working in FG mode

rtorrent [ / ]$ pyrotorque --debug --verbose --fg
/opt/rtorrent/.local/lib/python3.11/site-packages/tzlocal/unix.py:192: UserWarning: Can not find any timezone configuration, defaulting to UTC.
  warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
2023-07-15 16:35:18,956  INFO pyrosimple.pyrotorque.jobs.queue: Startable matcher is: is_ignored=0 done=0 message="" prio>0
2023-07-15 16:35:18,956  INFO pyrosimple.pyrotorque.jobs.queue: Downloading matcher is: OrNode["AndNode['BoolFilter', 'BoolFilter']"]


pyrotorque dependency issue

So I was able to fix this error

File "/root/.local/bin/pyrotorque", line 5, in
from pyrosimple.scripts.pyrotorque import run
File "/root/.local/pipx/venvs/pyrosimple/lib/python3.10/site-packages/pyrosimple/scripts/pyrotorque.py", line 15, in
from apscheduler.schedulers.background import BackgroundScheduler
ModuleNotFoundError: No module named 'apscheduler'

Issue seems to be that apscheduler is not installed as part of the default package from pypi

pyrotorque bad module name

Trying to migrate from pyrocore to pyrosimple. I've finished migrating all of the torque configuration but when I run
pyrotorque --fg
I simply get an error:
vncviewer_2022-12-29_12-54-51

I have all the dependencies installed:
vncviewer_2022-12-29_12-55-17

torque config:

## https://github.com/kannibalox/pyrosimple/blob/main/docs/pyrotorque-jobs.md
[TORQUE]
autoreload = true # false by default
[TORQUE.queue]
handler = "pyrocore.torrent.watch:QueueManager"
schedule = "second=*/15"
active = true
dry_run = false
sort_fields = "-prio, loaded, name"
downloading_min = 1
downloading_max = 9
start_at_once = 4
intermission = 0
startable = "is_ignored=0 done=0 message='' prio>0"
[TORQUE.stats]
handler = "pyrocore.torrent.jobs:EngineStats"
schedule = "minute=*"
active = true
dry_run = false
[TORQUE.watch]
handler = "pyrocore.torrent.watch:TreeWatch"
schedule = "second=*/5"
active = true
dry_run = false
load_mode = "start"
queued = true
path = "/mnt/torrent/start"

`SCGI_URL` doesn't allow the use of `~` in local socket path

It is not possible to use ~ when configuring SCGI with local socket.

SCGI_URL = "~/.config/rtorrent/socket"

results in

FileNotFoundError: [Errno 2] No such file or directory

while

SCGI_URL = "/home/user/.config/rtorrent/socket"

works fine.

I didn't do much debugging, but it seems that ~ is getting stripped somewhere along the way. It would also be a bit helpful if the above error message mentioned the path which was not found.

In other parts of configuration (e.g. RTORRENT_RC) ~ works as expected.

I am also wondering whether local socket should be picked up automatically from .rtorrent.rc when SCGI_URL is unset. I have
network.scgi.open_local = ~/.config/rtorrent/socket
in there, but it doesn't seem being recognized as I am getting 'You need to configure a RPC connection'.

Command "d.last_xfer.is_active" does not exist

I am really enjoying pyrosimple, but I've come across this error in rtorrent:
Scheduled command failed: pyro_update_last_xfer: Command "d.last_xfer.is_active" does not exist

I've copy/pasted from the documentation page, so I don't think I should be getting this error?
https://kannibalox.github.io/pyrosimple/rtorrent-config/#timestamps

This is my entire .rtorrent.rc conf

# This is the rtorrent configuration file installed by rtinst script - https://github.com/arakasi72/rtinst
# This file is installed to ~/.rtorrent.rc
# Enable/modify the options as needed, uncomment the options you wish to enable.
# This configuration will work with most systems, but optimal settings are dependant on specific server setup

### Set Directories
method.insert = cfg.basedir,     private|const|string, (cat,"/home/CENSORED/rtorrent/")
method.insert = cfg.watch,       private|const|string, (cat,(cfg.basedir),"watch/")

#method.insert = cfg.logs,       private|const|string, (cat,(cfg.basedir),"log/")
#method.insert = cfg.logfile,    private|const|string, (cat,(cfg.logs),"rtorrent-",(system.time),".log")

session.path.set = (cat,(cfg.basedir),".session")
# directory.default.set = (cat,(cfg.basedir),"download")
directory.default.set = /home/CENSORED/rtorrent/download/ruTorrent_Downloads/

schedule2 = watch_directory,5,5,((load.start,(cat,(cfg.watch),"*.torrent")))

#system.umask.set = 0000

### BitTorrent
# Global upload and download rate in KiB, `0` for unlimited
throttle.global_down.max_rate.set = 0
throttle.global_up.max_rate.set = 0

# Maximum number of simultaneous downloads and uploads slots
throttle.max_downloads.global.set = 150
throttle.max_uploads.global.set = 300

# Maximum and minimum number of peers to connect to per torrent while downloading
throttle.min_peers.normal.set = 30
throttle.max_peers.normal.set = 150

# Same as above but for seeding completed torrents (seeds per torrent)
throttle.min_peers.seed.set = -1
throttle.max_peers.seed.set = -1

### Networking
network.port_range.set = 51132-51132
network.port_random.set = yes
dht.mode.set = disable
protocol.pex.set = no
trackers.use_udp.set = yes

# network.scgi.open_port = localhost:5000
network.scgi.open_port = 127.0.0.1:5000
network.http.ssl_verify_peer.set = 0
protocol.encryption.set = allow_incoming,enable_retry,prefer_plaintext

network.max_open_files.set = 4096
network.max_open_sockets.set = 1536
network.http.max_open.set = 48
network.send_buffer.size.set = 128M
network.receive_buffer.size.set = 4M

### Memory Settings
pieces.hash.on_completion.set = no
pieces.preload.type.set = 1
pieces.memory.max.set = 3500M

### Logging:
#   Levels = critical error warn notice info debug
#   Groups = connection_* dht_* peer_* rpc_* storage_* thread_* tracker_* torrent_*
#print = (cat,"Logging to ",(cfg.logfile))
#log.open_file = "log", (cfg.logfile)
#log.add_output = "info", "log"
#log.add_output = "tracker_debug", "log"


### The following line initialises rutorrent plugins without needing to open the web interface
execute2 = {sh,-c,/usr/bin/php /var/www/rutorrent/php/initplugins.php CENSORED &}

# This is for rtcontrol

# loaded
method.set_key = event.download.inserted_new, !time_stamp,\
    "d.custom.set=tm_loaded,$cat=$system.time= ; d.save_resume="

# started
method.insert = pyro._tm_started.now, simple|private,\
    "d.custom.set=tm_started,$cat=$system.time= ; d.save_resume="
method.set_key = event.download.resumed, !time_stamp,\
    "branch=d.custom=tm_started,false=,pyro._tm_started.now="

# completed
method.insert = pyro._tm_completed.now, simple|private,\
    "d.custom.set=tm_completed,$cat=$system.time= ; d.save_resume="
method.set_key = event.download.finished, !time_stamp,\
    "pyro._tm_completed.now="
method.set_key = event.download.hash_done, !time_stamp,\
    "branch=\"and={d.complete=,not=$d.custom=tm_completed}\", pyro._tm_completed.now="

# active - This section is *not* needed for variants that implement `d.timestamp.last_active` natively (i.e. jesec/rtorrent)
method.insert = d.timestamp.last_active, simple, "if=$d.peers_connected=,$cat=$system.time=,$d.custom=last_active"
method.insert = d.timestamp.last_active.update, simple|private,\
    "d.custom.set=last_active,$cat=$system.time= ; branch=argument.0=,d.save_resume="

schedule2 = pyro_update_last_active, 24, 42,\
    "d.multicall2=started,\"branch=$d.peers_connected=,d.timestamp.last_active.update=\""

method.set_key = event.download.resumed, !last_active,\
    "branch=\"or={d.peers_connected=,not=$d.custom=last_active}\", d.timestamp.last_active.update=1"
method.set_key = event.download.finished, !last_active, "d.timestamp.last_active.update=1"

# last_xfer
method.insert.value = pyro.last_xfer.min_rate, 5000
method.insert = pyro._last_xfer_check_min_rate, simple|private,\
    "greater=argument.0=,pyro.last_xfer.min_rate="
method.insert = pyro._last_xfer_update, simple|private,\
    "d.custom.set=last_xfer,$cat=$system.time= ; branch=argument.0=,d.save_resume="
schedule2 = pyro_update_last_xfer, 33, 17,\
    "d.multicall2=active,\"branch=$d.last_xfer.is_active=,pyro._last_xfer_update=\""

`chtor --fast-resume` prints error message when used with `-o`

chtor --fast-resume <data_dir> -o <out_dir> <metafile> prints the following error:

File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Program Files\Python311\Scripts\chtor.exe\__main__.py", line 7, in <module>
  File "C:\Program Files\Python311\site-packages\pyrosimple\scripts\chtor.py", line 464, in run
    MetafileChanger().run()
  File "C:\Program Files\Python311\site-packages\pyrosimple\scripts\base.py", line 178, in run
    self.mainloop()
  File "C:\Program Files\Python311\site-packages\pyrosimple\scripts\chtor.py", line 416, in mainloop
    filename = filename.replace(".torrent", "-no-resume.torrent")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Path.replace() takes 2 positional arguments but 3 were given

A modified torrent file is created in <out_dir> though.

BTW, when not using -o, is there a way to have *-resume.torrent instead of modifying the original metafile (as original chtor did)?

Unable to check version number

rtcontrol --version prints

rtcontrol unknown on Python 3.7.3

Other tools don't output version number too.

Versions checked:
pyrosimple-2.9.1, pyrosimple-2.10.0

handle scgi_url name option in watcher

I was getting an error on my end with the scgi_url job specific option.
I'm not sure if that is the root cause as I also have to pass the URL option for pyrotorque.
So the latter should have worked anyways.

The error happens at
Line 116
host, port = target.netloc.split(":")

It said that it only got one value from the command. I think it might be sending my url alias "media", and not the final url. Strangely I did not experience this when I was using the queue job yesterday.

The only way I can get it to work is if use the url alias, to retrive the proper final url. Before sending it off to the rpc command

Something like
self.proxy = rpc.RTorrentProxy(configuration.settings.connections.get(self.config["scgi_url"]) or self.config["scgi_url"] or configuration.settings.SCGI_URL)

Command "d.timestamp.last_active" does not exist.

First off, thank you so much for this port and all the work you've put into it, it really works super great! :)

I do apologize if this has been brought up before but I just couldn't find it in any of the corners of the internet.

The error
I get the following error when trying to use the filter "active" (e.g. rtcontrol -s active -/5 completed=+5d)

Traceback (most recent call last):
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/torrent/rtorrent.py", line 840, in items
    raw_items = multi_call(*tuple(multi_args))
  File "/usr/lib/python3.9/xmlrpc/client.py", line 1116, in __call__
    return self.__send(self.__name, args)
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 244, in __request
    return self.__request_switch(methodname, params)
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 265, in __request_switch
    raise exc
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 257, in __request_switch
    return self.__request_xml(methodname, params)
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 145, in __request_xml
    response = self.__transport.request(
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/io/scgi.py", line 141, in request
    return self.parse_response(io.BytesIO(response))
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/io/scgi.py", line 57, in parse_response
    return super().parse_response(response)
  File "/usr/lib/python3.9/xmlrpc/client.py", line 1348, in parse_response
    return u.close()
  File "/usr/lib/python3.9/xmlrpc/client.py", line 662, in close
    raise Fault(**self._stack[0])
xmlrpc.client.Fault: <Fault -503: 'Command "d.timestamp.last_active" does not exist.'>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/scripts/base.py", line 184, in run
    self.mainloop()
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/scripts/rtcontrol.py", line 739, in mainloop
    matches = futures[url].get()
  File "/usr/lib/python3.9/multiprocessing/pool.py", line 771, in get
    raise self._value
  File "/usr/lib/python3.9/multiprocessing/pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/scripts/rtcontrol.py", line 730, in fetch
    matches = list(e.items(view=view, prefetch=prefetch))
  File "/home/mrbamse/.local/lib/python3.9/site-packages/pyrosimple/torrent/rtorrent.py", line 864, in items
    raise error.EngineError(
pyrosimple.error.EngineError: While getting download items from RtorrentEngine connected to wireguard:1 [rTorrent 0.13.8/0.9.8, up 7h 11m] via 'scgi+unix:///home/mrbamse/rtorrent.sock': <Fault -503: 'Command "d.timestamp.last_active" does not exist.'>

Settings
And these are my settings from .rtorrent.rc (copied straight from https://kannibalox.github.io/pyrosimple/rtorrent-config/)

# active
method.insert = d.last_xfer.is_active, simple,"or={pyro._last_xfer_check_min_rate=$d.up.rate=,pyro._last_xfer_check_min_rate=$d.down.rate=}"
method.insert = d.timestamp.last_xfer, simple, "if=$d.last_xfer.is_active=,$cat=$system.time=,$d.custom=last_xfer"
schedule2 = pyro_update_last_xfer, 33, 17,"d.multicall2=active,\"branch=$d.last_xfer.is_active=,pyro._last_xfer_update=\""

# last_xfer
method.insert.value = pyro.last_xfer.min_rate, 5000
method.insert = pyro._last_xfer_check_min_rate, simple|private,"greater=argument.0=,pyro.last_xfer.min_rate="
method.insert = pyro._last_xfer_update, simple|private,"d.custom.set=last_xfer,$cat=$system.time= ; branch=argument.0=,d.save_resume="
schedule2 = pyro_update_last_xfer, 33, 17,"d.multicall2=active,\"branch=$d.last_xfer.is_active=,pyro._last_xfer_update=\""

Goal
I'm trying to setup a filter where the five completed items that were the opposite of last to do any transfers are listed.
Another option, preferably, would be a filter that lists every item that has not seeded for X days.

Conclusion

  • My guess is that d.timestamp.last_active just simply isn't set in .rtorrent.rc
  • I can't figure out why schedule2 = pyro_update_last_xfer, 33, 17,"d.multicall2=active,\"branch=$d.last_xfer.is_active=,pyro._last_xfer_update=\"" is mentioned twice.
  • Could it be that the filter "active" should be using d.timestamp.last_xfer instead?
  • Is there a separate config for d.timestamp.last_active that I'm missing?

Thank you so much, and again; great job! :)

rtcontrol -V error

Calling rtcontrol with the - V option fails with an error:

Traceback (most recent call last):
File "/home/rtorrent/.local/bin/rtcontrol", line 8, in
sys.exit(run())
^^^^^
File "/home/rtorrent/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/rtcontrol.py", line 1006, in run
RtorrentControl().run()
File "/home/rtorrent/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/base.py", line 177, in run
self.mainloop()
File "/home/rtorrent/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/rtcontrol.py", line 914, in mainloop
self.show_in_view(view, matches)
File "/home/rtorrent/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/scripts/rtcontrol.py", line 680, in show_in_view
targetname = self.engine.show(

AttributeError: 'NoneType' object has no attribute 'show'

Version 2.7.1 works. The two versions above don't work for me.

custom field problem

hi kannibalox,

first let me thank for your work on pyrosimple (and ptpuploader ;))

I installed this gem a few days ago and have some troubles with the custom_1 field:

rtorrent@host:~$ rtcontrol name=*Menu* -o name,d_custom1

The.Menu.2022.1080p.MA.WEB-DL.DDP5.1.Atmos.H.264-FLUX.mkv	radarr-imported

rtorrent@host:~$ rtcontrol name=*Menu* -o name,custom_1

The.Menu.2022.1080p.MA.WEB-DL.DDP5.1.Atmos.H.264-FLUX.mkv

same problem with filtering:

rtcontrol custom_1=radarr-imported-> does not work
rtcontrol d_custom1=radarr-imported -> works

rtorrent 0.9.8 / libtorrent 0.13.8
pyrosimple 2.5.1

any help to debug this would be appreciated.

Installation of pyrosimple doesn't include config.py

Hello,

I did a simple install of pyrosimple using pip which seems to go fine, but then when I run a debug of rtxmlrpc to see what I am doing wrong, I get the following message, where I am told the config.py is missing. Shouldn't the install just get the config.py and install it in place?

Thank you!

foo@asdfd:~$ rtxmlrpc --debug load.start '' 'Musical.torrent' "d.directory_base.set="$data_dir"" "d.priority.set=1"
DEBUG:pyrosimple.scripts.rtxmlrpc.RtorrentXmlRpc:Options: args=['', 'Musical.torrent', 'd.directory_base.set=""', 'd.priority.set=1'], as_import=False, log_level=10, method='load.start', output_format='pretty', print_completion=None, repl=False, session=False, url=None
DEBUG:pyrosimple.config:Configuration file '/home/foo/.config/pyrosimple/config.py' not found.
DEBUG:pyrosimple.config:Loading rtorrent config from '/home/foo/.rtorrent.rc'
DEBUG:pyrosimple.config:rtorrent.rc: network.scgi.open_local = /var/run/foo/.rtorrent.sock
DEBUG:pyrosimple.util.rpc:method 'load.start', params ('', 'Musical.torrent', 'd.directory_base.set=""', 'd.priority.set=1')
0
DEBUG:pyrosimple.scripts.rtxmlrpc.RtorrentXmlRpc:RPC stats: 1 requests (423 bytes) in 0.0s (response 140 bytes)
INFO:pyrosimple.scripts.rtxmlrpc.RtorrentXmlRpc:Total time: 0.008 seconds.

`fast_query` interferes with large date ranges

$ rtcontrol completed=+2w -o completed.delta,completed.raw -Q0 -/1
   3w  3d ago	1673535085
   3w  3d ago	1673534795
   5w  6d ago	1672056251
$ rtcontrol completed=+2w -o completed.delta,completed.raw -Q1 -/1 --debug
...snip...
DEBUG:pyrosimple.util.rpc:method 'd.multicall.filtered', params ('', 'default', 'greater=value=$d.custom=tm_completed,value=1674361222', 'd.custom=tm_completed', 'd.hash=', 'd.name=')

pyrotorque extend time symbols not support

I want to make sure I report these before I forget

The original pyrocore had extended time formats like 12H 2W,etc. Currently these do not work on pyrosimple, a work around is to just convert the desire time into seconds.

However these time formats are still present in some of the help outputs

kind_N field throws error when used

When using kind_N as a field, I get the below error:

  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/torrent/rtorrent.py", line 841, in items
    raw_items = multi_call(*tuple(multi_args))
  File "/usr/lib/python3.9/xmlrpc/client.py", line 1122, in __call__
    return self.__send(self.__name, args)
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 222, in __request
    return self.__request_switch(methodname, params)
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 243, in __request_switch
    raise exc
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 235, in __request_switch
    return self.__request_xml(methodname, params)
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/util/rpc.py", line 127, in __request_xml
    response = self.__transport.request(
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/io/scgi.py", line 140, in request
    return self.parse_response(io.BytesIO(response))
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/io/scgi.py", line 59, in parse_response
    return super().parse_response(response)
  File "/usr/lib/python3.9/xmlrpc/client.py", line 1354, in parse_response
    return u.close()
  File "/usr/lib/python3.9/xmlrpc/client.py", line 668, in close
    raise Fault(**self._stack[0])
xmlrpc.client.Fault: <Fault -503: 'Command "kind_95" does not exist.'>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/scripts/base.py", line 183, in run
    self.mainloop()
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/scripts/rtcontrol.py", line 715, in mainloop
    matches = futures[url].get()
  File "/usr/lib/python3.9/multiprocessing/pool.py", line 771, in get
    raise self._value
  File "/usr/lib/python3.9/multiprocessing/pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/scripts/rtcontrol.py", line 706, in fetch
    matches = list(e.items(view=view, prefetch=prefetch))
  File "/home/youser/.local/lib/python3.9/site-packages/pyrosimple/torrent/rtorrent.py", line 864, in items
    raise error.EngineError(
pyrosimple.error.EngineError: While getting download items from RtorrentEngine connected to rhea.whatbox.ca:10494 [rTorrent 0.13.8/0.9.8, up 31w  2d] via 'scgi+unix:///config/youser/rtorrent/socket': <Fault -503: 'Command "kind_95" does not exist.'>

I'm able to reproduce these results using this command: rtcontrol is_complete=yes -o custom_1,name,realpath,kind_95,hash,directory

--cull deletes file on disc with error and not in rtorrent

Hi,
I am running the following rtcontrol command:

/home/user/.local/bin/rtcontrol 'message=/(.*torrent not registered with this tracker.*|.*Unregistered torrent.*)/' --select 1 --cull --quiet --yes

rtcontrol then gives me this error message:

2023-07-04 13:51:56 cull         torrent_name_here [tag_here]
Traceback (most recent call last):
  File "/home/user/.local/bin/rtcontrol", line 8, in <module>
    sys.exit(run())
  File "/home/user/.local/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 973, in run
    RtorrentControl().run()
  File "/home/user/.local/lib/python3.10/site-packages/pyrosimple/scripts/base.py", line 177, in run
    self.mainloop()
  File "/home/user/.local/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 870, in mainloop
    getattr(item, action["method"])(*args)
  File "/home/user/.local/lib/python3.10/site-packages/pyrosimple/torrent/rtorrent.py", line 566, in cull
    directory.rmdir()
  File "/usr/lib/python3.10/pathlib.py", line 1215, in rmdir
    self._accessor.rmdir(self)
PermissionError: [Errno 13] Permission denied: '/home/user/rtorrent/download/rtorrent_sonarr2'

I tried giving permissions 777, but I still got the error.

I then discovered that the file on disk in the path '/home/user/rtorrent/download/rtorrent_sonarr2/torrent_to_be_deleted' actually did get deleted, but it just did not get deleted in rtorrent.

The user running the rtcontrol command is also the user running the rtorrent process and is the owner of all the paths.

I don't understand why I get the permissions denied error when it does have the permissions, and it also deleted the torrent_file in path, but not in rtorrent which is run by the same user.

I experienced this on v.2.8.0. I just updated to v.2.9.0 and still facing this issue.

`ZeroDivisionError` when hashing small files

I am getting ZeroDivisionError when checking hash of a small file (~700KB) on Windows. I suppose hashing_secs = time.time() - hashing_secs yields zero in my case.

lstor -c 'directory\datafile' 'directory\metafile':

100.0% [============================================================================>] 707.3 KiB/707 ETA [00:00]
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Program Files\Python311\Scripts\lstor.exe\__main__.py", line 7, in <module>
  File "C:\Program Files\Python311\Lib\site-packages\pyrosimple\scripts\lstor.py", line 179, in run
    MetafileLister().run()
  File "C:\Program Files\Python311\Lib\site-packages\pyrosimple\scripts\base.py", line 178, in run
    self.mainloop()
  File "C:\Program Files\Python311\Lib\site-packages\pyrosimple\scripts\lstor.py", line 106, in mainloop
    data_correct = torrent.hash_check(
                   ^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\site-packages\pyrosimple\util\metafile.py", line 668, in hash_check
    datameta, _ = self._make_info(
                  ^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\site-packages\pyrosimple\util\metafile.py", line 366, in _make_info
    fmt.human_size(totalhashed / hashing_secs).strip(),
                   ~~~~~~~~~~~~^~~~~~~~~~~~~~
ZeroDivisionError: float division by zero

Weirdly enough, the error is gone when double backslash is used in pathnames. My only guess is that path handling takes more time in this case.

Python 3.11.5
pyrosimple 2.11
PowerShell 7.3.6

pyroadmin can only create default config when directory exists

Executing pyroadmin --verbose config --create-config when the path doesn't exist exits with:

INFO:pyrosimple.scripts.pyroadmin.AdminTool:Creating pyrosimple config file '/home/flower/.config/pyrosimple/config.toml'
INFO:pyrosimple.scripts.pyroadmin.AdminTool:Total time: 0.009 seconds.
Traceback (most recent call last):
  File "/usr/lib/python-exec/python3.10/pyroadmin", line 8, in <module>
    sys.exit(run())
  File "/usr/lib/python3.10/site-packages/pyrosimple/scripts/pyroadmin.py", line 303, in run
    AdminTool().run()
  File "/usr/lib/python3.10/site-packages/pyrosimple/scripts/base.py", line 173, in run
    self.mainloop()
  File "/usr/lib/python3.10/site-packages/pyrosimple/scripts/pyroadmin.py", line 298, in mainloop
    self.args.func()
  File "/usr/lib/python3.10/site-packages/pyrosimple/scripts/pyroadmin.py", line 273, in config
    self.create_config()
  File "/usr/lib/python3.10/site-packages/pyrosimple/scripts/pyroadmin.py", line 248, in create_config
    with config_path.open("wb") as fh:
  File "/usr/lib/python3.10/pathlib.py", line 1119, in open
    return self._accessor.open(self, mode, buffering, encoding, errors,
FileNotFoundError: [Errno 2] No such file or directory: '/home/flower/.config/pyrosimple/config.toml'

Is this expected behaviour or should --create-config check if ~/.config/pyrosimple exists?

Checking hash when announce URL is missing

Hash checking has nothing to do with announce URL. Thus lstor -c should not terminate or print error messages if announce URL is not present in metafile.

Current behavior:

  • lstor -c – prints "ValueError: bad announce URL - not a string" and terminates with exit code 1
  • lstor -V -c – does the check and prints progress. Then prints "KeyError: 'announce'" and terminates with exit code 1

Expected behavior:

At least lstor -V -c should not print error messages and should exit with 0 in case hash check succeeded. As for lstor -c, IMO it should not print error about missing URL as well (although you might have different opinion). In any case, it should not terminate with 1, since the use case is hash checking, which succeeds.

last_xfer

Is their a replacement for last_xfer or will this feature not be included in this script?

'TimeFilter' object has no attribute 'not_null'

When I use last_xfer or active filter like:

rtcontrol active=-7d

I get the following error:

Traceback (most recent call last):
  File "/home/alex/tmp/pyro/.venv/bin/rtcontrol", line 8, in <module>
    sys.exit(run())
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 1051, in run
    RtorrentControl().run()
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/scripts/base.py", line 195, in run
    self.mainloop()
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 841, in mainloop
    matches = futures[url].get()
  File "/usr/lib/python3.10/multiprocessing/pool.py", line 774, in get
    raise self._value
  File "/usr/lib/python3.10/multiprocessing/pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/scripts/rtcontrol.py", line 832, in fetch
    matches = list(e.items(view=view, prefetch=prefetch))
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/torrent/rtorrent.py", line 890, in items
    if view.matcher.match(ritem):
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/util/matching.py", line 190, in match
    return any(c.match(item) for c in self.children)
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/util/matching.py", line 190, in <genexpr>
    return any(c.match(item) for c in self.children)
  File "/home/alex/tmp/pyro/.venv/lib/python3.10/site-packages/pyrosimple/util/matching.py", line 488, in match
    if self.not_null and self._value and not val:
AttributeError: 'TimeFilter' object has no attribute 'not_null'

Seem like a coding error, the validate function is not called before to define the attribute.

`lstor` can't provide human-readable output when metafile has no announce URL

When a torrent is added via magnet link, upon metadata retrieval rtorrent creates corresponding torrent file. It has info.files section only and, naturally, no announce key. Making lstor work with a metafile like this requires -o and -V flags to work around "bad announce URL" error.

The problem with this workaround is that you can't have nice human-readable output when -o is used. Normally, it would print torrent files in the FILE LISTING section. In contrast, -o info.files, prints raw array literal ([{'length': ..., 'path': ['...', '...']}]). There seems no supported syntax to get access to array elements and their members. One would need to parse the output.

Another scenario is obtaining human-readable info about a torrent without announce URL. Not possible.

Pyrotorque

It seems some changes have been made to pyrotorque and are not documented yet

  1. The handler is now handler = "pyrocore.job.queue:QueueManager" not handler = "pyrocore.torrent.watch:QueueManager"
  2. I had startable but the syntax seems to be matcher now
  3. I had to comment out this line
    # if not self.__handler and parsed_url.scheme in ("http", "https"): # self.__handler = "/RPC2" # self.__url += "/RPC2"

I a little confused about what is going on print out the variables gets media, media
media is the name of my connection.
Anyways my path is not /rpc2 so the command was failing for me

edit: I figure it out it was the way I was trying to debug.
It's called more then once, and I was quitting on the first run, When handler is not set.

Q: I got it working now, but is their any way to disable the path /rpc2?

'pyro._activations.append' does not exist

hi kannibalox,

Thank you for your work on pyrosimple, I use it on all of my seedboxes!

When trying to stop/cull torrents exceeding x seedtime, rtcontrol is_complete=yes seedtime=+72h --stop --yes or rtcontrol is_complete=yes 'seedtime>72h' --stop --yesI get this error message. UserWarning: Method 'pyro._activations.append' does not exist! I have added the relevant lines from the sample rtorrent.rc file, but the error remains.

# EVENTS: Activation intervals
method.insert = pyro._activations.append, simple|private,\   
    "d.custom.set=activations,\"$cat=$d.custom=activations,$argument.0=,$system.time=\" ; d.save_resume="
method.set_key = event.download.paused, !activations, "pyro._activations.append=P"
method.set_key = event.download.resumed, !activations, "pyro._activations.append=R"

Full error message:

/home/jonnyboy/.local/pipx/venvs/pyrosimple/lib/python3.11/site-packages/pyrosimple/torrent/engine.py:728: UserWarning: Method 'pyro._activations.append' does not exist! See https://github.com/kannibalox/pyrosimple/blob/main/src/pyrosimple/data/full-example.rc#L157-L161 for an example of a configuration for using activations
  warnings.warn(

Is there something else I need to add to the config file or am I running the command wrong?

Thanks

Missing fields

Hi,
I just installed Pyrosimple and super easy setup! Very happy you guys have made this project!
I installed it to get rtcontrol.
I have setup Aliases in the config, and this works on new torrents.

But what about all my existing torrents? If I select the tracker field with rtcontrol I can see the tracker on existing torrents. But how do I set the appropriate alias on existing torrents?

The way I see it, I need to run through all the torrents, read the tracker, load the config to read the appropriate alias, and then set the alias. But I don't know how to do this :(

EDIT
Same with the completed field. I don't have any info here either for existing torrents.

Multiple `OR` conditionals don't match any items

First noticed in #36, e.g. alias=TEST1 OR alias=TEST2 OR alias=TEST3. Regexes are a valid workaround when all the fields are the same, but that wouldn't work for something like xfer=+0 OR alias=TEST1 OR message=""

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.