nzbperl
nzb based nntp/usenet downloader in perl
last updated Nov 25th, 2006
overview | features | download | requirements | usage | screenshots | faq | todo list | email list | license
Latest News / Announcements
(changelog)
Novermber 25th, 2006 - Still kicking. Just wanted to let people know that although there hasn't been a release in the better part of a year now, I still consider this project active. I've been silently banging away on the 0.7.x version and hope to have a source repository available in the near future.
December 31st, 2005: Version 0.6.8 released today.
Sneaking out the new version before the turn of the year. This will be the last release in the 0.6.x series, and it now supports disk free space checking and several important bug fixes. As usual, the changelog has gory details, and the summary is:
- New commandline option: --diskfree (used to set threshhold for disk free space checking)
- New remote control command: diskfree (used to change diskfree param)
- Several useful bug fixes.
The next release will be in the 0.7.x series and will be geared at allowing connections to work on the same file (smaller units of parallelization).
November 14th, 2005: Version 0.6.7 released today.
Major changes:
- New commandline option: --ifilter (to do inverse filtering)
- New option: --decodelog (so users can specify a debug log location)
- New option: --dthreadct (to control number of decoder threads)
- "speed" remote control command
- nzbperl now takes up entire terminal space
- --nothread option gone and combined with --dthreadct option (use --dthreadct 0 for single threaded operation)
- Many assorted important bug fixes
There are some important bug fixes, so upgrade is recommended!
October 16th, 2005: Email group/list now active.
Thanks to google, nzbperl now has an email list. To subscribe, send a message to nzbperl-subscribe@googlegroups.com. The group should now be used for most nzbperl related discussions, bug reports, questions, feature requests, etc.
September 11th, 2005: another broken release. :)
The 0.6.6 version released earlier today had a silly bug. If you downloaded it earlier today and see a problem about --queuedir requiring an ABSOLUTE path, please re-download. It should be fixed now. Sorry for the hassle.
September 11th, 2005: Version 0.6.6 released today.
The major improvements/changes are:
- Fix to the --nothread option that prevented it from working properly. It should be possible to run nzbperl now without a threaded version of perl. Please report back success/failure stories, as I don't have a nonthread version.
- Added the --forever option to prevent nzbperl from ever exiting (requires --queuedir to also be provided). This is primarily for users that wish to run nzbperl as a pure daemon that always runs and monitors a directory for new nzb files.
- Added --postnzb option to allow nzbperl to run an external program after the last file in an nzb file is decoded. This option should help facilitate 3rd party add-ons that do various things (like file joining/unpacking/moving/whatever). Please report back success/failure stories if you use this option.
- Added the --chunksize option to allow users to modify the internal recv byte count. This is really only for true tweakers, most users won't need it.
- Continued bug fixes and improvements mentioned in the changelog.
Aug 9th, 2005: Once again, I released a broken version. 0.6.5 had a problem with --config not working, but I've changed it in place...so please re-download 0.6.5 to get the fix. I suppose it's a typical situation where a program's complexity reaches a certain point and the developer can't test it all. So...if anybody wants to write a suite of unit tests, it sure would be nice. :)
{there are older announcements, but I haven't built a nice way to view them yet}
Overview
Run Linux (or OSX or Windows)? Need a multi-connection newsreader utility that can process an nzb file and autodecode and even do bandwidth throttling? You've come to the right place. :)
I looked around for something that I could use for nzb files on my Linux setup, and I soon discovered limited options. There are progs out there that will download nzb files (nzbget and knzb are apparently the most visible ones), but none seemed to have a key feature that I put importance on: bandwidth throttling. So, like many other one-off hacks and open source projects, this little toy was built to scratch an itch.
Features
- Automated parsing and sorting of nzb files
- Supports multiple server connections
- Automated parts downloading, assembling, and decoding
- Decodes uuencoded and yenc encoded files (via uudeview)
- User controllable bandwidth throttling (even change speeds during runtime)
- Nice colored text display with progress information
- News server authentication (optional)
- Perl script requires no compilation.
- Few dependencies
- Small footprint (about an 84kB download)
This has currently been tested and confirmed working with Debian, SuSE, RedHat, NetBSD, OSX, and Windows (via Cygwin). There's no obvious reason this shouldn't work with other platforms or distros. Feel free to send me your success or failure stories.
Download
- nzbperl.pl - Version 0.6.8 (97kB) (Recommended) -- Released Dec 31st, 2005
- ...or view the changelog.
- sample nzbperlrc configuration file
- nzbperl-0.6.7.pl - Version 0.6.7 (93kB) (OLD version) -- Released Nov 14th, 2005
- nzbperl-0.6.6.pl - Version 0.6.6 (90kB) (OLD version) -- Released Sep 11th, 2005
- nzbperl-0.6.5.pl - Version 0.6.5 (84kB) (OLD version) -- Released Aug 7th, 2005
- nzbperl-0.6.4.pl - Version 0.6.4 (70kB) (OLD version) -- Released Jun 20th, 2005
- nzbperl.pl - Version 0.6.3 (57kB) (OLD version) -- Released Apr 17th, 2005
- nzbperl.pl - Version 0.6.2 (51kB) (OLD version) -- Released Mar 20th, 2005
- nzbperl-0.6.1.pl - Version 0.6.1 (44kB) (OLD version) -- Released Jan 27rd, 2005
- nzbperl-0.6.pl - Version 0.6 (44kB) (OLD VERSION) -- Released Jan 23rd, 2005
not recommended
- nzbperl-0.5.pl - Version 0.5 (34kB) (OLD version) -- Released Jan 3rd, 2005
- nzbperl-0.03.pl -(OLD Version 0.03) (17kB) -- Released Nov 6th, 2004
Requirements / Dependencies
UUDeview - great program, used by nzbperl to do file decoding.
Perl (version likely flexible), and the following modules:
use IO::Socket::INET;
use File::Basename;
use XML::DOM;
use Getopt::Long;
use Time::HiRes;
use Term::ReadKey;
use Term::Cap;
use Cwd;
-------- optional modules --------
use threads; (only if you want threaded decoding)
use Thread::Queue; (only if you want threaded decoding)
use Term::ANSIColor; (only if you want color)
use XML::Simple; (only if you want remote control functions)
use IO::Socket::SSL; (only if you want SSL)
use IO::Socket::Socks; (only if you want to use SOCKS proxy)
use Net::HTTPTunnel; (only if you want to use an HTTP tunnel)
use IO::Socket::INET6; (only if you want IPv6 support)
On most systems, installing Perl modules from CPAN is a snap (as root):
$ perl -MCPAN -e "install XML::DOM"
(as an example)
See the CPAN faq for more information.
If you get a "Malformed UTF-8 character" crash on a Redhat/Fedora system, you may need to preface nzbperl commandline startup with a "LANG=C" like:
LANG=C perl nzbperl.pl
Usage
For now, you just get the --help summary...although most things are pretty self explanatory. Detailed explanations may or may not appear here in the future.
nzbperl version 0.6.8
nzbperl <options> <file1.nzb> ... <file.nzb>
where <options> are:
: Port can also be specified with
: May be combined with
: use a proxy server with SSL.
: port 1080, but can use
: use an alternative port.
: to port 8080, but can use
: use an alternative port.
: and leave the parts files on disk still encoded.
: (default downloads to current dirctory)
: (default downloads to current directory)
threaded perl operation. (Note: When ct = 0, downloads
will be paused during file decoding)
: Default = 5k, Can specify in bytes or kb (ie. 5120 or 5k)
During runtime, press 'h' or '?' to see a list of key commands.
If all goes well, you'll see the main screen. You can press 'h' or '?' during normal operation to view the help screen which shows available key commands.
Screenshots
8 connections maxed out
3 connections throtteld down to 25kBps
the help screen
Running in Windows under Cygwin
snap of 80-col text console
User Submitted Screenshots
10 connections at 9.3 megabytes per second!
Nice looking KDE konsole
Running on OSX Tiger
Running on OSX 10.4.1 for x86
TODO list
There's always room for improvement. The following is a list of things I may or may not get around to thinking about implementing. Items that have been implemented have been given strikethru and moved lower on the list.
- Add option (--badNZB or similar) that can call a script when a "bad" NZB is hit (see google groups thread from beheerder@gmail.com).
- Ensure that GROUP is issued for servers that require it (how did this get dropped?). Maybe make this an option to disable, and maybe have connections track their current group and only issue it when required (ie. hit new file that only exists in groups outside where we are).
- Quote/unescape $path when doing df for free space checks
- Fix "freezing bug" when number of connections goes over screen height ($statuslimit goes negative). See "thegeek" messages in email list.
- Fix bug that causes --postnzb script to be called even when there are files from the nzb still being downloaded. Caused by "last" smaller/faster file finishing before a bigger/slower one.
- DTD validation (http://www.newzbin.com/DTD/nzb/nzb-1.0.dtd), enable by default(?), option to override.
- Create "contrib" section for helpful add-ons that people are submitting (ie. repairDir.pl and others)
- Auth security (and/or ssl?) for the remote control socket to prevent unwanted baddies.
Would changing the socket to a fifo help for security or just make things more difficult?
I think HTTP::Daemon::SSL is perhaps the best way to handle security for this?
Perhaps this blows up into a mini web UI?
- 'n' (?) key to switch to screen that allows files to be reordered.
- Color themes. Probably pretty easy to do, but completely unnecessary. ;)
- Look into reducing memory usage (undef to no longer needed items)
- Each connection should download a part-at-a-time instead of file-at-a-time. This is a pretty huge change and will be tricky in places, but it's worth doing.
- Idle connections should help other connections...especially after multiple servers are supported.
- Pause key (p?) to stop all downloads, close all connections, and wait for an unpause event before continuing (via reconnect).
- Nice little apt-get -able Debian packages. How to do Perl module deps?
- Build in a way to prevent auto retry/reconnect logic (--retrywait=0 maybe)
- Dump missing parts and/or broken files into an output nzb file for later use (like against another server)
- After decoding a known-broken file and --keepbrokenbin is enabled, rename the binary to show that it's broken (ie. append .broken to filename)
- Fetch head first to check article existence before fetching body?
- Once that happens, what about verifying/changing the size from the nzb?
Perhaps tricky, but worth doing? Have to adjust all sizes...
- Timeouts on each connection -- if data not seen in N seconds (minutes), reconnect.
- Finish downloading any parts in progress and cleanly close server connection with QUIT command when user hits 'q' (Default behavior)
- Implement 'Q' key (capital Q) to force a less graceful but more timely shutdown.
- Promote the DECODE_DBG_FILE (decoding debug file) into a commandline option. When given, remove the silent option to uudeview.
- Command line option to sort by reverse date (oldest parts first)
- Fix bug related to fetch fail from server (response = (400 xxxx.xxxxx.xxxxxxxxxxx.com: Session timeout.))
- Consider putting tempfile (.parts files) in /tmp or other customize location
- Support for multiple servers, with priority levels.
- Support for remote control bandwidth throttling (via cron) -- not sure yet how to do this, but consider it.
- Keystrokes to dynamically add or subtract connections. Also more complicated with multiple servers, but valuable nontheless.
- Implement 's'kip key command (to skip current file...hard with multiple connections)
- Consider using DBI (SQLite/MySQL/?) for queueing. This could really make things pretty simple and could likely give MUCH better control over things (queueing, ordering, expiring, filtering, whatever). Downside: additional dependency.
- [ Your reasonable feature here ] :)
- ...show old/completed todo entries...
Older:
- Somebody also recommended a keystroke (a?) to add additional nzb files at runtime. I don't really think I like this idea, but I'm jotting it down for later consideration.
The --queuedir should really be used instead
- --ifilter (inverse filter) option to explicitly exclude items in the nzb file.
Included in version 0.6.7
- Fix bug when the first segment in a file is numbered starting at zero. Presently, this causes a negative index value.
Fixed in version 0.6.7
- Commandline option for use with --queuedir to prevent nzbperl from ever exiting. If this option is used, nzbperl will just hang around monitoring the queue...FOREVER.
Included in 0.6.6 via --forever option
- Commandline option to run a program after each nzb file is completed.
Included in 0.6.6 via --postnzb option
- Option to run external program (perhaps with environment vars or something?) after each nzb file is downloaded. (not the same as --postdec). Helps facilitate the creation of 3rd party add ons (such as email notification or par2 repairs that users have asked for)
Included in 0.6.6 via --postnzb option
- Ensure that nzb file parts are sorted when a new nzb file is popped off the nzb file queue.
Included in 0.6.6
- Promote $recv_chunksize to a commandline/config option for people that want to tweak it.
Included in 0.6.6 via --chunksize option
- Remote control via socket and/or fifo. Should be able to send all keys to the app, but also handle additional commands (like status report). Primarily targeted at additional automation (--daemon) and other UIs that peeps may want to build.
Included in 0.6.5 via --rcport
- Options to run external program (perhaps with environment vars or something?) after each binary file is decoded? This could help facilitate the creation of 3rd party add ons (such as email notification or par2 repairs that users have asked for), but is different from running a program after each nzb is finished.
Implemented in 0.6.5 via --postdec option
- Fix 530 time out issue as reported by Sergio (recreated by suspending until server closes socket)
Fixed in 0.6.5
- Add option to create dload dirs (similar to --dlcreate) based on the first group name for the file.
Included in 0.6.5 via dlcreategrp option
- More usable/human-readable error messages for invalid XML parsing (eval it?)
Fixed/improved in 0.6.5
- Better error handling/messages when nzb xml parsing fails.
Fixed/improved in 0.6.5
- Build option to disable threading and run decoding "inline". Mostly of use to people who don't have threading support compiled into Perl, but overall just A Good Idea.
Included in 0.6.5 via the --nothread option
- CPU goes to 100% usage when bandwidth expired and all connections waiting to reconnect? Fixme.
Fixed on 0.6.5
- Regex on nzb filename(?) to autogenerate subdirectory name (-p to uudeview)
Version 0.6.4 does this via --dlcreate
- Basic daemon (non display) mode. Still use the log file (showing statmsgs), but prevent all output for those that want to run with a nohup or as a daemon.
Version 0.6.3 supports --daemon
- Support for multiple NZB files per run (refer to Omen's recommended approach)
Version 0.6.3 supports multiple nzb files per run
- Newer version available checking, thru a url, on by default, but user can disable through a commandline/config option. How to do this without introducing a module dependency? Do I dare just code the HTTP/GET? Maybe it's enough to do the use inside the routine...
Included in version 0.6.3
- User specified output directory for downloads (see -p option to uudeview)
Version 0.6.3 has --dlpath and --dlrelative options to support this
- The program blocks during a decode. Not a horribly bad thing, but for larger files it creates inefficiency. Consider threading (perl threads are yucky) or running in background. Need a decent suggestion here. * Somebody suggested adding a commandline arg that tells nzbperl to NOT decode each file as it finishes, but to rather queue up the encoded files and do all decoding in a batch mode after all downloading finishes. I like it. Good compromise.
Version 0.6.3 has threaded decoding support
- Add decode completion status message and make sure that the decoding message is cleared correctly on screen.
Included in version 0.6.2
- Incorporate Omen's --continue-incomplete patch so that --keep doesn't do double duty.
Equivalent behavior is included in version 0.6.2
- --keep might be doing triple duty, so also investigate broken binary outputs from uudeview and decide (via new commandline option) if the broken binaries should be kept.
Included in version 0.6.2
- Server connection retry logic. If connection/authentication fails, the app should enter a sleep+retry loop. More complicated with multiple servers, but should be doable.
Included in version 0.6.2
- Possibly doing regex filtering on filenames in nzb file?
Included in version 0.6.2
- Consider using .rc file to store parameters, commandline will override
Included in version 0.6.2
- Commandline option to log stat messages to disk.
Implemented in version 0.6
- Allow alternate (non 119) server ports
Implemented in version 0.6
- Fix file sizes when a part is missing or a file is skipped (already on disk). The totals need to be updated to reflect the change in state.
Fixed in version 0.6
- Adjust file remaining count and adjust total sizes after skipping a part that exists on disk.
Fixed in version 0.6
- Sanity check nzb file for broken parts in files (using standard deviation of file size?) at startup (with a bypass or autoskip option)
Implemented in version 0.6
- News server is currently required. If server not given, we should fall back on environment var for NNTPSERVER
fixed as of version 0.5
- Use a configurable number of connections/threads so that people on throttled servers can still max out speed. Makes client bandwidth throttling harder, but should be reasonable.
fixed as of version 0.5
- Implement 'q'uit key command (end program gracefully)
fixed as of version 0.5
- Implement 'h' or ? key command to show interactive use key list
fixed as of version 0.5
- Display line should have an ETA section
included in version 0.5
- Consider making the display line into 2 lines for formatting on smaller terms
Fixed in version 0.5
- Display line(s) should be 80 column friendly (see above)
fixed as of version 0.5
- Runtime keys to incrementally bump up/down speed.
fixed as of version 0.5
- Maintaining version and date information in the code
global version in code as of version 0.5
- Confirm that connectivity with open servers (no user/pw) works (can somebody verify this for me?)
- Continue from the middle of an nzb, don't redownload if already on disk. (not sure how to tell) Saving state between "sessions".
Email List
nzbperl has an email group/list hosted at google groups. The list can be used to ask for support, submit feature requests, provide patches, submit bug reports, and general nzbperl related discussions.
To view the email list on the web, please visit http://groups.google.com/group/nzbperl.
To subscribe, send email to nzbperl-subscribe@googlegroups.com.
To subscribe, send email to nzbperl-unsubscribe@googlegroups.com.
License
This program is distributed under the terms of the GPL.
Copyright (C) 2004 jason plumb
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.