470 Commits

Author SHA1 Message Date
mnightingale
babd8517e9 Database SQLite storage for RSS feeds (#3253)
* Store RSS in database

* Use context manager for rss repository in most instances

* Combine _evaluate_entry and _process_entry
2026-06-07 08:43:14 +02:00
Safihre
0950393b82 Correctly format tests based on new rules and remove star imports 2026-06-05 14:34:17 +02:00
mnightingale
ca5e02f2f1 Sanitise host_whitelist and login/request public IP addresses (#3437)
* Sanitise host_whitelist and login/request IP addresses

* Keep json keys

* Remove all IPv4 and IPv6 from logs

* Less crazy remote label replacements

* Remove unused import

* Sanitise public ipv4/ipv6 and test

* Add loopback/link-local test cases

* Switch is_local_addr to is_lan_addr because the former allows user configuration of trusted addresses

* Remove prefix group, ip regex should be good enough
2026-06-04 11:06:07 +02:00
renovate[bot]
dc870495c5 Update all dependencies (#3448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-04 11:05:39 +02:00
VisorCraft
a6491750f7 Fix false "not writable" warning from non-atomic writability self-test (#3446)
directory_is_writable_with_file() removed its fixed-name temp file in a
non-atomic exists/remove/open/remove sequence wrapped in a blanket
"except Exception: return False". If the test file was removed between the
write and the final os.remove (e.g. by a concurrent writability check), the
FileNotFoundError was swallowed and reported as "is not writable at all.
This blocks downloads." -- a false negative on a fully writable folder.

Make the result depend only on creating and writing the file; treat cleanup
as best-effort. Genuine write failures still return False, and the unicode
and special-character capability checks are unchanged.

Adds regression tests for the cleanup race and for a genuine write failure.
2026-06-04 10:50:45 +02:00
mnightingale
7f421a3c0b Add logging of unhandled connection exceptions and wait_for result (#3440) 2026-05-26 16:54:19 +02:00
mnightingale
2c530fee47 Remove disableDelays because config is not defined (#3438) 2026-05-26 06:50:24 +02:00
Ryan Hollister
25d20f0f08 Fix RuntimeError: dictionary changed size during iteration in stop_idle_jobs (#3432)
* Fix RuntimeError from dict mutation in stop_idle_jobs (#3431)

Collecting exhausted articles into a snapshot list while holding
nzf.lock, then calling register_article outside the iteration.
This prevents RuntimeError when register_article -> nzf.remove_article
pops from nzf.articles (a dict) while stop_idle_jobs is iterating it.

The original code in fd3ece31c used `nzf.articles[:]` which was safe
when articles was a list. When 44d94226e changed articles to a dict
the protective copy was dropped, leaving bare dict iteration that
mutates mid-loop.

The collect-then-act pattern matches nzf_remove_list in nzb/object.py
and the empty-nzo list already used in stop_idle_jobs itself. It also
correctly calls register_article outside nzf.lock, consistent with its
own "not locked for performance" contract.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Apply Black formatting to nzbqueue.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Soften comment per maintainer feedback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:33:14 +02:00
mnightingale
fec57377db Fix warnings when retrying jobs that have missing renamed files and fix the causes (#3428) 2026-05-23 18:59:44 +02:00
mnightingale
2f4750f77d Match previous RSS parsing behaviour (#3425)
* Match to previous RSS behaviour

* Cleanup logic due to normalisation

* Tests comparing 4.5.5 outcome

* Remove comment - fixed since 4.5.5

* Consistent types for prio, rule, season, and episode

* Rename matching_rule_index

* Fix type warnings
2026-05-22 22:34:30 +02:00
renovate[bot]
196a92550c Update all dependencies (#3422)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-18 09:12:28 +02:00
mnightingale
d7ca91e395 Try to clean the cache dir multiple times (#3419) 2026-05-16 22:43:07 +02:00
mnightingale
10ffcb2c82 Check SAB_CACHE_DIR exists first and allow to already exist (#3415) 2026-05-15 14:43:29 +02:00
mnightingale
1564ee3ccf Remove unreliable test (#3416) 2026-05-15 14:42:30 +02:00
Safihre
290f85ca1c Extend Cleanup List with filename and path pattern matching (#3413)
* Extend Cleanup List with filename and path pattern matching

Previously limited to cleaning up files based only on their extensions, the 'Cleanup List' now supports more flexible matching. Users can specify:
- Exact filenames (e.g., `Thumbs.db`)
- Wildcard filename patterns (e.g., `*.tmp`, `cleanup.*`)
- Relative path patterns (e.g., `images/*`, `*/test.jpg`)

This enhancement provides greater control and flexibility for automated post-processing cleanup.
2026-05-15 09:38:22 +02:00
mnightingale
2184964d78 Reduce time to test (#3412)
* Remove UI delays

* Everything using set_config, set_platform, or pyfakefs

* tmp_path

* Scroll to top seems unnecessary but make it wait until it's done

* Remove sleep from test_rss_basic_flow

* Remove sleeps from test_daemonizing

* Define pytest markers

* Reduce sleep in test_queue_repair

* Remove sleeps from clean_cache_dir

* Suppress failures to connect during startup

* Reduce cache sleeps

* Reduce sleeps checking app started

* Reduce sleep removing cache dir
2026-05-13 18:49:41 +02:00
Safihre
8be8af018f Refactor RSS processing for clarity and option precedence
Refactor RSS feed processing logic to enhance clarity and ensure correct precedence for resolved options. Renames functions and variables for better understanding, and inlines feed configuration logic. Adds new tests to verify how category, post-processing, script, and priority settings are applied hierarchically. Also provides a default display for empty RSS log categories.
2026-05-11 15:45:24 +02:00
mnightingale
ee3cd747b9 Use UUID4 for nzo_id and rekey existing duplicates (#3395)
* Replace duplicate nzo_ids in history database and use uuid4

* Remove SABnzbd_nzo on reuse

* Keep SABnzbd_nzo_ prefix for future jobs

* Try loading from multiple normal and future paths

* Purege NZO_FILE

* Rename NZO_FILE

* Allow failed migration to rollback
2026-05-05 10:39:49 +02:00
Safihre
98dc183881 Add test for 3.0.0 legacy queue format restoration
Moved sys.modules call higher, so it is always applied
2026-05-04 17:04:03 +02:00
Safihre
c6d3b1ebf3 Tavern issue fixed 2026-04-10 10:21:34 +02:00
renovate[bot]
a0feeb66c1 Update all dependencies (#3371)
* Update all dependencies

* Restore compatibility

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Safihre <safihre@sabnzbd.org>
2026-04-07 07:10:25 +00:00
Safihre
f60da12ae6 Skip extract_pot tests on Python 3.9 2026-03-31 14:47:41 +02:00
Safihre
1c6e5e0deb Generalize (most) filenames to NFC form
Closes #2858, #1633
But might not be enough. We will see.
2026-03-23 22:50:40 +01:00
Safihre
9b2c9621a9 Generalize diskspace check arguments 2026-03-23 11:41:30 +01:00
mnightingale
baa52e4acf Perform diskspace check on complete directory for nzo (#3346)
* Perform diskspace check on complete directory for nzo

* Always check complete_dir even if complete_free is 0

* Slots require 3.10

* Fix direct unpack calculation

* Schedule resume against download_dir, complete_dir, or an arbitrary path

* Document params

* Replace Diskspace with returning a tuple

* Fix the broken things

* Add diskspace tests
2026-03-23 09:01:24 +01:00
Safihre
47db831b17 Correct availability check for case of all missing par2 2026-03-09 16:27:22 +01:00
mnightingale
7f8d7d80d2 Make conditional_cache exception safe and exclude force from the key (#3317) 2026-02-09 21:27:15 +01:00
Safihre
2122503762 Update copyright to 2026 2026-02-09 16:44:38 +01:00
mnightingale
47e71912d5 Ignore all OSError from FakeNNTPServer (#3309) 2026-02-06 18:18:18 +01:00
mnightingale
16a6936053 Bind socket throughout test but don't listen and configure a timeout (#3296) 2026-01-29 12:07:27 +01:00
mnightingale
d9f9aa5bea Fix adding sockets mid-connect (#3291)
* Do not add sockets that are not already connected

* Don't preemptively mark thread busy

* Clear nntp instance on failed connect

* Just use reset_nw like everywhere else

* Track when the socket is connected and idle connections can handle requested when connected (completed auth) or socket_connected

* Add tests for connection state handling

* Windows is really slow at this

* Rename connected to ready and socket_connected to connected
2026-01-26 19:06:22 +01:00
mnightingale
46c98acff3 Fix inconsistent NzbFile sorting (#3276)
* Fix inconsistent NzbFile sorting

* Add more groups and tiers

* Black formatting
2026-01-20 11:06:02 +01:00
Safihre
3384beed24 Make black 26.1.0 happy again - almost 2026-01-19 12:42:51 +01:00
mnightingale
3e7dcce365 Fix queue cannot be loaded (#3271)
* Fix queue cannot be restored

* Also change init

* Add a test

Fixes #3269
2026-01-12 09:54:59 +01:00
mnightingale
df1c0915d0 Recreate frènch_german_demö test data (#3268) 2026-01-09 10:59:51 +01:00
Safihre
17dcff49b2 Generalize locking strategy (#3264)
* Use per-nzo/nzf lock in wrapper

* Replace global TryList lock with per-nzo one

* Offset does require file_lock
2026-01-06 17:00:27 +01:00
mnightingale
b4e8c80bc9 Implement Direct Write (#3236)
* Implement direct write

* Support direct_write changes at runtime

* Check sparse support when download_dir changes

* Fixes to reverting to append mode and add tests

* Single write path, remove truncate, improve tests, add test for append mode with out of order direct writes

* assert expected nzf.assembler_next_index

* bytes_written_sequentially assertions

* Slim tests and mock load_article as a dictionary

* More robust bytes_written_sequentially

* Worked but guard Python -1 semantics

* os.path.getsize silly

* Add test with force followed by append to gaps

* Split flush_cache into its own function so the loop does not need to clear the article variable

* Fewer private functions

* Extract article cache limit for waiting constant

* Move option back to specials

* Use Status.DELETED for clarity

* Use nzo.lock in articlecache

* Document why assembler_next_index increments

* Remove duplicated code from write

* load_data formatting

* Create files with the same permissions as with open(...)

* Options are callable

* Fix crash if direct writing from cache but has been deleted

* Fix crash in next_index check via article cache

* Fix assembler waiting for register_article and cache waiting for assembler to write

* Simplify flush_cache loop and only log once per second

* Document why we would leave the assembler when forced at the first not tried article

* When skippedwe can't increment the next_index

* Rename bytes_written_sequentially to sequential_offset improve comments and logic

* Don't need to check when the config changes, due to the runtime changes any failure during assembly will disable it

* Remove unused constant

* Improve append triggering based on contiguous bytes ready to write to file and add a trigger to direct write

* Throttle downloader threads when direct writing out of order

* Clear ready_bytes when removed from queue

* Rework check_assembler_levels sleeping to have a deadline, be based on if the assembler actual pending bytes, and if delaying could have any impact

* Always write first articles if filenames are checked

* Rename force to allow_non_contiguous so it is clearer what it means

* Article is required

* Tweak delay triggers

* Fix for possible dictionary changed size during iteration

* postproc only gets the nzo

* Rename constants and remove redundant calculation

* For safety just key by nzf_id

* Not redundant because capped at 500M

* Tweak a little more

* Only delay if assembler is busy

* Remove unused constant and rename the remaining one

* Calculate if direct write is allowed when cache limit changes

* Allow direct writes to bypass trigger

* Avoid race to requeue

* Breakup the queuing logic so its understandable
2026-01-06 10:03:00 +01:00
mnightingale
9d5cf9fc5b Fix binding outgoing ip test when ipv6 is available (#3257) 2026-01-02 15:53:48 +01:00
mnightingale
240d5b4ff7 Fix failing downloader tests and make tests less fragile (#3254)
* Fix failing downloader tests and make tests less fragile

* Implement feedback

* Spelling and only sleep if necessary

* Grammar is hard
2026-01-02 15:02:34 +01:00
mnightingale
b6691003db Refactor RSS flow (#3247) 2025-12-30 09:23:20 +01:00
mnightingale
62401cba27 Simplify RSS rule evaluation (#3243) 2025-12-29 10:50:55 +01:00
renovate[bot]
239fddf39c Update all dependencies (develop) (#3238)
* Update all dependencies

* Compare fakefs result after sorting

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Safihre <safihre@sabnzbd.org>
2025-12-22 12:45:00 +00:00
Safihre
a91e718ef5 Split nzbstuff into separate files for Article, NzbFile and NzbObject (#3221) 2025-12-09 21:21:51 +01:00
Safihre
05cbd9d7c4 Correct process_nzb_only_download and add tests 2025-12-08 11:42:22 +01:00
mnightingale
44d94226ec Pipelining and performance optimisations (#3199)
* Pipelining and performance optimisations

* Refactor to remove handle_remainder and add on_response callback to allow inspecting of nntp messages

* Logic fix if there are sockets but nothing to read/write

* Fix logic errors for failed article requests

* Fix logic for reconfiguring servers

* Add guard_restart callback to pipelining_requests

* Fix article download stats

* Fix current article request shown via api

* Removal of DecodingStatus

* Fix circular reference

* Cleanup imports

* Handle reset_nw and hard_reset for inflight requests

* Improve __request_article behaviour using discard helper

* Article should be None here (before auth) but just in case

* Remove command_queue_condition unnecessary with the pull rather than push queue system

* During reset discard any data received prior to sending quit request

* Circular references again

* Revert to using bytearray

* Revert "During reset discard any data received prior to sending quit request"

This reverts commit ed522e3e80.

* Simpler interaction with sabctools

* Temporarily use the sabctools streaming decoder branch

* Fix most uu tests

* Reduce maximum pipelining requests

* Fix the squiggly line

* Remove some LOG_ALL debug code

* Make get_articles return consistent (None) - it now populates the server deque

* Reduce NNTP_BUFFER_SIZE

* Rename PIPELINING_REQUESTS to DEF_PIPELINING_REQUESTS

* A little refactoring

* Reduce default pipelining until it is dynamic

* Use BoundedSemaphore and fix the unacquired release

* Use crc from sabctools for uu and make filename logic consistent wit yenc

* Use sabctools 9.0.0

* Fix Check Before Download

* Move lock to NzbFile

* Use sabctools 9.1.0

* Minor change

* Fix 430 on check before download

* Update sabnews to work reliably with pipelining

* Minor tidy up

* Why does only Linux complain about this

* Leave this as it was

* Remove unused import

* Compare enum by identity

* Remove command_queue and just prepare a single request
Check if it should be sent and discard when paused

* Kick-start idle connections

* Modify events sockets are monitored for
2025-12-05 13:33:35 +01:00
Safihre
27e164763e Remove unused imports and shorten build timeouts 2025-11-21 11:29:53 +01:00
Safihre
67a5a552fd Add missing typing hints to several files 2025-11-21 10:00:10 +01:00
Safihre
80f57a2b9a Drop support for Python 3.8 2025-11-21 10:00:09 +01:00
renovate[bot]
1ba479398c Update all dependencies (develop) (#3195)
* Update all dependencies

* Pin tavern due to failure in newer versions

* User SABnzbd User-agent in wiki test

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Safihre <safihre@sabnzbd.org>
2025-11-18 13:30:07 +01:00
renovate[bot]
6983058f49 Update all dependencies (#3165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 01:09:52 +00:00